$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78177 - in branches/release/boost/spirit: . actor attribute core debug dynamic error_handling home home/qi/detail home/support/detail home/support/utree/detail include iterator meta phoenix repository/home/qi/directive repository/home/qi/operator repository/home/qi/operator/detail repository/home/support symbols tree utility
From: joel_at_[hidden]
Date: 2012-04-23 22:05:49
Author: djowel
Date: 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
New Revision: 78177
URL: http://svn.boost.org/trac/boost/changeset/78177
Log:
Merge from trunk
Removed:
   branches/release/boost/spirit/actor/
   branches/release/boost/spirit/actor.hpp
   branches/release/boost/spirit/attribute/
   branches/release/boost/spirit/attribute.hpp
   branches/release/boost/spirit/core/
   branches/release/boost/spirit/core.hpp
   branches/release/boost/spirit/debug/
   branches/release/boost/spirit/debug.hpp
   branches/release/boost/spirit/dynamic/
   branches/release/boost/spirit/dynamic.hpp
   branches/release/boost/spirit/error_handling/
   branches/release/boost/spirit/error_handling.hpp
   branches/release/boost/spirit/iterator/
   branches/release/boost/spirit/iterator.hpp
   branches/release/boost/spirit/meta/
   branches/release/boost/spirit/meta.hpp
   branches/release/boost/spirit/phoenix/
   branches/release/boost/spirit/phoenix.hpp
   branches/release/boost/spirit/symbols/
   branches/release/boost/spirit/symbols.hpp
   branches/release/boost/spirit/tree/
   branches/release/boost/spirit/utility/
   branches/release/boost/spirit/utility.hpp
Properties modified: 
   branches/release/boost/spirit/   (props changed)
   branches/release/boost/spirit/home/   (props changed)
Text files modified: 
   branches/release/boost/spirit/home/qi/detail/assign_to.hpp                    |    31 +                                       
   branches/release/boost/spirit/home/support/detail/endian.hpp                  |     6                                         
   branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp     |     2                                         
   branches/release/boost/spirit/include/version.hpp                             |     4                                         
   branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp            |   689 +++++++++++++++++++++++++++++++++++++-- 
   branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp |   634 +++++++++++++++++++++++++++++++++++-    
   branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp        |   424 ++++++------------------                
   branches/release/boost/spirit/repository/home/support/kwd.hpp                 |     2                                         
   8 files changed, 1403 insertions(+), 389 deletions(-)
Deleted: branches/release/boost/spirit/actor.hpp
==============================================================================
--- branches/release/boost/spirit/actor.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ACTOR
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ACTOR
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_actor.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_actor.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_actor.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/attribute.hpp
==============================================================================
--- branches/release/boost/spirit/attribute.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ATTRIBUTE
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ATTRIBUTE
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_attribute.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_attribute.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_attribute.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/core.hpp
==============================================================================
--- branches/release/boost/spirit/core.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_CORE
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_CORE
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_core.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_core.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_core.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/debug.hpp
==============================================================================
--- branches/release/boost/spirit/debug.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_DEBUG
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_DEBUG
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_debug.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_debug.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_debug.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/dynamic.hpp
==============================================================================
--- branches/release/boost/spirit/dynamic.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_DYNAMIC
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_DYNAMIC
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_dynamic.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_dynamic.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_dynamic.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/error_handling.hpp
==============================================================================
--- branches/release/boost/spirit/error_handling.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ERROR_HANDLING
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ERROR_HANDLING
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_error_handling.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_error_handling.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_error_handling.hpp>
-
-#endif
Modified: branches/release/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/assign_to.hpp	(original)
+++ branches/release/boost/spirit/home/qi/detail/assign_to.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -28,11 +28,25 @@
     //  accept spirit's unused_type; all no-ops. Compiler optimization will
     //  easily strip these away.
     ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename T>
+        struct is_iter_range : mpl::false_ {};
+
+        template <typename I>
+        struct is_iter_range<boost::iterator_range<I> > : mpl::true_ {};
+
+        template <typename C>
+        struct is_container_of_ranges
+          : is_iter_range<typename C::value_type> {};
+    }
+
     template <typename Attribute, typename Iterator, typename Enable>
     struct assign_to_attribute_from_iterators
     {
+        // Common case
         static void
-        call(Iterator const& first, Iterator const& last, Attribute& attr)
+        call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::false_)
         {
             if (traits::is_empty(attr))
                 attr = Attribute(first, last);
@@ -41,6 +55,21 @@
                     push_back(attr, *i);
             }
         }
+
+        // If Attribute is a container with value_type==iterator_range<T> just push the
+        // iterator_range into it
+        static void
+        call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::true_)
+        {
+            typename Attribute::value_type rng(first, last);
+            push_back(attr, rng);
+        }
+
+        static void
+        call(Iterator const& first, Iterator const& last, Attribute& attr)
+        {
+            call(first, last, attr, detail::is_container_of_ranges<Attribute>());
+        }
     };
 
     template <typename Attribute, typename Iterator>
Modified: branches/release/boost/spirit/home/support/detail/endian.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/detail/endian.hpp	(original)
+++ branches/release/boost/spirit/home/support/detail/endian.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -20,9 +20,9 @@
 
 // If Boost has the endian library, use it, otherwise use an adapted version
 // included with Spirit
-// #if BOOST_VERSION >= 105100
-// #include <boost/endian/integers.hpp>
-// #else
+#if BOOST_VERSION >= 105100
+#include <boost/endian/integers.hpp>
+#else
 #include <boost/spirit/home/support/detail/endian/endian.hpp>
 // #endif
 
Modified: branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp	(original)
+++ branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -1043,7 +1043,7 @@
         if (!pos.node) 
         {
             l.push_back(val);
-            return utree::iterator(l.first, 0); // begin();
+            return utree::iterator(l.last, l.last->prev);
         }
         l.insert(val, pos);
         return utree::iterator(pos.node->prev, pos.node->prev->prev);
Modified: branches/release/boost/spirit/include/version.hpp
==============================================================================
--- branches/release/boost/spirit/include/version.hpp	(original)
+++ branches/release/boost/spirit/include/version.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -14,7 +14,7 @@
 //  This is the version of the current Spirit distribution
 //
 ///////////////////////////////////////////////////////////////////////////////
-#define SPIRIT_VERSION 0x2050
-#define SPIRIT_PIZZA_VERSION DEEP_PAN_BBQ  // :-O
+#define SPIRIT_VERSION 0x2053
+#define SPIRIT_PIZZA_VERSION SUPER_HOT_SPANISH_SARDINES  // :-O
 
 #endif
Deleted: branches/release/boost/spirit/iterator.hpp
==============================================================================
--- branches/release/boost/spirit/iterator.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ITERATOR
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ITERATOR
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_iterator.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_iterator.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_iterator.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/meta.hpp
==============================================================================
--- branches/release/boost/spirit/meta.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_META
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_META
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_meta.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_meta.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_meta.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/phoenix.hpp
==============================================================================
--- branches/release/boost/spirit/phoenix.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_PHOENIX
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_PHOENIX
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/phoenix1.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/phoenix1.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/phoenix1.hpp>
-
-#endif
Modified: branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp	(original)
+++ branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -35,50 +35,98 @@
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd                     // enables kwd(key)[p]
         , fusion::vector1<T > >
-    > : traits::is_string<T> {};
+    > : mpl::true_ {};
     
     template < typename T>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd                     // enables ikwd(key)[p]
         , fusion::vector1<T > >
-    > : traits::is_string<T> {};
+    > : mpl::true_ {};
     
+    template < typename T>
+    struct use_directive<qi::domain
+      , terminal_ex<repository::tag::dkwd                     // enables dkwd(key)[p]
+        , fusion::vector1<T > >
+    > : mpl::true_ {};
     
+    template < typename T>
+    struct use_directive<qi::domain
+      , terminal_ex<repository::tag::idkwd                     // enables idkwd(key)[p]
+        , fusion::vector1<T > >
+    > : mpl::true_ {};
+
+
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd                     // enables kwd(key,exact)[p]
         , fusion::vector2< T1, T2 > >
-    > : traits::is_string<T1> {};
+    > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd                     // enables ikwd(key,exact)[p]
         , fusion::vector2< T1, T2 > >
-    > : traits::is_string<T1> {};
+    > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
+      , terminal_ex<repository::tag::dkwd                     // enables dkwd(key,exact)[p]
+        , fusion::vector2< T1, T2 > >
+    > : mpl::true_ {};
+
+    template < typename T1, typename T2>
+    struct use_directive<qi::domain
+      , terminal_ex<repository::tag::idkwd                     // enables idkwd(key,exact)[p]
+        , fusion::vector2< T1, T2 > >
+    > : mpl::true_ {};
+
+   template < typename T1, typename T2>
+    struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd                     // enables kwd(min, max)[p]
         , fusion::vector3< T1, T2, T2 > >
-    > : traits::is_string<T1> {};
+    > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd                     // enables ikwd(min, max)[p]
         , fusion::vector3< T1, T2, T2 > >
-    > : traits::is_string<T1> {};
+    > : mpl::true_ {};
+
+    template < typename T1, typename T2>
+    struct use_directive<qi::domain
+      , terminal_ex<repository::tag::dkwd                     // enables dkwd(min, max)[p]
+        , fusion::vector3< T1, T2, T2 > >
+    > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
+      , terminal_ex<repository::tag::idkwd                     // enables idkwd(min, max)[p]
+        , fusion::vector3< T1, T2, T2 > >
+    > : mpl::true_ {};
+
+   template < typename T1, typename T2>
+    struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd                     // enables kwd(min, inf)[p]
         , fusion::vector3<T1, T2, inf_type > >
-    > : traits::is_string<T1> {};
+    > : mpl::true_ {};
     
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd                     // enables ikwd(min, inf)[p]
         , fusion::vector3<T1, T2, inf_type > >
-    > : traits::is_string<T1> {};
+    > : mpl::true_ {};
+
+   template < typename T1, typename T2>
+    struct use_directive<qi::domain
+      , terminal_ex<repository::tag::dkwd                     // enables dkwd(min, inf)[p]
+        , fusion::vector3<T1, T2, inf_type > >
+    > : mpl::true_ {};
+
+    template < typename T1, typename T2>
+    struct use_directive<qi::domain
+      , terminal_ex<repository::tag::idkwd                     // enables idkwd(min, inf)[p]
+        , fusion::vector3<T1, T2, inf_type > >
+    > : mpl::true_ {};
 
 
   /*  template <>                                     // enables *lazy* kwd(exact)[p]
@@ -102,6 +150,8 @@
 {
     using repository::kwd;
     using repository::ikwd;
+    using repository::dkwd;
+    using repository::idkwd;
     using spirit::inf;
     using spirit::inf_type;
 
@@ -225,13 +275,14 @@
         int &counter;
     };
     
-    template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase >
-    struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase > >
+    template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase, typename Distinct >
+    struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > >
     {
         struct kwd_parser_id;
         
         typedef Subject subject_type;
         typedef NoCase no_case_keyword;
+        typedef Distinct distinct;
                 
         typedef typename
             remove_const<typename traits::char_type_of<KeywordType>::type>::type
@@ -256,6 +307,13 @@
            , LoopIter const& iter)
           : subject(subject), iter(iter), keyword(keyword) {}    
         
+        template<typename CharEncoding>
+        kwd_parser(Subject const& subject
+           , typename add_reference<KeywordType>::type keyword
+           , LoopIter const& iter, CharEncoding encoding)
+          : subject(subject), iter(iter), keyword(keyword,encoding) {}
+
+
         // Call the subject parser on a non container attribute
         template <typename Iterator, typename Context
           , typename Skipper, typename Attribute>
@@ -329,12 +387,14 @@
             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
             >::type predicate;
             
+
             // Parse the keyword
             bool flag = iter.flag_init();
             int counter = 0;
             Iterator save = first;
             spirit::qi::skip_over(first, last, skipper);
             if(keyword.parse(first,last,context,skipper,unused)){
+                if((!distinct::value) || skipper.parse(first,last,unused,unused,unused)){
                 // Followed by the subject parser
                 spirit::qi::skip_over(first, last, skipper);
                 if(parse_impl(first,last,context,skipper,attr, predicate()))
@@ -342,6 +402,7 @@
                     return iter.register_successful_parse(flag,counter);
                 }
             }
+            }
             first = save;            
             return flag;            
           }
@@ -350,16 +411,29 @@
         template <typename Context>
         info what(Context& context) const
         {
+            if(distinct::value){
             if(no_case_keyword::value)
+                return info("idkwd", subject.what(context));
+              else
+                return info("dkwd", subject.what(context));
+            }
+            else
+            {
+              if(no_case_keyword::value)
                 return info("ikwd", subject.what(context));
             else
                 return info("kwd", subject.what(context));
         }
+        }
 
         Subject subject;
         LoopIter iter;            
         
-        spirit::qi::literal_string<KeywordType, true> keyword;
+        typedef typename mpl::if_<
+                no_case_keyword,
+                spirit::qi::no_case_literal_string< KeywordType, true>,
+                spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type;
+       keyword_string_type keyword;
     private:
         // silence MSVC warning C4512: assignment operator could not be generated
         kwd_parser& operator= (kwd_parser const&);
@@ -376,6 +450,151 @@
 
 
     };
+
+template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct>
+    struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > >
+    {
+        struct complex_kwd_parser_id;
+        typedef Subject subject_type;
+        typedef Distinct distinct;
+
+        template <typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+            traits::build_std_vector<
+                typename traits::attribute_of<
+                Subject, Context, Iterator>::type
+                        >::type
+                type;
+        };
+
+
+        complex_kwd_parser(Subject const& subject
+           , typename add_reference<KeywordType>::type keyword
+           , LoopIter const& iter)
+          : subject(subject), iter(iter), keyword(keyword) {}
+
+        // Call the subject parser on a non container attribute
+        template <typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        bool parse_impl(Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr,mpl::false_) const
+        {
+            return subject.parse(first,last,context,skipper,attr);
+        }
+
+        // Call the subject parser on a container attribute
+        template <typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        bool parse_impl(Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr,mpl::true_) const
+        {
+
+            // synthesized attribute needs to be default constructed
+            typename traits::container_value<Attribute>::type val =
+                typename traits::container_value<Attribute>::type();
+
+            Iterator save = first;
+            bool r = subject.parse(first,last,context,skipper, val);
+            if (r)
+            {
+                // push the parsed value into our attribute
+                r = traits::push_back(attr, val);
+                if (!r)
+                    first = save;
+            }
+            return r;
+        }
+
+       template <typename Iterator, typename Context
+          , typename Skipper, typename Attribute,typename NoCasePass>
+        bool parse(Iterator& first, Iterator const& last
+          , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
+          , Attribute &attr) const
+        {
+
+            typedef typename traits::attribute_of<
+                Subject, Context, Iterator>::type
+                subject_attribute;
+
+            typedef typename mpl::and_<
+             traits::is_container<Attribute>
+            , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+            >::type predicate;
+
+            if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
+                return iter.register_successful_parse(skipper.flag,skipper.counter);
+            return false;
+        }
+
+        template <typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        bool parse(Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr) const
+          {
+              typedef typename traits::attribute_of<
+                Subject, Context, Iterator>::type
+                subject_attribute;
+
+            typedef typename mpl::and_<
+            traits::is_container<Attribute>
+            , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+            >::type predicate;
+
+
+            // Parse the keyword
+            bool flag = iter.flag_init();
+            int counter = 0;
+            Iterator save = first;
+            spirit::qi::skip_over(first, last, skipper);
+            if(keyword.parse(first,last,context,skipper,unused)){
+              if( !distinct::value || skipper.parse(first,last,unused,unused,unused)){
+                // Followed by the subject parser
+                spirit::qi::skip_over(first, last, skipper);
+                if(parse_impl(first,last,context,skipper,attr, predicate()))
+                {
+                  return iter.register_successful_parse(flag,counter);
+                }
+              }
+            }
+            first = save;
+            return flag;
+          }
+
+
+        template <typename Context>
+        info what(Context& context) const
+        {
+           if(distinct::value)
+            return info("dkwd", subject.what(context));
+           else
+            return info("kwd", subject.what(context));
+        }
+
+        Subject subject;
+        LoopIter iter;
+
+        KeywordType keyword;
+    private:
+        // silence MSVC warning C4512: assignment operator could not be generated
+        complex_kwd_parser& operator= (complex_kwd_parser const&);
+
+        template <typename Iterator, typename Context, typename Skipper>
+        static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
+        fail_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+        {
+            return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
+                (first, last, context, skipper);
+        }
+
+    };
+
 }}}}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -386,177 +605,546 @@
     // Parser generators: make_xxx function (objects)
     ///////////////////////////////////////////////////////////////////////////
     
+    template <typename T1, typename T2,  typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
+    struct make_directive_internal_2_args
+    {
+
+        // is the keyword a string keyword ?
+        typedef typename traits::is_string<T1> is_string_kwd_type;
+        // make the keyword type
+        typedef typename mpl::if_< is_string_kwd_type ,
+                                   T1 ,
+                                   typename result_of::compile<qi::domain, T1>::type
+                                 >::type keyword_type;
+
+        typedef typename add_const<keyword_type>::type const_keyword;
+        // select the pass iterator type
+        typedef typename MakeDirectiveHelper::iterator_type iterator_type;
+        // determine if a no case modifier applies to the context
+        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+        // Determine the full type of the kwd / complex_kwd directive
+        typedef typename
+             mpl::if_<
+                is_string_kwd_type,
+                repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
+                repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct >
+                     >::type result_type;
+
+        // Return a kwd parser object
+        template <typename Terminal>
+        result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const
+        {
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
+           return result_type(subject
+                        ,MakeDirectiveHelper::make_iterator(term.args)
+                        ,encoding
+                        );
+        }
+        template <typename Terminal>
+        result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
+        {
+           return result_type(subject
+                        ,fusion::at_c<0>(term.args)
+                        ,MakeDirectiveHelper::make_iterator(term.args)
+                        );
+        }
+        template <typename Terminal>
+        result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const
+        {
+           return create_kwd_string(term,subject,no_case());
+        }
+        // Return a complex_kwd parser object
+        template <typename Terminal>
+        result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
+        {
+           return result_type(subject
+                        ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
+                        ,MakeDirectiveHelper::make_iterator(term.args)                        
+                        );
+        }
+        // Select which object type to return
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+            return create_kwd(term, subject, modifiers, is_string_kwd_type());
+        }
+
+    };
+
      // Directive kwd(key)[p]
+    template <typename T1,  typename Subject, typename Modifiers, typename Distinct>
+    struct make_directive_internal
+    {
+        // is the keyword a string keyword ?
+        typedef typename traits::is_string<T1> is_string_kwd_type;
+        // make the keyword type
+        typedef typename mpl::if_< is_string_kwd_type ,
+                                   T1 ,
+                                   typename result_of::compile<qi::domain, T1, Modifiers>::type
+                                 >::type keyword_type;
+
+        typedef typename add_const<keyword_type>::type const_keyword;
+        // select the pass iterator type
+        typedef repository::qi::kwd_pass_iterator<int> iterator_type;
+        // determine if a no case modifier applies to the context
+        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+        // Determine the full type of the kwd / complex_kwd directive
+        typedef typename
+             mpl::if_<
+                is_string_kwd_type,
+                repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
+                repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct>
+                     >::type result_type;
+
+        // Return a kwd parser object
+        template <typename Terminal>
+        result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) const
+        {
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
+
+            return result_type(subject
+                        ,fusion::at_c<0>(term.args)
+                        ,iterator_type()
+                        ,encoding
+                        );
+
+        }
+        template <typename Terminal>
+        result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
+        {
+            return result_type(subject
+                        ,fusion::at_c<0>(term.args)
+                        ,iterator_type()
+                        );
+        }
+        template <typename Terminal>
+        result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const
+        {
+           return create_kwd_string(term,subject,no_case());
+        }
+        // Return a complex_kwd parser object
+        template <typename Terminal>
+        result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
+        {
+           return result_type(subject
+                        ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
+                        ,iterator_type()
+                        );
+        }
+        // Select which object type to return
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const
+        {
+            return create_kwd(term, subject, modifiers, is_string_kwd_type());
+        }
+    };
+
     template <typename T1,  typename Subject, typename Modifiers>
     struct make_directive<
         terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
     {
+        typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type;
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+
+            return make_directive_type()(term, subject, modifiers);
+        }
+
+    };
+ 
+   template <typename T1,  typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
+    {
+        typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type;
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+
+            return make_directive_type()(term, subject, modifiers);
+        }
+
+    };
+ 
+
+
+    // Directive ikwd(key)[p]
+    template <typename T1,  typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
+    {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
-        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
         
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
                 
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
-
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
+
             return result_type(subject
                         ,fusion::at_c<0>(term.args)
                         ,iterator_type()
+                        ,encoding
                         );
         }
     };
     
-    // Directive ikwd(key)[p]
     template <typename T1,  typename Subject, typename Modifiers>
     struct make_directive<
-        terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
+        terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
         
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
-       /*     typename spirit::detail::get_encoding<Modifiers,
-                spirit::char_encoding::standard>::type encoding;*/
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
                 
             return result_type(subject
                         ,fusion::at_c<0>(term.args)
                         ,iterator_type()                        
+                        ,encoding
                         );
         }
     };
     
     // Directive kwd(key,exact)[p]
+        template <typename T>
+    struct make_exact_helper
+    { 
+        typedef repository::qi::kwd_exact_iterator<T> iterator_type;
+        template<typename Args>
+        static iterator_type make_iterator(Args const& args)
+        {
+          return iterator_type(fusion::at_c<1>(args));
+        }
+    };
+
     template <typename T1, typename T2,  typename Subject, typename Modifiers>
     struct make_directive<
         terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
     {
+        typedef make_directive_internal_2_args< T1
+                                              , T2
+                                              , Subject
+                                              , Modifiers
+                                              , mpl::false_
+                                              , make_exact_helper<T2>
+                                              > make_directive_type;
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+
+            return make_directive_type()(term,subject, modifiers);
+        }
+
+    };
+  
+    template <typename T1, typename T2,  typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+    {
+         typedef make_directive_internal_2_args< T1
+                                              , T2
+                                              , Subject
+                                              , Modifiers
+                                              , mpl::true_
+                                              , make_exact_helper<T2>
+                                              > make_directive_type;
+        
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+
+            return make_directive_type()(term, subject, modifiers);
+        }
+
+    };
+  
+
+    // Directive ikwd(key,exact)[p]
+    template <typename T1, typename T2,  typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+    {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
-        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
         
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
-            Terminal const& term, Subject const& subject, unused_type) const
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
         {
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
             return result_type(subject
                         ,fusion::at_c<0>(term.args)
                         ,fusion::at_c<1>(term.args)
+                        , encoding
                         );
         }
     };
 
-    // Directive ikwd(key,exact)[p]
     template <typename T1, typename T2,  typename Subject, typename Modifiers>
     struct make_directive<
-        terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+        terminal_ex<repository::tag::idkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
         
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
         
         template <typename Terminal>
         result_type operator()(
-            Terminal const& term, Subject const& subject, unused_type) const
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
         {            
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
             return result_type(subject
                         , fusion::at_c<0>(term.args)
                         , fusion::at_c<1>(term.args)
+                        , encoding
                         );
         }
     };
     
+
     // Directive kwd(min, max)[p]
+
+    template <typename T>
+    struct make_finite_helper
+    { 
+        typedef repository::qi::kwd_finite_iterator<T> iterator_type;
+        template<typename Args>
+        static iterator_type make_iterator(Args const& args)
+        {
+          return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
+        }
+
+    };
+
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
         terminal_ex<repository::tag::kwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
     {
+        typedef make_directive_internal_2_args< T1
+                                              , T2
+                                              , Subject
+                                              , Modifiers
+                                              , mpl::false_
+                                              , make_finite_helper<T2>
+                                              > make_directive_type;
+        
+        
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+
+            return make_directive_type()(term,subject, modifiers);
+        }
+
+    };
+  
+    template <typename T1, typename T2,  typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
+    {
+       
+        typedef make_directive_internal_2_args< T1
+                                              , T2
+                                              , Subject
+                                              , Modifiers
+                                              , mpl::true_
+                                              , make_finite_helper<T2>
+                                              > make_directive_type;
+ 
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+        {
+
+            return make_directive_type()(term,subject, modifiers);
+        }
+
+    };
+
+    // Directive ikwd(min, max)[p]
+    template <typename T1, typename T2, typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
+    {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
-        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
                     
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
+
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
             return result_type(subject, fusion::at_c<0>(term.args),
                 iterator_type(
                     fusion::at_c<1>(term.args)
                   , fusion::at_c<2>(term.args)
+                  , encoding
                 )
             );
         }
     };
 
-    // Directive ikwd(min, max)[p]
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
-        terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
+        terminal_ex<repository::tag::idkwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
                 
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
         
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
             return result_type(subject, fusion::at_c<0>(term.args),
                 iterator_type(
                     fusion::at_c<1>(term.args)
                   , fusion::at_c<2>(term.args)
+                  , encoding
                 )
             );
         }
     };
     
+
     // Directive kwd(min, inf)[p]
+
+    template <typename T>
+    struct make_infinite_helper
+    { 
+        typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
+        template<typename Args>
+        static iterator_type make_iterator(Args const& args)
+        {
+          return iterator_type(fusion::at_c<1>(args));
+        }
+
+    };
+
+
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
-        terminal_ex<repository::tag::kwd
+        terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
+    {
+         typedef make_directive_internal_2_args< T1
+                                              , T2
+                                              , Subject
+                                              , Modifiers
+                                              , mpl::false_
+                                              , make_infinite_helper<T2>
+                                              > make_directive_type;
+        
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, unused_type) const
+        {
+
+            return make_directive_type()(term,subject, unused_type());
+        }
+
+    };
+  
+    template <typename T1, typename T2,  typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
+    {
+      typedef make_directive_internal_2_args< T1
+                                              , T2
+                                              , Subject
+                                              , Modifiers
+                                              , mpl::false_
+                                              , make_infinite_helper<T2>
+                                              > make_directive_type;
+    
+        typedef typename make_directive_type::result_type result_type;
+        template <typename Terminal>
+        result_type operator()(
+            Terminal const& term, Subject const& subject, unused_type) const
+        {
+
+            return make_directive_type()(term,subject, unused_type());
+        }
+
+    };
+
+
+    // Directive ikwd(min, inf)[p]
+    template <typename T1, typename T2, typename Subject, typename Modifiers>
+    struct make_directive<
+        terminal_ex<repository::tag::ikwd
         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
-        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
         
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
+            typename spirit::detail::get_encoding<Modifiers,
+                spirit::char_encoding::standard>::type encoding;
+
             return result_type(subject
                 , fusion::at_c<0>(term.args)
                 , fusion::at_c<1>(term.args)
+                , encoding
                 );
         }
     };
     
-    // Directive ikwd(min, inf)[p]
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
-        terminal_ex<repository::tag::ikwd
+        terminal_ex<repository::tag::idkwd
         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
         
-        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+        typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
@@ -568,6 +1156,7 @@
             return result_type(subject
                 , fusion::at_c<0>(term.args)
                 , fusion::at_c<1>(term.args)
+                , encoding
                 );
         }
     };
@@ -578,10 +1167,32 @@
 namespace boost { namespace spirit { namespace traits
 {
     template <typename Subject, typename KeywordType
-            , typename LoopIter, typename NoCase >
+            , typename LoopIter, typename NoCase , typename Distinct>
     struct has_semantic_action< 
-            repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase > >
+            repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > >
+      : unary_has_semantic_action<Subject> {};
+
+    template <typename Subject, typename KeywordType
+            , typename LoopIter, typename Distinct >
+    struct has_semantic_action<
+            repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > >
       : unary_has_semantic_action<Subject> {};
+
+    template <typename Subject, typename KeywordType
+              , typename LoopIter, typename NoCase, typename Attribute, typename Context
+                , typename Iterator, typename Distinct>
+    struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute
+        , Context, Iterator>
+      : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+
+    template <typename Subject, typename KeywordType
+                , typename LoopIter
+                , typename Attribute, typename Context
+                , typename Iterator, typename Distinct>
+    struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute
+        , Context, Iterator>
+      : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+
 }}}
 
 #endif
Modified: branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp	(original)
+++ branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -1,6 +1,5 @@
 /*=============================================================================
-    Copyright (c) 2001-2011 Joel de Guzman
-    Copyright (c) 2011 Thomas Bernard
+  Copyright (c) 2011-2012 Thomas Bernard
 
     Distributed under the Boost Software License, Version 1.0. (See accompanying
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,39 +10,35 @@
 #if defined(_MSC_VER)
 #pragma once
 #endif
-
+#include <boost/fusion/include/nview.hpp>
+#include <boost/spirit/home/qi/string/lit.hpp>
+#include <boost/fusion/include/at.hpp>
 namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-        
-        // This helper class enables jumping over intermediate directives 
-        // down the kwd parser iteration count checking policy
-        struct register_successful_parse
-        {
-            template <typename Subject>
-            static bool call(Subject const &subject,bool &flag, int &counter)
-            {
-                return subject.iter.register_successful_parse(flag,counter);
-            }
-            template <typename Subject, typename Action>
-            static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
-            {
-                return subject.subject.iter.register_successful_parse(flag,counter);
-            }
-            template <typename Subject>
-            static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
-            {
-                return subject.subject.iter.register_successful_parse(flag,counter);
-            }
-        };
         // Variant visitor class which handles dispatching the parsing to the selected parser
         // This also handles passing the correct attributes and flags/counters to the subject parsers       
+    template<typename T>
+    struct is_distinct : T::distinct { };
  
+    template<typename T, typename Action>
+    struct is_distinct< spirit::qi::action<T,Action> > : T::distinct { };
+
+    template<typename T>
+    struct is_distinct< spirit::qi::hold_directive<T> > : T::distinct { };
+
+
+
         template < typename Elements, typename Iterator ,typename Context ,typename Skipper
                   ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
-        class parse_dispatcher
+        struct parse_dispatcher
             : public boost::static_visitor<bool>
         {
+
+            typedef Iterator iterator_type;
+            typedef Context context_type;
+            typedef Skipper skipper_type;
+            typedef Elements elements_type;
+
             typedef typename add_reference<Attribute>::type attr_reference; 
-            
             public:
             parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper
@@ -65,7 +60,8 @@
                 , Index& idx ) const
             {
                 Iterator save = first;
-                skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+                    skipper_keyword_marker<Skipper,NoCasePass>
+                        marked_skipper(skipper,flags[Index::value],counters[Index::value]);
                 
                 if(subject.parse(first,last,context,marked_skipper,unused))
                 {
@@ -84,7 +80,8 @@
             {
                
                 Iterator save = first;
-                skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+                    skipper_keyword_marker<Skipper,NoCasePass> 
+                        marked_skipper(skipper,flags[Index::value],counters[Index::value]);
                 if(subject.parse(first,last,context,marked_skipper,fusion::at_c<Index::value>(attr)))
                 {
                         return true;
@@ -95,12 +92,28 @@
 
             // Handle unused attributes
             template <typename T> bool call(T &idx, mpl::false_) const{                            
+ 
+                typedef typename mpl::at<Elements,T>::type ElementType;
+                if(
+                       (!is_distinct<ElementType>::value)
+                    || skipper.parse(first,last,unused,unused,unused)
+                  ){
+                      spirit::qi::skip_over(first, last, skipper);
                 return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
             }
+                return false;
+            }
             // Handle normal attributes
             template <typename T> bool call(T &idx, mpl::true_) const{
+                 typedef typename mpl::at<Elements,T>::type ElementType;
+                 if(
+                       (!is_distinct<ElementType>::value)
+                    || skipper.parse(first,last,unused,unused,unused)
+                  ){
                 return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
             }
+                return false;
+            }
             
             const Elements &elements;
             Iterator &first;
@@ -111,7 +124,572 @@
             Counters &counters;
             attr_reference attr;
         };
+    // string keyword loop handler
+    template <typename Elements, typename StringKeywords, typename IndexList, typename FlagsType, typename Modifiers>
+        struct string_keywords
+        {
+            // Create a variant type to be able to store parser indexes in the embedded symbols parser
+            typedef typename
+                spirit::detail::as_variant<
+                IndexList >::type        parser_index_type;
       
+            ///////////////////////////////////////////////////////////////////////////
+            // build_char_type_sequence
+            //
+            // Build a fusion sequence from the kwd directive specified character type.
+            ///////////////////////////////////////////////////////////////////////////
+            template <typename Sequence >
+                struct build_char_type_sequence
+                {
+                    struct element_char_type
+                    {
+                        template <typename T>
+                            struct result;
+
+                        template <typename F, typename Element>
+                            struct result<F(Element)>
+                            {
+                                typedef typename Element::char_type type;
+
+                            };
+                        template <typename F, typename Element,typename Action>
+                            struct result<F(spirit::qi::action<Element,Action>) >
+                            {
+                                typedef typename Element::char_type type;
+                            };
+                        template <typename F, typename Element>
+                            struct result<F(spirit::qi::hold_directive<Element>)>
+                            {
+                                typedef typename Element::char_type type;
+                            };
+
+                        // never called, but needed for decltype-based result_of (C++0x)
+                        template <typename Element>
+                            typename result<element_char_type(Element)>::type
+                            operator()(Element&) const;
+                    };
+
+                    // Compute the list of character types of the child kwd directives
+                    typedef typename
+                        fusion::result_of::transform<Sequence, element_char_type>::type
+                        type;
+                };
+
+
+            ///////////////////////////////////////////////////////////////////////////
+            // get_keyword_char_type
+            //
+            // Collapses the character type comming from the subject kwd parsers and
+            // and checks that they are all identical (necessary in order to be able
+            // to build a tst parser to parse the keywords.
+            ///////////////////////////////////////////////////////////////////////////
+            template <typename Sequence>
+                struct get_keyword_char_type
+                {
+                    // Make sure each of the types occur only once in the type list
+                    typedef typename
+                        mpl::fold<
+                        Sequence, mpl::vector<>,
+                        mpl::if_<
+                            mpl::contains<mpl::_1, mpl::_2>,
+                        mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
+                            >
+                            >::type
+                            no_duplicate_char_types;
+
+                    // If the compiler traps here this means you mixed
+                    // character type for the keywords specified in the
+                    // kwd directive sequence.
+                    BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
+
+                    typedef typename mpl::front<no_duplicate_char_types>::type type;
+
+                };
+
+            // Get the character type for the tst parser
+            typedef typename build_char_type_sequence< StringKeywords >::type char_types;
+            typedef typename get_keyword_char_type<
+                typename mpl::if_<
+                  mpl::equal_to<
+                    typename mpl::size < char_types >::type
+                    , mpl::int_<0>
+                    >
+                  , mpl::vector< boost::spirit::standard::char_type >
+                  , char_types >::type
+                >::type  char_type;
+
+            // Our symbols container
+            typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
+
+            // Filter functor used for case insensitive parsing
+            template <typename CharEncoding>
+                struct no_case_filter
+                {
+                    char_type operator()(char_type ch) const
+                    {
+                        return static_cast<char_type>(CharEncoding::tolower(ch));
+                    }
+                };
+
+            ///////////////////////////////////////////////////////////////////////////
+            // build_case_type_sequence
+            //
+            // Build a fusion sequence from the kwd/ikwd directives
+            // in order to determine if case sensitive and case insensitive
+            // keywords have been mixed.
+            ///////////////////////////////////////////////////////////////////////////
+            template <typename Sequence >
+                struct build_case_type_sequence
+                {
+                    struct element_case_type
+                    {
+                        template <typename T>
+                            struct result;
+
+                        template <typename F, typename Element>
+                            struct result<F(Element)>
+                            {
+                                typedef typename Element::no_case_keyword type;
+
+                            };
+                        template <typename F, typename Element,typename Action>
+                            struct result<F(spirit::qi::action<Element,Action>) >
+                            {
+                                typedef typename Element::no_case_keyword type;
+                            };
+                        template <typename F, typename Element>
+                            struct result<F(spirit::qi::hold_directive<Element>)>
+                            {
+                                typedef typename Element::no_case_keyword type;
+                            };
+
+                        // never called, but needed for decltype-based result_of (C++0x)
+                        template <typename Element>
+                            typename result<element_case_type(Element)>::type
+                            operator()(Element&) const;
+                    };
+
+                    // Compute the list of character types of the child kwd directives
+                    typedef typename
+                        fusion::result_of::transform<Sequence, element_case_type>::type
+                        type;
+                };
+
+            ///////////////////////////////////////////////////////////////////////////
+            // get_nb_case_types
+            //
+            // Counts the number of entries in the case type sequence matching the
+            // CaseType parameter (mpl::true_  -> case insensitve
+            //                   , mpl::false_ -> case sensitive
+            ///////////////////////////////////////////////////////////////////////////
+            template <typename Sequence,typename CaseType>
+                struct get_nb_case_types
+                {
+                    // Make sure each of the types occur only once in the type list
+                    typedef typename
+                        mpl::count_if<
+                        Sequence, mpl::equal_to<mpl::_,CaseType>
+                        >::type type;
+
+
+                };
+            // Build the case type sequence
+            typedef typename build_case_type_sequence< StringKeywords >::type case_type_sequence;
+            // Count the number of case sensitive entries and case insensitve entries
+            typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
+            typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
+            // Get the size of the original sequence
+            typedef typename mpl::size<IndexList>::type nb_elements;
+            // Determine if all the kwd directive are case sensitive/insensitive
+            typedef typename mpl::and_<
+                typename mpl::greater< nb_elements, mpl::int_<0> >::type
+                , typename mpl::equal_to< ikwd_count, nb_elements>::type
+                >::type all_ikwd;
+
+            typedef typename mpl::and_<
+                typename mpl::greater< nb_elements, mpl::int_<0> >::type
+                , typename mpl::equal_to< kwd_count, nb_elements>::type
+                >::type all_kwd;
+
+            typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
+
+            // Do we have a no case modifier
+            typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
+
+            // Should the no_case filter always be used ?
+            typedef typename mpl::or_<
+                no_case_modifier,
+                mpl::and_<
+                    all_directives_of_same_type
+                    ,all_ikwd
+                    >
+                    >::type
+                    no_case;
+
+            typedef no_case_filter<
+                typename spirit::detail::get_encoding_with_case<
+                Modifiers
+                , char_encoding::standard
+                , no_case::value>::type>
+                nc_filter;
+            // Determine the standard case filter type
+            typedef typename mpl::if_<
+                no_case
+                , nc_filter
+                , spirit::qi::tst_pass_through >::type
+                first_pass_filter_type;
+
+            typedef typename mpl::or_<
+                    all_directives_of_same_type
+                  , no_case_modifier
+                >::type requires_one_pass;
+
+
+            // Functor which adds all the keywords/subject parser indexes
+            // collected from the subject kwd directives to the keyword tst parser
+            struct keyword_entry_adder
+            {
+                typedef int result_type;
+
+                keyword_entry_adder(shared_ptr<keywords_type> lookup,FlagsType &flags, Elements &elements) :
+                    lookup(lookup)
+                    ,flags(flags)
+                    ,elements(elements)
+                {}
+
+                template <typename T>
+                    int operator()(const T &index) const
+                    {
+                        return call(fusion::at_c<T::value>(elements),index);
+                    }
+
+                template <typename T, typename Position, typename Action>
+                    int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
+                    {
+
+                        // Make the keyword/parse index entry in the tst parser
+                        lookup->add(
+                                traits::get_begin<char_type>(parser.subject.keyword.str),
+                                traits::get_end<char_type>(parser.subject.keyword.str),
+                                position
+                                );
+                        // Get the initial state of the flags array and store it in the flags initializer
+                        flags[Position::value]=parser.subject.iter.flag_init();
+                        return 0;
+                    }
+
+                template <typename T, typename Position>
+                    int call( const T & parser, const Position position) const
+                    {
+                        // Make the keyword/parse index entry in the tst parser
+                        lookup->add(
+                                traits::get_begin<char_type>(get_string(parser.keyword)),
+                                traits::get_end<char_type>(get_string(parser.keyword)),
+                                position
+                                );
+                        // Get the initial state of the flags array and store it in the flags initializer
+                        flags[Position::value]=parser.iter.flag_init();
+                        return 0;
+                    }
+
+                template <typename T, typename Position>
+                    int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
+                    {
+                        // Make the keyword/parse index entry in the tst parser
+                        lookup->add(
+                                traits::get_begin<char_type>(parser.subject.keyword.str),
+                                traits::get_end<char_type>(parser.subject.keyword.str),
+                                position
+                                );
+                        // Get the initial state of the flags array and store it in the flags initializer
+                        flags[Position::value]=parser.subject.iter.flag_init();
+                        return 0;
+                    }
+
+                template <typename String, bool no_attribute>
+                const String & get_string(const boost::spirit::qi::literal_string<String,no_attribute> &parser) const
+                {
+                        return parser.str;
+                }
+
+                template <typename String, bool no_attribute>
+                const typename boost::spirit::qi::no_case_literal_string<String,no_attribute>::string_type &
+                        get_string(const boost::spirit::qi::no_case_literal_string<String,no_attribute> &parser) const
+                {
+                        return parser.str_lo;
+                }
+
+
+
+                shared_ptr<keywords_type> lookup;
+                FlagsType & flags;
+                Elements &elements;
+            };
+
+            string_keywords(Elements &elements,FlagsType &flags_init) : lookup(new keywords_type())
+            {
+                // Loop through all the subject parsers to build the keyword parser symbol parser
+                IndexList indexes;
+                keyword_entry_adder f1(lookup,flags_init,elements);
+                fusion::for_each(indexes,f1);
+
+            }
+            template <typename Iterator,typename ParseVisitor, typename Skipper>
+                bool parse(
+                        Iterator &first,
+                        const Iterator &last,
+                        const ParseVisitor &parse_visitor,
+                        const Skipper &skipper) const
+                {
+                    if(parser_index_type* val_ptr =
+                            lookup->find(first,last,first_pass_filter_type()))
+                    {                        
+                        if(!apply_visitor(parse_visitor,*val_ptr)){
+                            return false;
+                        }
+            return true;
+                    }
+                    return false;
+                }
+
+            template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
+                bool parse(
+                        Iterator &first,
+                        const Iterator &last,
+                        const ParseVisitor &parse_visitor,
+                        const NoCaseParseVisitor &no_case_parse_visitor,
+                        const Skipper &skipper) const
+                {
+                    Iterator saved_first = first;
+                    if(parser_index_type* val_ptr =
+                            lookup->find(first,last,first_pass_filter_type()))
+                    {
+                        if(!apply_visitor(parse_visitor,*val_ptr)){
+                            return false;
+                        }
+            return true;
+                    }
+                    // Second pass case insensitive
+                    else if(parser_index_type* val_ptr
+                            = lookup->find(saved_first,last,nc_filter()))
+                    {
+                        first = saved_first;
+                        if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
+                            return false;
+                        }
+            return true;
+                    }
+                    return false;
+                }
+            shared_ptr<keywords_type> lookup;
+
+
+        };
+
+    struct empty_keywords_list
+    {
+        typedef mpl::true_ requires_one_pass;
+
+        empty_keywords_list()
+        {}
+        template<typename Elements>
+        empty_keywords_list(const Elements &)
+        {}
+
+       template<typename Elements, typename FlagsInit>
+        empty_keywords_list(const Elements &, const FlagsInit &)
+        {}
+
+        template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
+        bool parse(
+                        Iterator &first,
+                        const Iterator &last,
+                        const ParseVisitor &parse_visitor,
+                        const NoCaseParseVisitor &no_case_parse_visitor,
+                        const Skipper &skipper) const
+                {
+                        return false;
+                }
+
+        template <typename Iterator,typename ParseVisitor, typename Skipper>
+                bool parse(
+                        Iterator &first,
+                        const Iterator &last,
+                        const ParseVisitor &parse_visitor,
+                        const Skipper &skipper) const
+                {
+                    return false;
+                }
+
+        template <typename ParseFunction>
+        bool parse( ParseFunction &function ) const
+                {
+                   return false;
+                }
+    };
+
+    template<typename ComplexKeywords>
+    struct complex_keywords
+    {
+      // Functor which performs the flag initialization for the complex keyword parsers
+      template <typename FlagsType, typename Elements>
+            struct flag_init_value_setter
+            {
+                typedef int result_type;
+
+                flag_init_value_setter(Elements &elements,FlagsType &flags)
+          :flags(flags)
+                    ,elements(elements)
+                {}
+
+                template <typename T>
+                    int operator()(const T &index) const
+                    {
+                        return call(fusion::at_c<T::value>(elements),index);
+                    }
+
+                template <typename T, typename Position, typename Action>
+                    int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
+                    {
+                        // Get the initial state of the flags array and store it in the flags initializer
+                        flags[Position::value]=parser.subject.iter.flag_init();
+                        return 0;
+                    }
+
+                template <typename T, typename Position>
+                    int call( const T & parser, const Position position) const
+                    {
+                        // Get the initial state of the flags array and store it in the flags initializer
+                        flags[Position::value]=parser.iter.flag_init();
+                        return 0;
+                    }
+
+                template <typename T, typename Position>
+                    int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
+                    {
+                        // Get the initial state of the flags array and store it in the flags initializer
+                        flags[Position::value]=parser.subject.iter.flag_init();
+                        return 0;
+                    }
+
+                FlagsType & flags;
+                Elements &elements;
+            };
+
+    template <typename Elements, typename Flags>
+        complex_keywords(Elements &elements, Flags &flags)
+        {
+      flag_init_value_setter<Flags,Elements> flag_initializer(elements,flags);
+      fusion::for_each(complex_keywords_inst,flag_initializer);
+    }
+
+        template <typename ParseFunction>
+        bool parse( ParseFunction &function ) const
+                {
+                   return fusion::any(complex_keywords_inst,function);
+                }
+
+        ComplexKeywords complex_keywords_inst;
+    };
+    // This helper class enables jumping over intermediate directives
+    // down the kwd parser iteration count checking policy
+    struct register_successful_parse
+    {
+        template <typename Subject>
+            static bool call(Subject const &subject,bool &flag, int &counter)
+            {
+                return subject.iter.register_successful_parse(flag,counter);
+            }
+        template <typename Subject, typename Action>
+            static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
+            {
+                return subject.subject.iter.register_successful_parse(flag,counter);
+            }
+        template <typename Subject>
+            static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
+            {
+                return subject.subject.iter.register_successful_parse(flag,counter);
+            }
+    };
+
+    // This helper class enables jumping over intermediate directives
+    // down the kwd parser
+    struct extract_keyword
+    {
+        template <typename Subject>
+            static Subject const& call(Subject const &subject)
+            {
+                return subject;
+            }
+        template <typename Subject, typename Action>
+            static Subject const& call(spirit::qi::action<Subject, Action> const &subject)
+            {
+                return subject.subject;
+            }
+        template <typename Subject>
+            static Subject const& call(spirit::qi::hold_directive<Subject> const &subject)
+            {
+                return subject.subject;
+            }
+    };
+
+    template <typename ParseDispatcher>
+        struct complex_kwd_function
+        {
+            typedef typename ParseDispatcher::iterator_type Iterator;
+            typedef typename ParseDispatcher::context_type Context;
+            typedef typename ParseDispatcher::skipper_type Skipper;
+            complex_kwd_function(
+                    Iterator& first, Iterator const& last
+                    , Context& context, Skipper const& skipper, ParseDispatcher &dispatcher)
+                : first(first)
+                  , last(last)
+                  , context(context)
+                  , skipper(skipper)
+                  , dispatcher(dispatcher)
+            {
+            }
+
+            template <typename Component>
+                bool operator()(Component const& component)
+                {
+                    Iterator save = first;
+                    if(
+                        extract_keyword::call(
+                                fusion::at_c<
+                                        Component::value
+                                        ,typename ParseDispatcher::elements_type
+                                >(dispatcher.elements)
+                                )
+                                .keyword.parse(
+                                        first
+                                        ,last
+                                        ,context
+                                        ,skipper
+                                        ,unused)
+                    )
+                    {
+                        if(!dispatcher(component)){
+                            first = save;
+                            return false;
+                        }
+                        return true;
+                    }
+                    return false;
+                }
+
+            Iterator& first;
+            Iterator const& last;
+            Context& context;
+            Skipper const& skipper;
+            ParseDispatcher const& dispatcher;
+
+            private:
+            // silence MSVC warning C4512: assignment operator could not be generated
+            complex_kwd_function& operator= (complex_kwd_function const&);
+        };
+
+
 }}}}}
 
 #endif
Modified: branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp	(original)
+++ branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -1,6 +1,6 @@
 /*=============================================================================
     Copyright (c) 2001-2011 Joel de Guzman
-    Copyright (c) 2011 Thomas Bernard
+    Copyright (c) 2011-2012 Thomas Bernard
 
     Distributed under the Boost Software License, Version 1.0. (See accompanying
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -22,6 +22,7 @@
 #include <boost/fusion/include/iter_fold.hpp>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/mpl.hpp>
 #include <boost/optional.hpp>
 #include <boost/foreach.hpp>
 #include <boost/array.hpp>
@@ -35,10 +36,14 @@
 #include <boost/mpl/size.hpp>
 #include <boost/mpl/equal_to.hpp>
 #include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/fusion/include/zip_view.hpp>
+#include <boost/fusion/include/as_vector.hpp>
 #include <boost/variant/static_visitor.hpp>
 #include <boost/type_traits/remove_const.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
+#include <boost/fusion/include/any.hpp>
 
 
 namespace boost { namespace spirit
@@ -62,6 +67,7 @@
     namespace detail
     {
         BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)        
+        BOOST_MPL_HAS_XXX_TRAIT_DEF(complex_kwd_parser_id)
 
     
     }
@@ -76,6 +82,16 @@
     template <typename Subject>
     struct is_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_kwd_parser_id<Subject> {};
 
+    template <typename T>
+    struct is_complex_kwd_parser : detail::has_complex_kwd_parser_id<T> {};
+
+    template <typename Subject, typename Action>
+    struct is_complex_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_complex_kwd_parser_id<Subject> {};
+
+    template <typename Subject>
+    struct is_complex_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_complex_kwd_parser_id<Subject> {};
+
+
     // Keywords operator
     template <typename Elements, typename Modifiers>
     struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
@@ -101,10 +117,15 @@
         typedef typename mpl::count_if< 
                 Elements, 
                         mpl::not_< 
+                           mpl::or_<
                             is_kwd_parser<
                                 mpl::_1 
+                              > ,
+                              is_complex_kwd_parser<
+                                mpl::_1
                             > 
                         >
+                        >
                 > non_kwd_subject_count;
         
         /// If the assertion fails here then you probably forgot to wrap a 
@@ -130,208 +151,38 @@
             typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
             
             // Transform the range_c to an mpl vector in order to be able to transform it into a variant
-            typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
+            typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type type;
         
-            // Build the variant type containing the indexes of the parsers
-            typedef typename 
-                spirit::detail::as_variant<
-                    int_vector >::type        type;
         };
+        // Build an index mpl vector
+        typedef typename build_parser_tags< Elements >::type parser_index_vector;
         
-        // Create a variant type to be able to store parser indexes in the embedded symbols parser
-        typedef typename build_parser_tags< Elements >::type parser_index_type;
-
-        ///////////////////////////////////////////////////////////////////////////
-        // build_char_type_sequence
-        //
-        // Build a fusion sequence from the kwd directive specified character type. 
-        ///////////////////////////////////////////////////////////////////////////
-        template <typename Sequence >
-        struct build_char_type_sequence
-        {
-            struct element_char_type
-            {
-                template <typename T>
-                struct result;
+        template <typename idx>
+        struct is_complex_kwd_parser_filter : is_complex_kwd_parser< typename mpl::at<Elements, idx>::type >
+        {};
+
+        template <typename idx>
+        struct is_kwd_parser_filter : is_kwd_parser< typename mpl::at<Elements, idx>::type >
+        {};
 
-                template <typename F, typename Element>
-                struct result<F(Element)>
-                {
-                    typedef typename Element::char_type type;
+        // filter out the string kwd directives
+        typedef typename mpl::filter_view< Elements, is_kwd_parser<mpl_::_> >::type string_keywords;
                         
-                };
-                template <typename F, typename Element,typename Action>
-                struct result<F(spirit::qi::action<Element,Action>) >
-                {
-                    typedef typename Element::char_type type;
-                };
-                template <typename F, typename Element>
-                struct result<F(spirit::qi::hold_directive<Element>)>
-                {   
-                    typedef typename Element::char_type type;
-                };
-
-                // never called, but needed for decltype-based result_of (C++0x)
-                template <typename Element>
-                typename result<element_char_type(Element)>::type
-                operator()(Element&) const;
-            };
+        typedef typename mpl::filter_view< parser_index_vector ,
+                                         is_kwd_parser_filter< mpl::_ >
+                                             >::type string_keyword_indexes;
+        // filter out the complex keywords
+        typedef typename mpl::filter_view< parser_index_vector ,
+                                         is_complex_kwd_parser_filter< mpl::_ >
+                                            >::type complex_keywords_indexes;
 
-            // Compute the list of character types of the child kwd directives
-            typedef typename
-                fusion::result_of::transform<Sequence, element_char_type>::type
-            type;
-        };
-    
-    
-        ///////////////////////////////////////////////////////////////////////////
-        // get_keyword_char_type
-        //
-        // Collapses the character type comming from the subject kwd parsers and
-        // and checks that they are all identical (necessary in order to be able 
-        // to build a tst parser to parse the keywords. 
-        ///////////////////////////////////////////////////////////////////////////
-        template <typename Sequence>
-        struct get_keyword_char_type
-        {
-            // Make sure each of the types occur only once in the type list
-            typedef typename
-                mpl::fold<
-                    Sequence, mpl::vector<>,
-                    mpl::if_<
-                        mpl::contains<mpl::_1, mpl::_2>,
-                        mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
-                    >
-                >::type
-            no_duplicate_char_types;
-        
-            // If the compiler traps here this means you mixed 
-            // character type for the keywords specified in the 
-            // kwd directive sequence.
-            BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-            
-            typedef typename mpl::front<no_duplicate_char_types>::type type;
-                
-        };
-
-        /// Get the character type for the tst parser
-        typedef typename build_char_type_sequence< Elements >::type char_types;
-        typedef typename  get_keyword_char_type< char_types >::type  char_type;
-        
-        /// Our symbols container
-        typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
-        // Filter functor used for case insensitive parsing
-        template <typename CharEncoding>
-        struct no_case_filter
-        {
-            char_type operator()(char_type ch) const
-            {
-                return static_cast<char_type>(CharEncoding::tolower(ch));
-            }
-        };
-    
-        ///////////////////////////////////////////////////////////////////////////
-        // build_case_type_sequence
-        //
-        // Build a fusion sequence from the kwd/ikwd directives 
-        // in order to determine if case sensitive and case insensitive 
-        // keywords have been mixed. 
-        ///////////////////////////////////////////////////////////////////////////
-        template <typename Sequence >
-        struct build_case_type_sequence
-        {
-            struct element_case_type
-            {
-                template <typename T>
-                struct result;
-
-                template <typename F, typename Element>
-                struct result<F(Element)>
-                {
-                    typedef typename Element::no_case_keyword type;
-                        
-                };
-                template <typename F, typename Element,typename Action>
-                struct result<F(spirit::qi::action<Element,Action>) >
-                {
-                    typedef typename Element::no_case_keyword type;
-                };
-                template <typename F, typename Element>
-                struct result<F(spirit::qi::hold_directive<Element>)>
-                {
-                    typedef typename Element::no_case_keyword type;
-                };
-
-                // never called, but needed for decltype-based result_of (C++0x)
-                template <typename Element>
-                typename result<element_case_type(Element)>::type
-                operator()(Element&) const;
-            };
+        //typedef typename fusion::filter_view< Elements, is_complex_kwd_parser< mpl::_ > > complex_keywords_view;
 
-            // Compute the list of character types of the child kwd directives
-            typedef typename
-                fusion::result_of::transform<Sequence, element_case_type>::type
-            type;
-        };
-
-        ///////////////////////////////////////////////////////////////////////////
-        // get_nb_case_types
-        //
-        // Counts the number of entries in the case type sequence matching the 
-        // CaseType parameter (mpl::true_  -> case insensitve
-        //                   , mpl::false_ -> case sensitive
-        ///////////////////////////////////////////////////////////////////////////
-        template <typename Sequence,typename CaseType>
-        struct get_nb_case_types
-        {
-            // Make sure each of the types occur only once in the type list
-            typedef typename
-                mpl::count_if<
-                    Sequence, mpl::equal_to<mpl::_,CaseType> 
-                >::type type;
-                
-            
-        };
-        // Build the case type sequence
-        typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
-        // Count the number of case sensitive entries and case insensitve entries
-        typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
-        typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-        // Get the size of the original sequence
-        typedef typename mpl::size<Elements>::type nb_elements;
-        // Determine if all the kwd directive are case sensitive/insensitive
-        typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
-        typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-        
-        typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-             
-        // Do we have a no case modifier
-        typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
-        // Should the no_case filter always be used ?
-        typedef typename mpl::or_<
-                            no_case_modifier,
-                            mpl::and_< 
-                                 all_directives_of_same_type
-                                ,all_ikwd
-                                >
-                            >::type
-                         no_case;
-        
-        typedef no_case_filter<
-            typename spirit::detail::get_encoding_with_case<
-                Modifiers
-              , char_encoding::standard
-              , no_case::value>::type>
-        nc_filter;
-        // Determine the standard case filter type
         typedef typename mpl::if_<
-            no_case
-          , nc_filter
-          , spirit::qi::tst_pass_through >::type
-        filter_type;
-        
+                typename mpl::empty<complex_keywords_indexes>::type,
+                detail::empty_keywords_list,
+                detail::complex_keywords< complex_keywords_indexes >
+                >::type complex_keywords_type;
         
         // build a bool array and an integer array which will be used to 
         // check that the repetition constraints of the kwd parsers are 
@@ -339,91 +190,24 @@
         typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
         typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
         
-        
-
-        // Functor which adds all the keywords/subject parser indexes 
-        // collected from the subject kwd directives to the keyword tst parser       
-        template< typename Sequence >
-        struct keyword_entry_adder
+        typedef typename mpl::if_<
+                        typename mpl::empty<string_keyword_indexes>::type,
+                        detail::empty_keywords_list,
+                        detail::string_keywords<
+                                Elements,
+                                string_keywords,
+                                string_keyword_indexes,
+                                flags_type,
+                                Modifiers>
+                >::type string_keywords_type;
+        
+        keywords(Elements const& elements_) :
+              elements(elements_)
+            , string_keywords_inst(elements,flags_init)
+      , complex_keywords_inst(elements,flags_init)
         {
-            typedef int result_type;
-
-            keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
-                lookup(lookup)
-                ,flags(flags)
-                {}
-            
-            typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-            
-            template <typename T>
-                int operator()(const int i, const T &parser) const
-                {
-                     // Determine the current position being handled
-                    typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
-                    // Transform the position to a parser index tag
-                    typedef typename mpl::integral_c<int,position_raw::value> position;
-
-                    return call(i,fusion::deref(parser),position());
                 }
 
-            template <typename T, typename Position, typename Action>
-                int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
-                {
-                    
-                    // Make the keyword/parse index entry in the tst parser
-                    lookup->add(
-                        traits::get_begin<char_type>(parser.subject.keyword.str),
-                        traits::get_end<char_type>(parser.subject.keyword.str), 
-                        position
-                        );
-                    // Get the initial state of the flags array and store it in the flags initializer
-                    flags[Position::value]=parser.subject.iter.flag_init();
-                    return 0;
-                }
-    
-            template <typename T, typename Position>
-                int call( const int i, const T & parser, const Position position) const
-                {
-                    // Make the keyword/parse index entry in the tst parser
-                    lookup->add(
-                        traits::get_begin<char_type>(parser.keyword.str),
-                        traits::get_end<char_type>(parser.keyword.str), 
-                        position
-                        );
-                    // Get the initial state of the flags array and store it in the flags initializer
-                    flags[Position::value]=parser.iter.flag_init();
-                    return 0;
-                }
-       
-            template <typename T, typename Position>
-                int call( const int i, const spirit::qi::hold_directive<T> & parser, const Position position) const
-                {
-                    // Make the keyword/parse index entry in the tst parser
-                    lookup->add(
-                        traits::get_begin<char_type>(parser.subject.keyword.str),
-                        traits::get_end<char_type>(parser.subject.keyword.str), 
-                        position
-                        );
-                    // Get the initial state of the flags array and store it in the flags initializer
-                    flags[Position::value]=parser.subject.iter.flag_init();
-                    return 0;
-                }
- 
-
-            shared_ptr<keywords_type> lookup;
-            flags_type & flags;
-        };
-        
-        
-        keywords(Elements const& elements) :
-              elements(elements)
-            , lookup(new keywords_type())
-        {
-            // Loop through all the subject parsers to build the keyword parser symbol parser
-            keyword_entry_adder<Elements> f1(lookup,flags_init);
-            fusion::iter_fold(this->elements,0,f1);
-        }
-        
         template <typename Iterator, typename Context
           , typename Skipper, typename Attribute>
         bool parse(Iterator& first, Iterator const& last
@@ -434,7 +218,7 @@
             // We need to handle the case where kwd / ikwd directives have been mixed
             // This is where we decide which function should be called.
             return parse_impl(first, last, context, skipper, attr_,
-                                typename mpl::or_<all_directives_of_same_type, no_case>::type()
+                                typename string_keywords_type::requires_one_pass()
                              );
         }
         
@@ -442,7 +226,7 @@
           , typename Skipper, typename Attribute>
         bool parse_impl(Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper
-          , Attribute& attr_,mpl::true_ /* no ikwd */) const
+          , Attribute& attr_,mpl::true_ /* one pass */) const
           {
            
             // wrap the attribute in a tuple if it is not a tuple
@@ -458,10 +242,16 @@
                                     , flags_type, counters_type
                                     , typename traits::wrap_if_not_tuple<Attribute>::type
                                     , mpl::false_ > parser_visitor_type;
+
             parser_visitor_type parse_visitor(elements, first, last
                                              , context, skipper, flags
                                              , counters, attr);
             
+            typedef repository::qi::detail::complex_kwd_function< parser_visitor_type > complex_kwd_function_type;
+
+            complex_kwd_function_type
+                     complex_function(first,last,context,skipper,parse_visitor);
+
             // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
             // array.
             // The kwd directive sets and increments the counter when a successeful parse occured
@@ -471,35 +261,36 @@
             // The parsing takes place here in two steps:
             // 1) parse a keyword and fetch the parser index associated with that keyword
             // 2) call the associated parser and store the parsed value in the matching attribute.
-            Iterator save = first;
+
             while(true)
             {
                 
                 spirit::qi::skip_over(first, last, skipper);
-                if (parser_index_type* val_ptr
-                    = lookup->find(first, last, filter_type()))
+                Iterator save = first;
+                if (string_keywords_inst.parse(first, last,parse_visitor,skipper))
                 {
-                    spirit::qi::skip_over(first, last, skipper);
-                    if(!apply_visitor(parse_visitor,*val_ptr)){
-                        first = save;
-                        return false;
-                    }                
                     save = first;
                 }
-                else
+                else {
+          // restore the position to the last successful keyword parse
+          first = save;
+          if(!complex_keywords_inst.parse(complex_function))
                 {
+            first = save;
                     // Check that we are leaving the keywords parser in a successfull state
                     BOOST_FOREACH(bool &valid,flags)
                     {
                         if(!valid)
                         {
-                            first = save;
                             return false;
                         }                        
                     }
                     return true;
                 }
+          else
+            save = first;
             }            
+            }
             return false;
         }
         
@@ -508,7 +299,7 @@
           , typename Skipper, typename Attribute>
         bool parse_impl(Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper
-          , Attribute& attr_,mpl::false_) const
+          , Attribute& attr_,mpl::false_ /* two passes */) const
           {
            
             // wrap the attribute in a tuple if it is not a tuple
@@ -536,6 +327,12 @@
             no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
                                              ,context,skipper,flags,counters,attr);                    
             
+            typedef repository::qi::detail::complex_kwd_function< parser_visitor_type > complex_kwd_function_type;
+
+            complex_kwd_function_type
+                     complex_function(first,last,context,skipper,parse_visitor);
+
+
             // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
             // array.
             // The kwd directive sets and increments the counter when a successeful parse occured
@@ -545,47 +342,37 @@
             // The parsing takes place here in two steps:
             // 1) parse a keyword and fetch the parser index associated with that keyword
             // 2) call the associated parser and store the parsed value in the matching attribute.
-            Iterator save = first;
+
             while(true)
             {
                 spirit::qi::skip_over(first, last, skipper);
-                // First pass case sensitive
-                Iterator saved_first = first;
-                if (parser_index_type* val_ptr
-                    = lookup->find(first, last, spirit::qi::tst_pass_through()))
+                Iterator save = first;
+                // String keywords pass
+                if (string_keywords_inst.parse(first,last,parse_visitor,no_case_parse_visitor,skipper))
                 {
-                    spirit::qi::skip_over(first, last, skipper);
-                    if(!apply_visitor(parse_visitor,*val_ptr)){
-                        first = save;
-                        return false;
-                    }
                     save = first;
                 }
-                // Second pass case insensitive
-                else if(parser_index_type* val_ptr
-                    = lookup->find(saved_first,last,nc_filter()))
+                else {
+          first = save;
+
+          if(!complex_keywords_inst.parse(complex_function))
                 {                    
-                        first = saved_first;
-                        spirit::qi::skip_over(first, last, skipper);
-                        if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
                             first = save;
-                            return false;
-                        }                
-                        save = first;
-                }
-                else
-                {
                     // Check that we are leaving the keywords parser in a successfull state
                     BOOST_FOREACH(bool &valid,flags)
                     {
                         if(!valid)
                         {
-                            first = save;
                             return false;                        
                         }
                     }
                     return true;
                 }
+          else
+          {
+            save = first;
+            }
+                }
             }
             return false;
         }
@@ -600,7 +387,8 @@
         }
         flags_type flags_init;
         Elements elements;
-        shared_ptr<keywords_type> lookup;
+        string_keywords_type string_keywords_inst;
+        complex_keywords_type complex_keywords_inst;
         
     };
 }}}}
@@ -634,6 +422,14 @@
     template <typename Elements, typename Modifiers>
     struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
       : nary_has_semantic_action<Elements> {};
+
+    template <typename Elements, typename Attribute, typename Context
+        , typename Iterator, typename Modifiers>
+    struct handles_container<repository::qi::keywords<Elements,Modifiers>, Attribute
+        , Context, Iterator>
+      : nary_handles_container<Elements, Attribute, Context, Iterator> {};
+
+
 }}}
 
 #endif
Modified: branches/release/boost/spirit/repository/home/support/kwd.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/support/kwd.hpp	(original)
+++ branches/release/boost/spirit/repository/home/support/kwd.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -15,7 +15,7 @@
 namespace boost { namespace spirit { namespace repository
 {
     // The distinct extended terminal
-    BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( kwd, kwd_type )( ikwd, ikwd_type ) )
+    BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( kwd, kwd_type )( ikwd, ikwd_type )(dkwd, dkwd_type)(idkwd, idkwd_type) )
 
 }}}
 
Deleted: branches/release/boost/spirit/symbols.hpp
==============================================================================
--- branches/release/boost/spirit/symbols.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_SYMBOLS
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_SYMBOLS
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_symbols.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_symbols.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_symbols.hpp>
-
-#endif
Deleted: branches/release/boost/spirit/utility.hpp
==============================================================================
--- branches/release/boost/spirit/utility.hpp	2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
-  Copyright (c) 2001-2008 Joel de Guzman
-  Copyright (c) 2001-2008 Hartmut Kaiser
-  http://spirit.sourceforge.net/
-
-  Distributed under the Boost Software License, Version 1.0. (See accompanying
-  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_UTILITY
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_UTILITY
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-#  pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_utility.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-#  warning "This header is deprecated. Please use: boost/spirit/include/classic_utility.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_utility.hpp>
-
-#endif