diff --git a/include/ndnboost/regex/v4/basic_regex.hpp b/include/ndnboost/regex/v4/basic_regex.hpp
new file mode 100644
index 0000000..9fe4ea7
--- /dev/null
+++ b/include/ndnboost/regex/v4/basic_regex.hpp
@@ -0,0 +1,782 @@
+/*
+ *
+ * Copyright (c) 1998-2004 John Maddock
+ * Copyright 2011 Garmin Ltd. or its subsidiaries
+ *
+ * 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org/ for most recent version.
+  *   FILE         basic_regex.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares template class basic_regex.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_BASIC_REGEX_HPP
+#define NDNBOOST_REGEX_V4_BASIC_REGEX_HPP
+
+#include <ndnboost/type_traits/is_same.hpp>
+#include <ndnboost/functional/hash.hpp>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231 4800)
+#if NDNBOOST_MSVC < 1600
+#pragma warning(disable : 4660)
+#endif
+#endif
+
+namespace re_detail{
+
+//
+// forward declaration, we will need this one later:
+//
+template <class charT, class traits>
+class basic_regex_parser;
+
+template <class I>
+void bubble_down_one(I first, I last)
+{
+   if(first != last)
+   {
+      I next = last - 1;
+      while((next != first) && (*next < *(next-1)))
+      {
+         (next-1)->swap(*next);
+         --next;
+      }
+   }
+}
+
+template <class Iterator>
+inline int hash_value_from_capture_name(Iterator i, Iterator j)
+{
+   std::size_t r = ndnboost::hash_range(i, j);
+   r %= ((std::numeric_limits<int>::max)() - 10001);
+   r += 10000;
+   return static_cast<int>(r);
+}
+
+class named_subexpressions
+{
+public:
+   struct name
+   {
+      template <class charT>
+      name(const charT* i, const charT* j, int idx)
+         : index(idx) 
+      { 
+         hash = hash_value_from_capture_name(i, j); 
+      }
+      name(int h, int idx)
+         : index(idx), hash(h)
+      { 
+      }
+      int index;
+      int hash;
+      bool operator < (const name& other)const
+      {
+         return hash < other.hash;
+      }
+      bool operator == (const name& other)const
+      {
+         return hash == other.hash; 
+      }
+      void swap(name& other)
+      {
+         std::swap(index, other.index);
+         std::swap(hash, other.hash);
+      }
+   };
+
+   typedef std::vector<name>::const_iterator const_iterator;
+   typedef std::pair<const_iterator, const_iterator> range_type;
+
+   named_subexpressions(){}
+
+   template <class charT>
+   void set_name(const charT* i, const charT* j, int index)
+   {
+      m_sub_names.push_back(name(i, j, index));
+      bubble_down_one(m_sub_names.begin(), m_sub_names.end());
+   }
+   template <class charT>
+   int get_id(const charT* i, const charT* j)const
+   {
+      name t(i, j, 0);
+      typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
+      if((pos != m_sub_names.end()) && (*pos == t))
+      {
+         return pos->index;
+      }
+      return -1;
+   }
+   template <class charT>
+   range_type equal_range(const charT* i, const charT* j)const
+   {
+      name t(i, j, 0);
+      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
+   }
+   int get_id(int h)const
+   {
+      name t(h, 0);
+      std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
+      if((pos != m_sub_names.end()) && (*pos == t))
+      {
+         return pos->index;
+      }
+      return -1;
+   }
+   range_type equal_range(int h)const
+   {
+      name t(h, 0);
+      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
+   }
+private:
+   std::vector<name> m_sub_names;
+};
+
+//
+// class regex_data:
+// represents the data we wish to expose to the matching algorithms.
+//
+template <class charT, class traits>
+struct regex_data : public named_subexpressions
+{
+   typedef regex_constants::syntax_option_type   flag_type;
+   typedef std::size_t                           size_type;  
+
+   regex_data(const ::ndnboost::shared_ptr<
+      ::ndnboost::regex_traits_wrapper<traits> >& t) 
+      : m_ptraits(t), m_expression(0), m_expression_len(0) {}
+   regex_data() 
+      : m_ptraits(new ::ndnboost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0) {}
+
+   ::ndnboost::shared_ptr<
+      ::ndnboost::regex_traits_wrapper<traits>
+      >                        m_ptraits;                 // traits class instance
+   flag_type                   m_flags;                   // flags with which we were compiled
+   int                         m_status;                  // error code (0 implies OK).
+   const charT*                m_expression;              // the original expression
+   std::ptrdiff_t              m_expression_len;          // the length of the original expression
+   size_type                   m_mark_count;              // the number of marked sub-expressions
+   re_detail::re_syntax_base*  m_first_state;             // the first state of the machine
+   unsigned                    m_restart_type;            // search optimisation type
+   unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match
+   unsigned int                m_can_be_null;             // whether we can match a null string
+   re_detail::raw_storage      m_data;                    // the buffer in which our states are constructed
+   typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character
+   std::vector<
+      std::pair<
+      std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.
+   bool                        m_has_recursions;          // whether we have recursive expressions;
+};
+//
+// class basic_regex_implementation
+// pimpl implementation class for basic_regex.
+//
+template <class charT, class traits>
+class basic_regex_implementation
+   : public regex_data<charT, traits>
+{
+public:
+   typedef regex_constants::syntax_option_type   flag_type;
+   typedef std::ptrdiff_t                        difference_type;
+   typedef std::size_t                           size_type; 
+   typedef typename traits::locale_type          locale_type;
+   typedef const charT*                          const_iterator;
+
+   basic_regex_implementation(){}
+   basic_regex_implementation(const ::ndnboost::shared_ptr<
+      ::ndnboost::regex_traits_wrapper<traits> >& t)
+      : regex_data<charT, traits>(t) {}
+   void assign(const charT* arg_first,
+                          const charT* arg_last,
+                          flag_type f)
+   {
+      regex_data<charT, traits>* pdat = this;
+      basic_regex_parser<charT, traits> parser(pdat);
+      parser.parse(arg_first, arg_last, f);
+   }
+
+   locale_type NDNBOOST_REGEX_CALL imbue(locale_type l)
+   { 
+      return this->m_ptraits->imbue(l); 
+   }
+   locale_type NDNBOOST_REGEX_CALL getloc()const
+   { 
+      return this->m_ptraits->getloc(); 
+   }
+   std::basic_string<charT> NDNBOOST_REGEX_CALL str()const
+   {
+      std::basic_string<charT> result;
+      if(this->m_status == 0)
+         result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
+      return result;
+   }
+   const_iterator NDNBOOST_REGEX_CALL expression()const
+   {
+      return this->m_expression;
+   }
+   std::pair<const_iterator, const_iterator> NDNBOOST_REGEX_CALL subexpression(std::size_t n)const
+   {
+      if(n == 0)
+         ndnboost::throw_exception(std::out_of_range("0 is not a valid subexpression index."));
+      const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n - 1);
+      std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
+      return p;
+   }
+   //
+   // begin, end:
+   const_iterator NDNBOOST_REGEX_CALL begin()const
+   { 
+      return (this->m_status ? 0 : this->m_expression); 
+   }
+   const_iterator NDNBOOST_REGEX_CALL end()const
+   { 
+      return (this->m_status ? 0 : this->m_expression + this->m_expression_len); 
+   }
+   flag_type NDNBOOST_REGEX_CALL flags()const
+   {
+      return this->m_flags;
+   }
+   size_type NDNBOOST_REGEX_CALL size()const
+   {
+      return this->m_expression_len;
+   }
+   int NDNBOOST_REGEX_CALL status()const
+   {
+      return this->m_status;
+   }
+   size_type NDNBOOST_REGEX_CALL mark_count()const
+   {
+      return this->m_mark_count;
+   }
+   const re_detail::re_syntax_base* get_first_state()const
+   {
+      return this->m_first_state;
+   }
+   unsigned get_restart_type()const
+   {
+      return this->m_restart_type;
+   }
+   const unsigned char* get_map()const
+   {
+      return this->m_startmap;
+   }
+   const ::ndnboost::regex_traits_wrapper<traits>& get_traits()const
+   {
+      return *(this->m_ptraits);
+   }
+   bool can_be_null()const
+   {
+      return this->m_can_be_null;
+   }
+   const regex_data<charT, traits>& get_data()const
+   {
+      basic_regex_implementation<charT, traits> const* p = this;
+      return *static_cast<const regex_data<charT, traits>*>(p);
+   }
+};
+
+} // namespace re_detail
+//
+// class basic_regex:
+// represents the compiled
+// regular expression:
+//
+
+#ifdef NDNBOOST_REGEX_NO_FWD
+template <class charT, class traits = regex_traits<charT> >
+#else
+template <class charT, class traits >
+#endif
+class basic_regex : public regbase
+{
+public:
+   // typedefs:
+   typedef std::size_t                           traits_size_type;
+   typedef typename traits::string_type          traits_string_type;
+   typedef charT                                 char_type;
+   typedef traits                                traits_type;
+
+   typedef charT                                 value_type;
+   typedef charT&                                reference;
+   typedef const charT&                          const_reference;
+   typedef const charT*                          const_iterator;
+   typedef const_iterator                        iterator;
+   typedef std::ptrdiff_t                        difference_type;
+   typedef std::size_t                           size_type;   
+   typedef regex_constants::syntax_option_type   flag_type;
+   // locale_type
+   // placeholder for actual locale type used by the
+   // traits class to localise *this.
+   typedef typename traits::locale_type          locale_type;
+   
+public:
+   explicit basic_regex(){}
+   explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
+   {
+      assign(p, f);
+   }
+   basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+   {
+      assign(p1, p2, f);
+   }
+   basic_regex(const charT* p, size_type len, flag_type f)
+   {
+      assign(p, len, f);
+   }
+   basic_regex(const basic_regex& that)
+      : m_pimpl(that.m_pimpl) {}
+   ~basic_regex(){}
+   basic_regex& NDNBOOST_REGEX_CALL operator=(const basic_regex& that)
+   {
+      return assign(that);
+   }
+   basic_regex& NDNBOOST_REGEX_CALL operator=(const charT* ptr)
+   {
+      return assign(ptr);
+   }
+
+   //
+   // assign:
+   basic_regex& assign(const basic_regex& that)
+   { 
+      m_pimpl = that.m_pimpl;
+      return *this; 
+   }
+   basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
+   {
+      return assign(p, p + traits::length(p), f);
+   }
+   basic_regex& assign(const charT* p, size_type len, flag_type f)
+   {
+      return assign(p, p + len, f);
+   }
+private:
+   basic_regex& do_assign(const charT* p1,
+                          const charT* p2,
+                          flag_type f);
+public:
+   basic_regex& assign(const charT* p1,
+                          const charT* p2,
+                          flag_type f = regex_constants::normal)
+   {
+      return do_assign(p1, p2, f);
+   }
+#if !defined(NDNBOOST_NO_MEMBER_TEMPLATES)
+
+   template <class ST, class SA>
+   unsigned int NDNBOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+   { 
+      return set_expression(p.data(), p.data() + p.size(), f); 
+   }
+
+   template <class ST, class SA>
+   explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+   { 
+      assign(p, f); 
+   }
+
+   template <class InputIterator>
+   basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
+   {
+      typedef typename traits::string_type seq_type;
+      seq_type a(arg_first, arg_last);
+      if(a.size())
+         assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
+      else
+         assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
+   }
+
+   template <class ST, class SA>
+   basic_regex& NDNBOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
+   {
+      return assign(p.data(), p.data() + p.size(), regex_constants::normal);
+   }
+
+   template <class string_traits, class A>
+   basic_regex& NDNBOOST_REGEX_CALL assign(
+       const std::basic_string<charT, string_traits, A>& s,
+       flag_type f = regex_constants::normal)
+   {
+      return assign(s.data(), s.data() + s.size(), f);
+   }
+
+   template <class InputIterator>
+   basic_regex& NDNBOOST_REGEX_CALL assign(InputIterator arg_first,
+                          InputIterator arg_last,
+                          flag_type f = regex_constants::normal)
+   {
+      typedef typename traits::string_type seq_type;
+      seq_type a(arg_first, arg_last);
+      if(a.size())
+      {
+         const charT* p1 = &*a.begin();
+         const charT* p2 = &*a.begin() + a.size();
+         return assign(p1, p2, f);
+      }
+      return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
+   }
+#else
+   unsigned int NDNBOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
+   { 
+      return set_expression(p.data(), p.data() + p.size(), f); 
+   }
+
+   basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
+   { 
+      assign(p, f); 
+   }
+
+   basic_regex& NDNBOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
+   {
+      return assign(p.data(), p.data() + p.size(), regex_constants::normal);
+   }
+
+   basic_regex& NDNBOOST_REGEX_CALL assign(
+       const std::basic_string<charT>& s,
+       flag_type f = regex_constants::normal)
+   {
+      return assign(s.data(), s.data() + s.size(), f);
+   }
+
+#endif
+
+   //
+   // locale:
+   locale_type NDNBOOST_REGEX_CALL imbue(locale_type l);
+   locale_type NDNBOOST_REGEX_CALL getloc()const
+   { 
+      return m_pimpl.get() ? m_pimpl->getloc() : locale_type(); 
+   }
+   //
+   // getflags:
+   // retained for backwards compatibility only, "flags"
+   // is now the preferred name:
+   flag_type NDNBOOST_REGEX_CALL getflags()const
+   { 
+      return flags();
+   }
+   flag_type NDNBOOST_REGEX_CALL flags()const
+   { 
+      return m_pimpl.get() ? m_pimpl->flags() : 0;
+   }
+   //
+   // str:
+   std::basic_string<charT> NDNBOOST_REGEX_CALL str()const
+   {
+      return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
+   }
+   //
+   // begin, end, subexpression:
+   std::pair<const_iterator, const_iterator> NDNBOOST_REGEX_CALL subexpression(std::size_t n)const
+   {
+      if(!m_pimpl.get())
+         ndnboost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
+      return m_pimpl->subexpression(n);
+   }
+   const_iterator NDNBOOST_REGEX_CALL begin()const
+   { 
+      return (m_pimpl.get() ? m_pimpl->begin() : 0); 
+   }
+   const_iterator NDNBOOST_REGEX_CALL end()const
+   { 
+      return (m_pimpl.get() ? m_pimpl->end() : 0); 
+   }
+   //
+   // swap:
+   void NDNBOOST_REGEX_CALL swap(basic_regex& that)throw()
+   {
+      m_pimpl.swap(that.m_pimpl);
+   }
+   //
+   // size:
+   size_type NDNBOOST_REGEX_CALL size()const
+   { 
+      return (m_pimpl.get() ? m_pimpl->size() : 0); 
+   }
+   //
+   // max_size:
+   size_type NDNBOOST_REGEX_CALL max_size()const
+   { 
+      return UINT_MAX; 
+   }
+   //
+   // empty:
+   bool NDNBOOST_REGEX_CALL empty()const
+   { 
+      return (m_pimpl.get() ? 0 != m_pimpl->status() : true); 
+   }
+
+   size_type NDNBOOST_REGEX_CALL mark_count()const 
+   { 
+      return (m_pimpl.get() ? m_pimpl->mark_count() : 0); 
+   }
+
+   int status()const
+   {
+      return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
+   }
+
+   int NDNBOOST_REGEX_CALL compare(const basic_regex& that) const
+   {
+      if(m_pimpl.get() == that.m_pimpl.get())
+         return 0;
+      if(!m_pimpl.get())
+         return -1;
+      if(!that.m_pimpl.get())
+         return 1;
+      if(status() != that.status())
+         return status() - that.status();
+      if(flags() != that.flags())
+         return flags() - that.flags();
+      return str().compare(that.str());
+   }
+   bool NDNBOOST_REGEX_CALL operator==(const basic_regex& e)const
+   { 
+      return compare(e) == 0; 
+   }
+   bool NDNBOOST_REGEX_CALL operator != (const basic_regex& e)const
+   { 
+      return compare(e) != 0; 
+   }
+   bool NDNBOOST_REGEX_CALL operator<(const basic_regex& e)const
+   { 
+      return compare(e) < 0; 
+   }
+   bool NDNBOOST_REGEX_CALL operator>(const basic_regex& e)const
+   { 
+      return compare(e) > 0; 
+   }
+   bool NDNBOOST_REGEX_CALL operator<=(const basic_regex& e)const
+   { 
+      return compare(e) <= 0; 
+   }
+   bool NDNBOOST_REGEX_CALL operator>=(const basic_regex& e)const
+   { 
+      return compare(e) >= 0; 
+   }
+
+   //
+   // The following are deprecated as public interfaces
+   // but are available for compatibility with earlier versions.
+   const charT* NDNBOOST_REGEX_CALL expression()const 
+   { 
+      return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0); 
+   }
+   unsigned int NDNBOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+   {
+      assign(p1, p2, f | regex_constants::no_except);
+      return status();
+   }
+   unsigned int NDNBOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal) 
+   { 
+      assign(p, f | regex_constants::no_except); 
+      return status();
+   }
+   unsigned int NDNBOOST_REGEX_CALL error_code()const
+   {
+      return status();
+   }
+   //
+   // private access methods:
+   //
+   const re_detail::re_syntax_base* get_first_state()const
+   {
+      NDNBOOST_ASSERT(0 != m_pimpl.get());
+      return m_pimpl->get_first_state();
+   }
+   unsigned get_restart_type()const
+   {
+      NDNBOOST_ASSERT(0 != m_pimpl.get());
+      return m_pimpl->get_restart_type();
+   }
+   const unsigned char* get_map()const
+   {
+      NDNBOOST_ASSERT(0 != m_pimpl.get());
+      return m_pimpl->get_map();
+   }
+   const ::ndnboost::regex_traits_wrapper<traits>& get_traits()const
+   {
+      NDNBOOST_ASSERT(0 != m_pimpl.get());
+      return m_pimpl->get_traits();
+   }
+   bool can_be_null()const
+   {
+      NDNBOOST_ASSERT(0 != m_pimpl.get());
+      return m_pimpl->can_be_null();
+   }
+   const re_detail::regex_data<charT, traits>& get_data()const
+   {
+      NDNBOOST_ASSERT(0 != m_pimpl.get());
+      return m_pimpl->get_data();
+   }
+   ndnboost::shared_ptr<re_detail::named_subexpressions > get_named_subs()const
+   {
+      return m_pimpl;
+   }
+
+private:
+   shared_ptr<re_detail::basic_regex_implementation<charT, traits> > m_pimpl;
+};
+
+//
+// out of line members;
+// these are the only members that mutate the basic_regex object,
+// and are designed to provide the strong exception guarentee
+// (in the event of a throw, the state of the object remains unchanged).
+//
+template <class charT, class traits>
+basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
+                        const charT* p2,
+                        flag_type f)
+{
+   shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
+   if(!m_pimpl.get())
+   {
+      temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
+   }
+   else
+   {
+      temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
+   }
+   temp->assign(p1, p2, f);
+   temp.swap(m_pimpl);
+   return *this;
+}
+
+template <class charT, class traits>
+typename basic_regex<charT, traits>::locale_type NDNBOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
+{ 
+   shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp(new re_detail::basic_regex_implementation<charT, traits>());
+   locale_type result = temp->imbue(l);
+   temp.swap(m_pimpl);
+   return result;
+}
+
+//
+// non-members:
+//
+template <class charT, class traits>
+void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
+{
+   e1.swap(e2);
+}
+
+#ifndef NDNBOOST_NO_STD_LOCALE
+template <class charT, class traits, class traits2>
+std::basic_ostream<charT, traits>& 
+   operator << (std::basic_ostream<charT, traits>& os, 
+                const basic_regex<charT, traits2>& e)
+{
+   return (os << e.str());
+}
+#else
+template <class traits>
+std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
+{
+   return (os << e.str());
+}
+#endif
+
+//
+// class reg_expression:
+// this is provided for backwards compatibility only,
+// it is deprecated, no not use!
+//
+#ifdef NDNBOOST_REGEX_NO_FWD
+template <class charT, class traits = regex_traits<charT> >
+#else
+template <class charT, class traits >
+#endif
+class reg_expression : public basic_regex<charT, traits>
+{
+public:
+   typedef typename basic_regex<charT, traits>::flag_type flag_type;
+   typedef typename basic_regex<charT, traits>::size_type size_type;
+   explicit reg_expression(){}
+   explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
+      : basic_regex<charT, traits>(p, f){}
+   reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+      : basic_regex<charT, traits>(p1, p2, f){}
+   reg_expression(const charT* p, size_type len, flag_type f)
+      : basic_regex<charT, traits>(p, len, f){}
+   reg_expression(const reg_expression& that)
+      : basic_regex<charT, traits>(that) {}
+   ~reg_expression(){}
+   reg_expression& NDNBOOST_REGEX_CALL operator=(const reg_expression& that)
+   {
+      return this->assign(that);
+   }
+
+#if !defined(NDNBOOST_NO_MEMBER_TEMPLATES)
+   template <class ST, class SA>
+   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+   : basic_regex<charT, traits>(p, f)
+   { 
+   }
+
+   template <class InputIterator>
+   reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
+   : basic_regex<charT, traits>(arg_first, arg_last, f)
+   {
+   }
+
+   template <class ST, class SA>
+   reg_expression& NDNBOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
+   {
+      this->assign(p);
+      return *this;
+   }
+#else
+   explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
+   : basic_regex<charT, traits>(p, f)
+   { 
+   }
+
+   reg_expression& NDNBOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
+   {
+      this->assign(p);
+      return *this;
+   }
+#endif
+
+};
+
+#ifdef NDNBOOST_MSVC
+#pragma warning (pop)
+#endif
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/basic_regex_creator.hpp b/include/ndnboost/regex/v4/basic_regex_creator.hpp
new file mode 100644
index 0000000..5db04e6
--- /dev/null
+++ b/include/ndnboost/regex/v4/basic_regex_creator.hpp
@@ -0,0 +1,1571 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         basic_regex_creator.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares template class basic_regex_creator which fills in
+  *                the data members of a regex_data object.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
+#define NDNBOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable: 4800)
+#endif
+
+namespace ndnboost{
+
+namespace re_detail{
+
+template <class charT>
+struct digraph : public std::pair<charT, charT>
+{
+   digraph() : std::pair<charT, charT>(0, 0){}
+   digraph(charT c1) : std::pair<charT, charT>(c1, 0){}
+   digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2)
+   {}
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+   digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}
+#endif
+   template <class Seq>
+   digraph(const Seq& s) : std::pair<charT, charT>()
+   {
+      NDNBOOST_ASSERT(s.size() <= 2);
+      NDNBOOST_ASSERT(s.size());
+      this->first = s[0];
+      this->second = (s.size() > 1) ? s[1] : 0;
+   }
+};
+
+template <class charT, class traits>
+class basic_char_set
+{
+public:
+   typedef digraph<charT>                   digraph_type;
+   typedef typename traits::string_type     string_type;
+   typedef typename traits::char_class_type m_type;
+
+   basic_char_set()
+   {
+      m_negate = false;
+      m_has_digraphs = false;
+      m_classes = 0;
+      m_negated_classes = 0;
+      m_empty = true;
+   }
+
+   void add_single(const digraph_type& s)
+   {
+      m_singles.insert(m_singles.end(), s);
+      if(s.second)
+         m_has_digraphs = true;
+      m_empty = false;
+   }
+   void add_range(const digraph_type& first, const digraph_type& end)
+   {
+      m_ranges.insert(m_ranges.end(), first);
+      m_ranges.insert(m_ranges.end(), end);
+      if(first.second)
+      {
+         m_has_digraphs = true;
+         add_single(first);
+      }
+      if(end.second)
+      {
+         m_has_digraphs = true;
+         add_single(end);
+      }
+      m_empty = false;
+   }
+   void add_class(m_type m)
+   {
+      m_classes |= m;
+      m_empty = false;
+   }
+   void add_negated_class(m_type m)
+   {
+      m_negated_classes |= m;
+      m_empty = false;
+   }
+   void add_equivalent(const digraph_type& s)
+   {
+      m_equivalents.insert(m_equivalents.end(), s);
+      if(s.second)
+      {
+         m_has_digraphs = true;
+         add_single(s);
+      }
+      m_empty = false;
+   }
+   void negate()
+   { 
+      m_negate = true;
+      //m_empty = false;
+   }
+
+   //
+   // accessor functions:
+   //
+   bool has_digraphs()const
+   {
+      return m_has_digraphs;
+   }
+   bool is_negated()const
+   {
+      return m_negate;
+   }
+   typedef typename std::vector<digraph_type>::const_iterator  list_iterator;
+   list_iterator singles_begin()const
+   {
+      return m_singles.begin();
+   }
+   list_iterator singles_end()const
+   {
+      return m_singles.end();
+   }
+   list_iterator ranges_begin()const
+   {
+      return m_ranges.begin();
+   }
+   list_iterator ranges_end()const
+   {
+      return m_ranges.end();
+   }
+   list_iterator equivalents_begin()const
+   {
+      return m_equivalents.begin();
+   }
+   list_iterator equivalents_end()const
+   {
+      return m_equivalents.end();
+   }
+   m_type classes()const
+   {
+      return m_classes;
+   }
+   m_type negated_classes()const
+   {
+      return m_negated_classes;
+   }
+   bool empty()const
+   {
+      return m_empty;
+   }
+private:
+   std::vector<digraph_type> m_singles;         // a list of single characters to match
+   std::vector<digraph_type> m_ranges;          // a list of end points of our ranges
+   bool                      m_negate;          // true if the set is to be negated
+   bool                      m_has_digraphs;    // true if we have digraphs present
+   m_type                    m_classes;         // character classes to match
+   m_type                    m_negated_classes; // negated character classes to match
+   bool                      m_empty;           // whether we've added anything yet
+   std::vector<digraph_type> m_equivalents;     // a list of equivalence classes
+};
+   
+template <class charT, class traits>
+class basic_regex_creator
+{
+public:
+   basic_regex_creator(regex_data<charT, traits>* data);
+   std::ptrdiff_t getoffset(void* addr)
+   {
+      return getoffset(addr, m_pdata->m_data.data());
+   }
+   std::ptrdiff_t getoffset(const void* addr, const void* base)
+   {
+      return static_cast<const char*>(addr) - static_cast<const char*>(base);
+   }
+   re_syntax_base* getaddress(std::ptrdiff_t off)
+   {
+      return getaddress(off, m_pdata->m_data.data());
+   }
+   re_syntax_base* getaddress(std::ptrdiff_t off, void* base)
+   {
+      return static_cast<re_syntax_base*>(static_cast<void*>(static_cast<char*>(base) + off));
+   }
+   void init(unsigned l_flags)
+   {
+      m_pdata->m_flags = l_flags;
+      m_icase = l_flags & regex_constants::icase;
+   }
+   regbase::flag_type flags()
+   {
+      return m_pdata->m_flags;
+   }
+   void flags(regbase::flag_type f)
+   {
+      m_pdata->m_flags = f;
+      if(m_icase != static_cast<bool>(f & regbase::icase))
+      {
+         m_icase = static_cast<bool>(f & regbase::icase);
+      }
+   }
+   re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
+   re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
+   re_literal* append_literal(charT c);
+   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set);
+   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, mpl::false_*);
+   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, mpl::true_*);
+   void finalize(const charT* p1, const charT* p2);
+protected:
+   regex_data<charT, traits>*    m_pdata;              // pointer to the basic_regex_data struct we are filling in
+   const ::ndnboost::regex_traits_wrapper<traits>&  
+                                 m_traits;             // convenience reference to traits class
+   re_syntax_base*               m_last_state;         // the last state we added
+   bool                          m_icase;              // true for case insensitive matches
+   unsigned                      m_repeater_id;        // the state_id of the next repeater
+   bool                          m_has_backrefs;       // true if there are actually any backrefs
+   unsigned                      m_backrefs;           // bitmask of permitted backrefs
+   ndnboost::uintmax_t              m_bad_repeats;        // bitmask of repeats we can't deduce a startmap for;
+   bool                          m_has_recursions;     // set when we have recursive expresisons to fixup
+   std::vector<bool>             m_recursion_checks;   // notes which recursions we've followed while analysing this expression
+   typename traits::char_class_type m_word_mask;       // mask used to determine if a character is a word character
+   typename traits::char_class_type m_mask_space;      // mask used to determine if a character is a word character
+   typename traits::char_class_type m_lower_mask;       // mask used to determine if a character is a lowercase character
+   typename traits::char_class_type m_upper_mask;      // mask used to determine if a character is an uppercase character
+   typename traits::char_class_type m_alpha_mask;      // mask used to determine if a character is an alphabetic character
+private:
+   basic_regex_creator& operator=(const basic_regex_creator&);
+   basic_regex_creator(const basic_regex_creator&);
+
+   void fixup_pointers(re_syntax_base* state);
+   void fixup_recursions(re_syntax_base* state);
+   void create_startmaps(re_syntax_base* state);
+   int calculate_backstep(re_syntax_base* state);
+   void create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask);
+   unsigned get_restart_type(re_syntax_base* state);
+   void set_all_masks(unsigned char* bits, unsigned char);
+   bool is_bad_repeat(re_syntax_base* pt);
+   void set_bad_repeat(re_syntax_base* pt);
+   syntax_element_type get_repeat_type(re_syntax_base* state);
+   void probe_leading_repeat(re_syntax_base* state);
+};
+
+template <class charT, class traits>
+basic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)
+   : m_pdata(data), m_traits(*(data->m_ptraits)), m_last_state(0), m_repeater_id(0), m_has_backrefs(false), m_backrefs(0), m_has_recursions(false)
+{
+   m_pdata->m_data.clear();
+   m_pdata->m_status = ::ndnboost::regex_constants::error_ok;
+   static const charT w = 'w';
+   static const charT s = 's';
+   static const charT l[5] = { 'l', 'o', 'w', 'e', 'r', };
+   static const charT u[5] = { 'u', 'p', 'p', 'e', 'r', };
+   static const charT a[5] = { 'a', 'l', 'p', 'h', 'a', };
+   m_word_mask = m_traits.lookup_classname(&w, &w +1);
+   m_mask_space = m_traits.lookup_classname(&s, &s +1);
+   m_lower_mask = m_traits.lookup_classname(l, l + 5);
+   m_upper_mask = m_traits.lookup_classname(u, u + 5);
+   m_alpha_mask = m_traits.lookup_classname(a, a + 5);
+   m_pdata->m_word_mask = m_word_mask;
+   NDNBOOST_ASSERT(m_word_mask != 0); 
+   NDNBOOST_ASSERT(m_mask_space != 0); 
+   NDNBOOST_ASSERT(m_lower_mask != 0); 
+   NDNBOOST_ASSERT(m_upper_mask != 0); 
+   NDNBOOST_ASSERT(m_alpha_mask != 0); 
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::append_state(syntax_element_type t, std::size_t s)
+{
+   // if the state is a backref then make a note of it:
+   if(t == syntax_element_backref)
+      this->m_has_backrefs = true;
+   // append a new state, start by aligning our last one:
+   m_pdata->m_data.align();
+   // set the offset to the next state in our last one:
+   if(m_last_state)
+      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
+   // now actually extent our data:
+   m_last_state = static_cast<re_syntax_base*>(m_pdata->m_data.extend(s));
+   // fill in boilerplate options in the new state:
+   m_last_state->next.i = 0;
+   m_last_state->type = t;
+   return m_last_state;
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s)
+{
+   // append a new state, start by aligning our last one:
+   m_pdata->m_data.align();
+   // set the offset to the next state in our last one:
+   if(m_last_state)
+      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
+   // remember the last state position:
+   std::ptrdiff_t off = getoffset(m_last_state) + s;
+   // now actually insert our data:
+   re_syntax_base* new_state = static_cast<re_syntax_base*>(m_pdata->m_data.insert(pos, s));
+   // fill in boilerplate options in the new state:
+   new_state->next.i = s;
+   new_state->type = t;
+   m_last_state = getaddress(off);
+   return new_state;
+}
+
+template <class charT, class traits>
+re_literal* basic_regex_creator<charT, traits>::append_literal(charT c)
+{
+   re_literal* result;
+   // start by seeing if we have an existing re_literal we can extend:
+   if((0 == m_last_state) || (m_last_state->type != syntax_element_literal))
+   {
+      // no existing re_literal, create a new one:
+      result = static_cast<re_literal*>(append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
+      result->length = 1;
+      *static_cast<charT*>(static_cast<void*>(result+1)) = m_traits.translate(c, m_icase);
+   }
+   else
+   {
+      // we have an existing re_literal, extend it:
+      std::ptrdiff_t off = getoffset(m_last_state);
+      m_pdata->m_data.extend(sizeof(charT));
+      m_last_state = result = static_cast<re_literal*>(getaddress(off));
+      charT* characters = static_cast<charT*>(static_cast<void*>(result+1));
+      characters[result->length] = m_traits.translate(c, m_icase);
+      ++(result->length);
+   }
+   return result;
+}
+
+template <class charT, class traits>
+inline re_syntax_base* basic_regex_creator<charT, traits>::append_set(
+   const basic_char_set<charT, traits>& char_set)
+{
+   typedef mpl::bool_< (sizeof(charT) == 1) > truth_type;
+   return char_set.has_digraphs() 
+      ? append_set(char_set, static_cast<mpl::false_*>(0))
+      : append_set(char_set, static_cast<truth_type*>(0));
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::append_set(
+   const basic_char_set<charT, traits>& char_set, mpl::false_*)
+{
+   typedef typename traits::string_type string_type;
+   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
+   typedef typename traits::char_class_type m_type;
+   
+   re_set_long<m_type>* result = static_cast<re_set_long<m_type>*>(append_state(syntax_element_long_set, sizeof(re_set_long<m_type>)));
+   //
+   // fill in the basics:
+   //
+   result->csingles = static_cast<unsigned int>(::ndnboost::re_detail::distance(char_set.singles_begin(), char_set.singles_end()));
+   result->cranges = static_cast<unsigned int>(::ndnboost::re_detail::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;
+   result->cequivalents = static_cast<unsigned int>(::ndnboost::re_detail::distance(char_set.equivalents_begin(), char_set.equivalents_end()));
+   result->cclasses = char_set.classes();
+   result->cnclasses = char_set.negated_classes();
+   if(flags() & regbase::icase)
+   {
+      // adjust classes as needed:
+      if(((result->cclasses & m_lower_mask) == m_lower_mask) || ((result->cclasses & m_upper_mask) == m_upper_mask))
+         result->cclasses |= m_alpha_mask;
+      if(((result->cnclasses & m_lower_mask) == m_lower_mask) || ((result->cnclasses & m_upper_mask) == m_upper_mask))
+         result->cnclasses |= m_alpha_mask;
+   }
+
+   result->isnot = char_set.is_negated();
+   result->singleton = !char_set.has_digraphs();
+   //
+   // remember where the state is for later:
+   //
+   std::ptrdiff_t offset = getoffset(result);
+   //
+   // now extend with all the singles:
+   //
+   item_iterator first, last;
+   first = char_set.singles_begin();
+   last = char_set.singles_end();
+   while(first != last)
+   {
+      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (first->second ? 3 : 2)));
+      p[0] = m_traits.translate(first->first, m_icase);
+      if(first->second)
+      {
+         p[1] = m_traits.translate(first->second, m_icase);
+         p[2] = 0;
+      }
+      else
+         p[1] = 0;
+      ++first;
+   }
+   //
+   // now extend with all the ranges:
+   //
+   first = char_set.ranges_begin();
+   last = char_set.ranges_end();
+   while(first != last)
+   {
+      // first grab the endpoints of the range:
+      digraph<charT> c1 = *first;
+      c1.first = this->m_traits.translate(c1.first, this->m_icase);
+      c1.second = this->m_traits.translate(c1.second, this->m_icase);
+      ++first;
+      digraph<charT> c2 = *first;
+      c2.first = this->m_traits.translate(c2.first, this->m_icase);
+      c2.second = this->m_traits.translate(c2.second, this->m_icase);
+      ++first;
+      string_type s1, s2;
+      // different actions now depending upon whether collation is turned on:
+      if(flags() & regex_constants::collate)
+      {
+         // we need to transform our range into sort keys:
+#if NDNBOOST_WORKAROUND(__GNUC__, < 3)
+         string_type in(3, charT(0));
+         in[0] = c1.first;
+         in[1] = c1.second;
+         s1 = this->m_traits.transform(in.c_str(), (in[1] ? in.c_str()+2 : in.c_str()+1));
+         in[0] = c2.first;
+         in[1] = c2.second;
+         s2 = this->m_traits.transform(in.c_str(), (in[1] ? in.c_str()+2 : in.c_str()+1));
+#else
+         charT a1[3] = { c1.first, c1.second, charT(0), };
+         charT a2[3] = { c2.first, c2.second, charT(0), };
+         s1 = this->m_traits.transform(a1, (a1[1] ? a1+2 : a1+1));
+         s2 = this->m_traits.transform(a2, (a2[1] ? a2+2 : a2+1));
+#endif
+         if(s1.size() == 0)
+            s1 = string_type(1, charT(0));
+         if(s2.size() == 0)
+            s2 = string_type(1, charT(0));
+      }
+      else
+      {
+         if(c1.second)
+         {
+            s1.insert(s1.end(), c1.first);
+            s1.insert(s1.end(), c1.second);
+         }
+         else
+            s1 = string_type(1, c1.first);
+         if(c2.second)
+         {
+            s2.insert(s2.end(), c2.first);
+            s2.insert(s2.end(), c2.second);
+         }
+         else
+            s2.insert(s2.end(), c2.first);
+      }
+      if(s1 > s2)
+      {
+         // Oops error:
+         return 0;
+      }
+      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s1.size() + s2.size() + 2) ) );
+      re_detail::copy(s1.begin(), s1.end(), p);
+      p[s1.size()] = charT(0);
+      p += s1.size() + 1;
+      re_detail::copy(s2.begin(), s2.end(), p);
+      p[s2.size()] = charT(0);
+   }
+   //
+   // now process the equivalence classes:
+   //
+   first = char_set.equivalents_begin();
+   last = char_set.equivalents_end();
+   while(first != last)
+   {
+      string_type s;
+      if(first->second)
+      {
+#if NDNBOOST_WORKAROUND(__GNUC__, < 3)
+         string_type in(3, charT(0));
+         in[0] = first->first;
+         in[1] = first->second;
+         s = m_traits.transform_primary(in.c_str(), in.c_str()+2);
+#else
+         charT cs[3] = { first->first, first->second, charT(0), };
+         s = m_traits.transform_primary(cs, cs+2);
+#endif
+      }
+      else
+         s = m_traits.transform_primary(&first->first, &first->first+1);
+      if(s.empty())
+         return 0;  // invalid or unsupported equivalence class
+      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s.size()+1) ) );
+      re_detail::copy(s.begin(), s.end(), p);
+      p[s.size()] = charT(0);
+      ++first;
+   }
+   //
+   // finally reset the address of our last state:
+   //
+   m_last_state = result = static_cast<re_set_long<m_type>*>(getaddress(offset));
+   return result;
+}
+
+template<class T>
+inline bool char_less(T t1, T t2)
+{
+   return t1 < t2;
+}
+inline bool char_less(char t1, char t2)
+{
+   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);
+}
+inline bool char_less(signed char t1, signed char t2)
+{
+   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::append_set(
+   const basic_char_set<charT, traits>& char_set, mpl::true_*)
+{
+   typedef typename traits::string_type string_type;
+   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
+   
+   re_set* result = static_cast<re_set*>(append_state(syntax_element_set, sizeof(re_set)));
+   bool negate = char_set.is_negated();
+   std::memset(result->_map, 0, sizeof(result->_map));
+   //
+   // handle singles first:
+   //
+   item_iterator first, last;
+   first = char_set.singles_begin();
+   last = char_set.singles_end();
+   while(first != last)
+   {
+      for(unsigned int i = 0; i < (1 << CHAR_BIT); ++i)
+      {
+         if(this->m_traits.translate(static_cast<charT>(i), this->m_icase)
+            == this->m_traits.translate(first->first, this->m_icase))
+            result->_map[i] = true;
+      }
+      ++first;
+   }
+   //
+   // OK now handle ranges:
+   //
+   first = char_set.ranges_begin();
+   last = char_set.ranges_end();
+   while(first != last)
+   {
+      // first grab the endpoints of the range:
+      charT c1 = this->m_traits.translate(first->first, this->m_icase);
+      ++first;
+      charT c2 = this->m_traits.translate(first->first, this->m_icase);
+      ++first;
+      // different actions now depending upon whether collation is turned on:
+      if(flags() & regex_constants::collate)
+      {
+         // we need to transform our range into sort keys:
+         charT c3[2] = { c1, charT(0), };
+         string_type s1 = this->m_traits.transform(c3, c3+1);
+         c3[0] = c2;
+         string_type s2 = this->m_traits.transform(c3, c3+1);
+         if(s1 > s2)
+         {
+            // Oops error:
+            return 0;
+         }
+         NDNBOOST_ASSERT(c3[1] == charT(0));
+         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+         {
+            c3[0] = static_cast<charT>(i);
+            string_type s3 = this->m_traits.transform(c3, c3 +1);
+            if((s1 <= s3) && (s3 <= s2))
+               result->_map[i] = true;
+         }
+      }
+      else
+      {
+         if(char_less(c2, c1))
+         {
+            // Oops error:
+            return 0;
+         }
+         // everything in range matches:
+         std::memset(result->_map + static_cast<unsigned char>(c1), true, 1 + static_cast<unsigned char>(c2) - static_cast<unsigned char>(c1));
+      }
+   }
+   //
+   // and now the classes:
+   //
+   typedef typename traits::char_class_type m_type;
+   m_type m = char_set.classes();
+   if(flags() & regbase::icase)
+   {
+      // adjust m as needed:
+      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))
+         m |= m_alpha_mask;
+   }
+   if(m != 0)
+   {
+      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+      {
+         if(this->m_traits.isctype(static_cast<charT>(i), m))
+            result->_map[i] = true;
+      }
+   }
+   //
+   // and now the negated classes:
+   //
+   m = char_set.negated_classes();
+   if(flags() & regbase::icase)
+   {
+      // adjust m as needed:
+      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))
+         m |= m_alpha_mask;
+   }
+   if(m != 0)
+   {
+      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+      {
+         if(0 == this->m_traits.isctype(static_cast<charT>(i), m))
+            result->_map[i] = true;
+      }
+   }
+   //
+   // now process the equivalence classes:
+   //
+   first = char_set.equivalents_begin();
+   last = char_set.equivalents_end();
+   while(first != last)
+   {
+      string_type s;
+      NDNBOOST_ASSERT(static_cast<charT>(0) == first->second);
+      s = m_traits.transform_primary(&first->first, &first->first+1);
+      if(s.empty())
+         return 0;  // invalid or unsupported equivalence class
+      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+      {
+         charT c[2] = { (static_cast<charT>(i)), charT(0), };
+         string_type s2 = this->m_traits.transform_primary(c, c+1);
+         if(s == s2)
+            result->_map[i] = true;
+      }
+      ++first;
+   }
+   if(negate)
+   {
+      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+      {
+         result->_map[i] = !(result->_map[i]);
+      }
+   }
+   return result;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::finalize(const charT* p1, const charT* p2)
+{
+   if(this->m_pdata->m_status)
+      return;
+   // we've added all the states we need, now finish things off.
+   // start by adding a terminating state:
+   append_state(syntax_element_match);
+   // extend storage to store original expression:
+   std::ptrdiff_t len = p2 - p1;
+   m_pdata->m_expression_len = len;
+   charT* ps = static_cast<charT*>(m_pdata->m_data.extend(sizeof(charT) * (1 + (p2 - p1))));
+   m_pdata->m_expression = ps;
+   re_detail::copy(p1, p2, ps);
+   ps[p2 - p1] = 0;
+   // fill in our other data...
+   // successful parsing implies a zero status:
+   m_pdata->m_status = 0;
+   // get the first state of the machine:
+   m_pdata->m_first_state = static_cast<re_syntax_base*>(m_pdata->m_data.data());
+   // fixup pointers in the machine:
+   fixup_pointers(m_pdata->m_first_state);
+   if(m_has_recursions)
+   {
+      m_pdata->m_has_recursions = true;
+      fixup_recursions(m_pdata->m_first_state);
+      if(this->m_pdata->m_status)
+         return;
+   }
+   else
+      m_pdata->m_has_recursions = false;
+   // create nested startmaps:
+   create_startmaps(m_pdata->m_first_state);
+   // create main startmap:
+   std::memset(m_pdata->m_startmap, 0, sizeof(m_pdata->m_startmap));
+   m_pdata->m_can_be_null = 0;
+
+   m_bad_repeats = 0;
+   if(m_has_recursions)
+      m_recursion_checks.assign(1 + m_pdata->m_mark_count, false);
+   create_startmap(m_pdata->m_first_state, m_pdata->m_startmap, &(m_pdata->m_can_be_null), mask_all);
+   // get the restart type:
+   m_pdata->m_restart_type = get_restart_type(m_pdata->m_first_state);
+   // optimise a leading repeat if there is one:
+   probe_leading_repeat(m_pdata->m_first_state);
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::fixup_pointers(re_syntax_base* state)
+{
+   while(state)
+   {
+      switch(state->type)
+      {
+      case syntax_element_recurse:
+         m_has_recursions = true;
+         if(state->next.i)
+            state->next.p = getaddress(state->next.i, state);
+         else
+            state->next.p = 0;
+         break;
+      case syntax_element_rep:
+      case syntax_element_dot_rep:
+      case syntax_element_char_rep:
+      case syntax_element_short_set_rep:
+      case syntax_element_long_set_rep:
+         // set the state_id of this repeat:
+         static_cast<re_repeat*>(state)->state_id = m_repeater_id++;
+         NDNBOOST_FALLTHROUGH;
+      case syntax_element_alt:
+         std::memset(static_cast<re_alt*>(state)->_map, 0, sizeof(static_cast<re_alt*>(state)->_map));
+         static_cast<re_alt*>(state)->can_be_null = 0;
+         NDNBOOST_FALLTHROUGH;
+      case syntax_element_jump:
+         static_cast<re_jump*>(state)->alt.p = getaddress(static_cast<re_jump*>(state)->alt.i, state);
+         NDNBOOST_FALLTHROUGH;
+      default:
+         if(state->next.i)
+            state->next.p = getaddress(state->next.i, state);
+         else
+            state->next.p = 0;
+      }
+      state = state->next.p;
+   }
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state)
+{
+   re_syntax_base* base = state;
+   while(state)
+   {
+      switch(state->type)
+      {
+      case syntax_element_assert_backref:
+         {
+            // just check that the index is valid:
+            int idx = static_cast<const re_brace*>(state)->index;
+            if(idx < 0)
+            {
+               idx = -idx-1;
+               if(idx >= 10000)
+               {
+                  idx = m_pdata->get_id(idx);
+                  if(idx <= 0)
+                  {
+                     // check of sub-expression that doesn't exist:
+                     if(0 == this->m_pdata->m_status) // update the error code if not already set
+                        this->m_pdata->m_status = ndnboost::regex_constants::error_bad_pattern;
+                     //
+                     // clear the expression, we should be empty:
+                     //
+                     this->m_pdata->m_expression = 0;
+                     this->m_pdata->m_expression_len = 0;
+                     //
+                     // and throw if required:
+                     //
+                     if(0 == (this->flags() & regex_constants::no_except))
+                     {
+                        std::string message = "Encountered a forward reference to a marked sub-expression that does not exist.";
+                        ndnboost::regex_error e(message, ndnboost::regex_constants::error_bad_pattern, 0);
+                        e.raise();
+                     }
+                  }
+               }
+            }
+         }
+         break;
+      case syntax_element_recurse:
+         {
+            bool ok = false;
+            re_syntax_base* p = base;
+            std::ptrdiff_t idx = static_cast<re_jump*>(state)->alt.i;
+            if(idx > 10000)
+            {
+               //
+               // There may be more than one capture group with this hash, just do what Perl
+               // does and recurse to the leftmost:
+               //
+               idx = m_pdata->get_id(static_cast<int>(idx));
+            }
+            while(p)
+            {
+               if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == idx))
+               {
+                  //
+                  // We've found the target of the recursion, set the jump target:
+                  //
+                  static_cast<re_jump*>(state)->alt.p = p;
+                  ok = true;
+                  // 
+                  // Now scan the target for nested repeats:
+                  //
+                  p = p->next.p;
+                  int next_rep_id = 0;
+                  while(p)
+                  {
+                     switch(p->type)
+                     {
+                     case syntax_element_rep:
+                     case syntax_element_dot_rep:
+                     case syntax_element_char_rep:
+                     case syntax_element_short_set_rep:
+                     case syntax_element_long_set_rep:
+                        next_rep_id = static_cast<re_repeat*>(p)->state_id;
+                        break;
+                     case syntax_element_endmark:
+                        if(static_cast<const re_brace*>(p)->index == idx)
+                           next_rep_id = -1;
+                        break;
+                     default: 
+                        break;
+                     }
+                     if(next_rep_id)
+                        break;
+                     p = p->next.p;
+                  }
+                  if(next_rep_id > 0)
+                  {
+                     static_cast<re_recurse*>(state)->state_id = next_rep_id - 1;
+                  }
+
+                  break;
+               }
+               p = p->next.p;
+            }
+            if(!ok)
+            {
+               // recursion to sub-expression that doesn't exist:
+               if(0 == this->m_pdata->m_status) // update the error code if not already set
+                  this->m_pdata->m_status = ndnboost::regex_constants::error_bad_pattern;
+               //
+               // clear the expression, we should be empty:
+               //
+               this->m_pdata->m_expression = 0;
+               this->m_pdata->m_expression_len = 0;
+               //
+               // and throw if required:
+               //
+               if(0 == (this->flags() & regex_constants::no_except))
+               {
+                  std::string message = "Encountered a forward reference to a recursive sub-expression that does not exist.";
+                  ndnboost::regex_error e(message, ndnboost::regex_constants::error_bad_pattern, 0);
+                  e.raise();
+               }
+            }
+         }
+         break;
+      default:
+         break;
+      }
+      state = state->next.p;
+   }
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
+{
+   // non-recursive implementation:
+   // create the last map in the machine first, so that earlier maps
+   // can make use of the result...
+   //
+   // This was originally a recursive implementation, but that caused stack
+   // overflows with complex expressions on small stacks (think COM+).
+
+   // start by saving the case setting:
+   bool l_icase = m_icase;
+   std::vector<std::pair<bool, re_syntax_base*> > v;
+
+   while(state)
+   {
+      switch(state->type)
+      {
+      case syntax_element_toggle_case:
+         // we need to track case changes here:
+         m_icase = static_cast<re_case*>(state)->icase;
+         state = state->next.p;
+         continue;
+      case syntax_element_alt:
+      case syntax_element_rep:
+      case syntax_element_dot_rep:
+      case syntax_element_char_rep:
+      case syntax_element_short_set_rep:
+      case syntax_element_long_set_rep:
+         // just push the state onto our stack for now:
+         v.push_back(std::pair<bool, re_syntax_base*>(m_icase, state));
+         state = state->next.p;
+         break;
+      case syntax_element_backstep:
+         // we need to calculate how big the backstep is:
+         static_cast<re_brace*>(state)->index
+            = this->calculate_backstep(state->next.p);
+         if(static_cast<re_brace*>(state)->index < 0)
+         {
+            // Oops error:
+            if(0 == this->m_pdata->m_status) // update the error code if not already set
+               this->m_pdata->m_status = ndnboost::regex_constants::error_bad_pattern;
+            //
+            // clear the expression, we should be empty:
+            //
+            this->m_pdata->m_expression = 0;
+            this->m_pdata->m_expression_len = 0;
+            //
+            // and throw if required:
+            //
+            if(0 == (this->flags() & regex_constants::no_except))
+            {
+               std::string message = "Invalid lookbehind assertion encountered in the regular expression.";
+               ndnboost::regex_error e(message, ndnboost::regex_constants::error_bad_pattern, 0);
+               e.raise();
+            }
+         }
+         NDNBOOST_FALLTHROUGH;
+      default:
+         state = state->next.p;
+      }
+   }
+
+   // now work through our list, building all the maps as we go:
+   while(v.size())
+   {
+      // Initialize m_recursion_checks if we need it:
+      if(m_has_recursions)
+         m_recursion_checks.assign(1 + m_pdata->m_mark_count, false);
+
+      const std::pair<bool, re_syntax_base*>& p = v.back();
+      m_icase = p.first;
+      state = p.second;
+      v.pop_back();
+
+      // Build maps:
+      m_bad_repeats = 0;
+      create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take);
+      m_bad_repeats = 0;
+
+      if(m_has_recursions)
+         m_recursion_checks.assign(1 + m_pdata->m_mark_count, false);
+      create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip);
+      // adjust the type of the state to allow for faster matching:
+      state->type = this->get_repeat_type(state);
+   }
+   // restore case sensitivity:
+   m_icase = l_icase;
+}
+
+template <class charT, class traits>
+int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
+{
+   typedef typename traits::char_class_type m_type;
+   int result = 0;
+   while(state)
+   {
+      switch(state->type)
+      {
+      case syntax_element_startmark:
+         if((static_cast<re_brace*>(state)->index == -1)
+            || (static_cast<re_brace*>(state)->index == -2))
+         {
+            state = static_cast<re_jump*>(state->next.p)->alt.p->next.p;
+            continue;
+         }
+         else if(static_cast<re_brace*>(state)->index == -3)
+         {
+            state = state->next.p->next.p;
+            continue;
+         }
+         break;
+      case syntax_element_endmark:
+         if((static_cast<re_brace*>(state)->index == -1)
+            || (static_cast<re_brace*>(state)->index == -2))
+            return result;
+         break;
+      case syntax_element_literal:
+         result += static_cast<re_literal*>(state)->length;
+         break;
+      case syntax_element_wild:
+      case syntax_element_set:
+         result += 1;
+         break;
+      case syntax_element_dot_rep:
+      case syntax_element_char_rep:
+      case syntax_element_short_set_rep:
+      case syntax_element_backref:
+      case syntax_element_rep:
+      case syntax_element_combining:
+      case syntax_element_long_set_rep:
+      case syntax_element_backstep:
+         {
+            re_repeat* rep = static_cast<re_repeat *>(state);
+            // adjust the type of the state to allow for faster matching:
+            state->type = this->get_repeat_type(state);
+            if((state->type == syntax_element_dot_rep) 
+               || (state->type == syntax_element_char_rep)
+               || (state->type == syntax_element_short_set_rep))
+            {
+               if(rep->max != rep->min)
+                  return -1;
+               result += static_cast<int>(rep->min);
+               state = rep->alt.p;
+               continue;
+            }
+            else if(state->type == syntax_element_long_set_rep)
+            {
+               NDNBOOST_ASSERT(rep->next.p->type == syntax_element_long_set);
+               if(static_cast<re_set_long<m_type>*>(rep->next.p)->singleton == 0)
+                  return -1;
+               if(rep->max != rep->min)
+                  return -1;
+               result += static_cast<int>(rep->min);
+               state = rep->alt.p;
+               continue;
+            }
+         }
+         return -1;
+      case syntax_element_long_set:
+         if(static_cast<re_set_long<m_type>*>(state)->singleton == 0)
+            return -1;
+         result += 1;
+         break;
+      case syntax_element_jump:
+         state = static_cast<re_jump*>(state)->alt.p;
+         continue;
+      case syntax_element_alt:
+         {
+            int r1 = calculate_backstep(state->next.p);
+            int r2 = calculate_backstep(static_cast<re_alt*>(state)->alt.p);
+            if((r1 < 0) || (r1 != r2))
+               return -1;
+            return result + r1;
+         }
+      default:
+         break;
+      }
+      state = state->next.p;
+   }
+   return -1;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask)
+{
+   int not_last_jump = 1;
+   re_syntax_base* recursion_start = 0;
+   int recursion_sub = 0;
+   re_syntax_base* recursion_restart = 0;
+
+   // track case sensitivity:
+   bool l_icase = m_icase;
+
+   while(state)
+   {
+      switch(state->type)
+      {
+      case syntax_element_toggle_case:
+         l_icase = static_cast<re_case*>(state)->icase;
+         state = state->next.p;
+         break;
+      case syntax_element_literal:
+      {
+         // don't set anything in *pnull, set each element in l_map
+         // that could match the first character in the literal:
+         if(l_map)
+         {
+            l_map[0] |= mask_init;
+            charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));
+            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+            {
+               if(m_traits.translate(static_cast<charT>(i), l_icase) == first_char)
+                  l_map[i] |= mask;
+            }
+         }
+         return;
+      }
+      case syntax_element_end_line:
+      {
+         // next character must be a line separator (if there is one):
+         if(l_map)
+         {
+            l_map[0] |= mask_init;
+            l_map[static_cast<unsigned>('\n')] |= mask;
+            l_map[static_cast<unsigned>('\r')] |= mask;
+            l_map[static_cast<unsigned>('\f')] |= mask;
+            l_map[0x85] |= mask;
+         }
+         // now figure out if we can match a NULL string at this point:
+         if(pnull)
+            create_startmap(state->next.p, 0, pnull, mask);
+         return;
+      }
+      case syntax_element_recurse:
+         {
+            if(state->type == syntax_element_startmark)
+               recursion_sub = static_cast<re_brace*>(state)->index;
+            else
+               recursion_sub = 0;
+            if(m_recursion_checks[recursion_sub])
+            {
+               // Infinite recursion!!
+               if(0 == this->m_pdata->m_status) // update the error code if not already set
+                  this->m_pdata->m_status = ndnboost::regex_constants::error_bad_pattern;
+               //
+               // clear the expression, we should be empty:
+               //
+               this->m_pdata->m_expression = 0;
+               this->m_pdata->m_expression_len = 0;
+               //
+               // and throw if required:
+               //
+               if(0 == (this->flags() & regex_constants::no_except))
+               {
+                  std::string message = "Encountered an infinite recursion.";
+                  ndnboost::regex_error e(message, ndnboost::regex_constants::error_bad_pattern, 0);
+                  e.raise();
+               }
+            }
+            else if(recursion_start == 0)
+            {
+               recursion_start = state;
+               recursion_restart = state->next.p;
+               state = static_cast<re_jump*>(state)->alt.p;
+               m_recursion_checks[recursion_sub] = true;
+               break;
+            }
+            m_recursion_checks[recursion_sub] = true;
+            // can't handle nested recursion here...
+            NDNBOOST_FALLTHROUGH;
+         }
+      case syntax_element_backref:
+         // can be null, and any character can match:
+         if(pnull)
+            *pnull |= mask;
+         NDNBOOST_FALLTHROUGH;
+      case syntax_element_wild:
+      {
+         // can't be null, any character can match:
+         set_all_masks(l_map, mask);
+         return;
+      }
+      case syntax_element_match:
+      {
+         // must be null, any character can match:
+         set_all_masks(l_map, mask);
+         if(pnull)
+            *pnull |= mask;
+         return;
+      }
+      case syntax_element_word_start:
+      {
+         // recurse, then AND with all the word characters:
+         create_startmap(state->next.p, l_map, pnull, mask);
+         if(l_map)
+         {
+            l_map[0] |= mask_init;
+            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+            {
+               if(!m_traits.isctype(static_cast<charT>(i), m_word_mask))
+                  l_map[i] &= static_cast<unsigned char>(~mask);
+            }
+         }
+         return;
+      }
+      case syntax_element_word_end:
+      {
+         // recurse, then AND with all the word characters:
+         create_startmap(state->next.p, l_map, pnull, mask);
+         if(l_map)
+         {
+            l_map[0] |= mask_init;
+            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+            {
+               if(m_traits.isctype(static_cast<charT>(i), m_word_mask))
+                  l_map[i] &= static_cast<unsigned char>(~mask);
+            }
+         }
+         return;
+      }
+      case syntax_element_buffer_end:
+      {
+         // we *must be null* :
+         if(pnull)
+            *pnull |= mask;
+         return;
+      }
+      case syntax_element_long_set:
+         if(l_map)
+         {
+            typedef typename traits::char_class_type m_type;
+            if(static_cast<re_set_long<m_type>*>(state)->singleton)
+            {
+               l_map[0] |= mask_init;
+               for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+               {
+                  charT c = static_cast<charT>(i);
+                  if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<m_type>*>(state), *m_pdata, l_icase))
+                     l_map[i] |= mask;
+               }
+            }
+            else
+               set_all_masks(l_map, mask);
+         }
+         return;
+      case syntax_element_set:
+         if(l_map)
+         {
+            l_map[0] |= mask_init;
+            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+            {
+               if(static_cast<re_set*>(state)->_map[
+                  static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), l_icase))])
+                  l_map[i] |= mask;
+            }
+         }
+         return;
+      case syntax_element_jump:
+         // take the jump:
+         state = static_cast<re_alt*>(state)->alt.p;
+         not_last_jump = -1;
+         break;
+      case syntax_element_alt:
+      case syntax_element_rep:
+      case syntax_element_dot_rep:
+      case syntax_element_char_rep:
+      case syntax_element_short_set_rep:
+      case syntax_element_long_set_rep:
+         {
+            re_alt* rep = static_cast<re_alt*>(state);
+            if(rep->_map[0] & mask_init)
+            {
+               if(l_map)
+               {
+                  // copy previous results:
+                  l_map[0] |= mask_init;
+                  for(unsigned int i = 0; i <= UCHAR_MAX; ++i)
+                  {
+                     if(rep->_map[i] & mask_any)
+                        l_map[i] |= mask;
+                  }
+               }
+               if(pnull)
+               {
+                  if(rep->can_be_null & mask_any)
+                     *pnull |= mask;
+               }
+            }
+            else
+            {
+               // we haven't created a startmap for this alternative yet
+               // so take the union of the two options:
+               if(is_bad_repeat(state))
+               {
+                  set_all_masks(l_map, mask);
+                  if(pnull)
+                     *pnull |= mask;
+                  return;
+               }
+               set_bad_repeat(state);
+               create_startmap(state->next.p, l_map, pnull, mask);
+               if((state->type == syntax_element_alt)
+                  || (static_cast<re_repeat*>(state)->min == 0)
+                  || (not_last_jump == 0))
+                  create_startmap(rep->alt.p, l_map, pnull, mask);
+            }
+         }
+         return;
+      case syntax_element_soft_buffer_end:
+         // match newline or null:
+         if(l_map)
+         {
+            l_map[0] |= mask_init;
+            l_map[static_cast<unsigned>('\n')] |= mask;
+            l_map[static_cast<unsigned>('\r')] |= mask;
+         }
+         if(pnull)
+            *pnull |= mask;
+         return;
+      case syntax_element_endmark:
+         // need to handle independent subs as a special case:
+         if(static_cast<re_brace*>(state)->index < 0)
+         {
+            // can be null, any character can match:
+            set_all_masks(l_map, mask);
+            if(pnull)
+               *pnull |= mask;
+            return;
+         }
+         else if(recursion_start && (recursion_sub != 0) && (recursion_sub == static_cast<re_brace*>(state)->index))
+         {
+            // recursion termination:
+            recursion_start = 0;
+            state = recursion_restart;
+            break;
+         }
+
+         //
+         // Normally we just go to the next state... but if this sub-expression is
+         // the target of a recursion, then we might be ending a recursion, in which
+         // case we should check whatever follows that recursion, as well as whatever
+         // follows this state:
+         //
+         if(m_pdata->m_has_recursions && static_cast<re_brace*>(state)->index)
+         {
+            bool ok = false;
+            re_syntax_base* p = m_pdata->m_first_state;
+            while(p)
+            {
+               if(p->type == syntax_element_recurse)
+               {
+                  re_brace* p2 = static_cast<re_brace*>(static_cast<re_jump*>(p)->alt.p);
+                  if((p2->type == syntax_element_startmark) && (p2->index == static_cast<re_brace*>(state)->index))
+                  {
+                     ok = true;
+                     break;
+                  }
+               }
+               p = p->next.p;
+            }
+            if(ok)
+            {
+               create_startmap(p->next.p, l_map, pnull, mask);
+            }
+         }
+         state = state->next.p;
+         break;
+
+      case syntax_element_startmark:
+         // need to handle independent subs as a special case:
+         if(static_cast<re_brace*>(state)->index == -3)
+         {
+            state = state->next.p->next.p;
+            break;
+         }
+         NDNBOOST_FALLTHROUGH;
+      default:
+         state = state->next.p;
+      }
+      ++not_last_jump;
+   }
+}
+
+template <class charT, class traits>
+unsigned basic_regex_creator<charT, traits>::get_restart_type(re_syntax_base* state)
+{
+   //
+   // find out how the machine starts, so we can optimise the search:
+   //
+   while(state)
+   {
+      switch(state->type)
+      {
+      case syntax_element_startmark:
+      case syntax_element_endmark:
+         state = state->next.p;
+         continue;
+      case syntax_element_start_line:
+         return regbase::restart_line;
+      case syntax_element_word_start:
+         return regbase::restart_word;
+      case syntax_element_buffer_start:
+         return regbase::restart_buf;
+      case syntax_element_restart_continue:
+         return regbase::restart_continue;
+      default:
+         state = 0;
+         continue;
+      }
+   }
+   return regbase::restart_any;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::set_all_masks(unsigned char* bits, unsigned char mask)
+{
+   //
+   // set mask in all of bits elements, 
+   // if bits[0] has mask_init not set then we can 
+   // optimise this to a call to memset:
+   //
+   if(bits)
+   {
+      if(bits[0] == 0)
+         (std::memset)(bits, mask, 1u << CHAR_BIT);
+      else
+      {
+         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+            bits[i] |= mask;
+      }
+      bits[0] |= mask_init;
+   }
+}
+
+template <class charT, class traits>
+bool basic_regex_creator<charT, traits>::is_bad_repeat(re_syntax_base* pt)
+{
+   switch(pt->type)
+   {
+   case syntax_element_rep:
+   case syntax_element_dot_rep:
+   case syntax_element_char_rep:
+   case syntax_element_short_set_rep:
+   case syntax_element_long_set_rep:
+      {
+         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;
+         if(state_id > sizeof(m_bad_repeats) * CHAR_BIT)
+            return true;  // run out of bits, assume we can't traverse this one.
+         static const ndnboost::uintmax_t one = 1uL;
+         return m_bad_repeats & (one << state_id);
+      }
+   default:
+      return false;
+   }
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::set_bad_repeat(re_syntax_base* pt)
+{
+   switch(pt->type)
+   {
+   case syntax_element_rep:
+   case syntax_element_dot_rep:
+   case syntax_element_char_rep:
+   case syntax_element_short_set_rep:
+   case syntax_element_long_set_rep:
+      {
+         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;
+         static const ndnboost::uintmax_t one = 1uL;
+         if(state_id <= sizeof(m_bad_repeats) * CHAR_BIT)
+            m_bad_repeats |= (one << state_id);
+      }
+      break;
+   default:
+      break;
+   }
+}
+
+template <class charT, class traits>
+syntax_element_type basic_regex_creator<charT, traits>::get_repeat_type(re_syntax_base* state)
+{
+   typedef typename traits::char_class_type m_type;
+   if(state->type == syntax_element_rep)
+   {
+      // check to see if we are repeating a single state:
+      if(state->next.p->next.p->next.p == static_cast<re_alt*>(state)->alt.p)
+      {
+         switch(state->next.p->type)
+         {
+         case re_detail::syntax_element_wild:
+            return re_detail::syntax_element_dot_rep;
+         case re_detail::syntax_element_literal:
+            return re_detail::syntax_element_char_rep;
+         case re_detail::syntax_element_set:
+            return re_detail::syntax_element_short_set_rep;
+         case re_detail::syntax_element_long_set:
+            if(static_cast<re_detail::re_set_long<m_type>*>(state->next.p)->singleton)
+               return re_detail::syntax_element_long_set_rep;
+            break;
+         default:
+            break;
+         }
+      }
+   }
+   return state->type;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::probe_leading_repeat(re_syntax_base* state)
+{
+   // enumerate our states, and see if we have a leading repeat 
+   // for which failed search restarts can be optimised;
+   do
+   {
+      switch(state->type)
+      {
+      case syntax_element_startmark:
+         if(static_cast<re_brace*>(state)->index >= 0)
+         {
+            state = state->next.p;
+            continue;
+         }
+         if((static_cast<re_brace*>(state)->index == -1)
+            || (static_cast<re_brace*>(state)->index == -2))
+         {
+            // skip past the zero width assertion:
+            state = static_cast<const re_jump*>(state->next.p)->alt.p->next.p;
+            continue;
+         }
+         if(static_cast<re_brace*>(state)->index == -3)
+         {
+            // Have to skip the leading jump state:
+            state = state->next.p->next.p;
+            continue;
+         }
+         return;
+      case syntax_element_endmark:
+      case syntax_element_start_line:
+      case syntax_element_end_line:
+      case syntax_element_word_boundary:
+      case syntax_element_within_word:
+      case syntax_element_word_start:
+      case syntax_element_word_end:
+      case syntax_element_buffer_start:
+      case syntax_element_buffer_end:
+      case syntax_element_restart_continue:
+         state = state->next.p;
+         break;
+      case syntax_element_dot_rep:
+      case syntax_element_char_rep:
+      case syntax_element_short_set_rep:
+      case syntax_element_long_set_rep:
+         if(this->m_has_backrefs == 0)
+            static_cast<re_repeat*>(state)->leading = true;
+         NDNBOOST_FALLTHROUGH;
+      default:
+         return;
+      }
+   }while(state);
+}
+
+
+} // namespace re_detail
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/basic_regex_parser.hpp b/include/ndnboost/regex/v4/basic_regex_parser.hpp
new file mode 100644
index 0000000..2f72e44
--- /dev/null
+++ b/include/ndnboost/regex/v4/basic_regex_parser.hpp
@@ -0,0 +1,2874 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         basic_regex_parser.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares template class basic_regex_parser.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
+#define NDNBOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244 4800)
+#endif
+
+template <class charT, class traits>
+class basic_regex_parser : public basic_regex_creator<charT, traits>
+{
+public:
+   basic_regex_parser(regex_data<charT, traits>* data);
+   void parse(const charT* p1, const charT* p2, unsigned flags);
+   void fail(regex_constants::error_type error_code, std::ptrdiff_t position);
+   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos);
+   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, const std::string& message)
+   {
+      fail(error_code, position, message, position);
+   }
+
+   bool parse_all();
+   bool parse_basic();
+   bool parse_extended();
+   bool parse_literal();
+   bool parse_open_paren();
+   bool parse_basic_escape();
+   bool parse_extended_escape();
+   bool parse_match_any();
+   bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());
+   bool parse_repeat_range(bool isbasic);
+   bool parse_alt();
+   bool parse_set();
+   bool parse_backref();
+   void parse_set_literal(basic_char_set<charT, traits>& char_set);
+   bool parse_inner_set(basic_char_set<charT, traits>& char_set);
+   bool parse_QE();
+   bool parse_perl_extension();
+   bool add_emacs_code(bool negate);
+   bool unwind_alts(std::ptrdiff_t last_paren_start);
+   digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);
+   charT unescape_character();
+   regex_constants::syntax_option_type parse_options();
+
+private:
+   typedef bool (basic_regex_parser::*parser_proc_type)();
+   typedef typename traits::string_type string_type;
+   typedef typename traits::char_class_type char_class_type;
+   parser_proc_type           m_parser_proc;    // the main parser to use
+   const charT*               m_base;           // the start of the string being parsed
+   const charT*               m_end;            // the end of the string being parsed
+   const charT*               m_position;       // our current parser position
+   unsigned                   m_mark_count;     // how many sub-expressions we have
+   int                        m_mark_reset;     // used to indicate that we're inside a (?|...) block.
+   unsigned                   m_max_mark;       // largest mark count seen inside a (?|...) block.
+   std::ptrdiff_t             m_paren_start;    // where the last seen ')' began (where repeats are inserted).
+   std::ptrdiff_t             m_alt_insert_point; // where to insert the next alternative
+   bool                       m_has_case_change; // true if somewhere in the current block the case has changed
+#if defined(NDNBOOST_MSVC) && defined(_M_IX86)
+   // This is an ugly warning suppression workaround (for warnings *inside* std::vector
+   // that can not otherwise be suppressed)...
+   NDNBOOST_STATIC_ASSERT(sizeof(long) >= sizeof(void*));
+   std::vector<long>           m_alt_jumps;      // list of alternative in the current scope.
+#else
+   std::vector<std::ptrdiff_t> m_alt_jumps;      // list of alternative in the current scope.
+#endif
+
+   basic_regex_parser& operator=(const basic_regex_parser&);
+   basic_regex_parser(const basic_regex_parser&);
+};
+
+template <class charT, class traits>
+basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
+   : basic_regex_creator<charT, traits>(data), m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false)
+{
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned l_flags)
+{
+   // pass l_flags on to base class:
+   this->init(l_flags);
+   // set up pointers:
+   m_position = m_base = p1;
+   m_end = p2;
+   // empty strings are errors:
+   if((p1 == p2) && 
+      (
+         ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)
+         || (l_flags & regbase::no_empty_expressions)
+      )
+     )
+   {
+      fail(regex_constants::error_empty, 0);
+      return;
+   }
+   // select which parser to use:
+   switch(l_flags & regbase::main_option_type)
+   {
+   case regbase::perl_syntax_group:
+      {
+         m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;
+         //
+         // Add a leading paren with index zero to give recursions a target:
+         //
+         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+         br->index = 0;
+         br->icase = this->flags() & regbase::icase;
+         break;
+      }
+   case regbase::basic_syntax_group:
+      m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;
+      break;
+   case regbase::literal:
+      m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;
+      break;
+   default:
+      // Ooops, someone has managed to set more than one of the main option flags, 
+      // so this must be an error:
+      fail(regex_constants::error_unknown, 0, "An invalid combination of regular expression syntax flags was used.");
+      return;
+   }
+
+   // parse all our characters:
+   bool result = parse_all();
+   //
+   // Unwind our alternatives:
+   //
+   unwind_alts(-1);
+   // reset l_flags as a global scope (?imsx) may have altered them:
+   this->flags(l_flags);
+   // if we haven't gobbled up all the characters then we must
+   // have had an unexpected ')' :
+   if(!result)
+   {
+      fail(regex_constants::error_paren, ::ndnboost::re_detail::distance(m_base, m_position), "Found a closing ) with no corresponding openening parenthesis.");
+      return;
+   }
+   // if an error has been set then give up now:
+   if(this->m_pdata->m_status)
+      return;
+   // fill in our sub-expression count:
+   this->m_pdata->m_mark_count = 1 + m_mark_count;
+   this->finalize(p1, p2);
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)
+{
+   // get the error message:
+   std::string message = this->m_pdata->m_ptraits->error_string(error_code);
+   fail(error_code, position, message);
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos)
+{
+   if(0 == this->m_pdata->m_status) // update the error code if not already set
+      this->m_pdata->m_status = error_code;
+   m_position = m_end; // don't bother parsing anything else
+
+#ifndef NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+   //
+   // Augment error message with the regular expression text:
+   //
+   if(start_pos == position)
+      start_pos = (std::max)(static_cast<std::ptrdiff_t>(0), position - static_cast<std::ptrdiff_t>(10));
+   std::ptrdiff_t end_pos = (std::min)(position + static_cast<std::ptrdiff_t>(10), static_cast<std::ptrdiff_t>(m_end - m_base));
+   if(error_code != regex_constants::error_empty)
+   {
+      if((start_pos != 0) || (end_pos != (m_end - m_base)))
+         message += "  The error occurred while parsing the regular expression fragment: '";
+      else
+         message += "  The error occurred while parsing the regular expression: '";
+      if(start_pos != end_pos)
+      {
+         message += std::string(m_base + start_pos, m_base + position);
+         message += ">>>HERE>>>";
+         message += std::string(m_base + position, m_base + end_pos);
+      }
+      message += "'.";
+   }
+#endif
+
+#ifndef NDNBOOST_NO_EXCEPTIONS
+   if(0 == (this->flags() & regex_constants::no_except))
+   {
+      ndnboost::regex_error e(message, error_code, position);
+      e.raise();
+   }
+#else
+   (void)position; // suppress warnings.
+#endif
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_all()
+{
+   bool result = true;
+   while(result && (m_position != m_end))
+   {
+      result = (this->*m_parser_proc)();
+   }
+   return result;
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4702)
+#endif
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_basic()
+{
+   switch(this->m_traits.syntax_type(*m_position))
+   {
+   case regex_constants::syntax_escape:
+      return parse_basic_escape();
+   case regex_constants::syntax_dot:
+      return parse_match_any();
+   case regex_constants::syntax_caret:
+      ++m_position;
+      this->append_state(syntax_element_start_line);
+      break;
+   case regex_constants::syntax_dollar:
+      ++m_position;
+      this->append_state(syntax_element_end_line);
+      break;
+   case regex_constants::syntax_star:
+      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))
+         return parse_literal();
+      else
+      {
+         ++m_position;
+         return parse_repeat();
+      }
+   case regex_constants::syntax_plus:
+      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
+         return parse_literal();
+      else
+      {
+         ++m_position;
+         return parse_repeat(1);
+      }
+   case regex_constants::syntax_question:
+      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
+         return parse_literal();
+      else
+      {
+         ++m_position;
+         return parse_repeat(0, 1);
+      }
+   case regex_constants::syntax_open_set:
+      return parse_set();
+   case regex_constants::syntax_newline:
+      if(this->flags() & regbase::newline_alt)
+         return parse_alt();
+      else
+         return parse_literal();
+   default:
+      return parse_literal();
+   }
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_extended()
+{
+   bool result = true;
+   switch(this->m_traits.syntax_type(*m_position))
+   {
+   case regex_constants::syntax_open_mark:
+      return parse_open_paren();
+   case regex_constants::syntax_close_mark:
+      return false;
+   case regex_constants::syntax_escape:
+      return parse_extended_escape();
+   case regex_constants::syntax_dot:
+      return parse_match_any();
+   case regex_constants::syntax_caret:
+      ++m_position;
+      this->append_state(
+         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));
+      break;
+   case regex_constants::syntax_dollar:
+      ++m_position;
+      this->append_state(
+         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));
+      break;
+   case regex_constants::syntax_star:
+      if(m_position == this->m_base)
+      {
+         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"*\" cannot start a regular expression.");
+         return false;
+      }
+      ++m_position;
+      return parse_repeat();
+   case regex_constants::syntax_question:
+      if(m_position == this->m_base)
+      {
+         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"?\" cannot start a regular expression.");
+         return false;
+      }
+      ++m_position;
+      return parse_repeat(0,1);
+   case regex_constants::syntax_plus:
+      if(m_position == this->m_base)
+      {
+         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"+\" cannot start a regular expression.");
+         return false;
+      }
+      ++m_position;
+      return parse_repeat(1);
+   case regex_constants::syntax_open_brace:
+      ++m_position;
+      return parse_repeat_range(false);
+   case regex_constants::syntax_close_brace:
+      fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
+      return false;
+   case regex_constants::syntax_or:
+      return parse_alt();
+   case regex_constants::syntax_open_set:
+      return parse_set();
+   case regex_constants::syntax_newline:
+      if(this->flags() & regbase::newline_alt)
+         return parse_alt();
+      else
+         return parse_literal();
+   case regex_constants::syntax_hash:
+      //
+      // If we have a mod_x flag set, then skip until
+      // we get to a newline character:
+      //
+      if((this->flags() 
+         & (regbase::no_perl_ex|regbase::mod_x))
+         == regbase::mod_x)
+      {
+         while((m_position != m_end) && !is_separator(*m_position++)){}
+         return true;
+      }
+      NDNBOOST_FALLTHROUGH;
+   default:
+      result = parse_literal();
+      break;
+   }
+   return result;
+}
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_literal()
+{
+   // append this as a literal provided it's not a space character
+   // or the perl option regbase::mod_x is not set:
+   if(
+      ((this->flags() 
+         & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex)) 
+            != regbase::mod_x)
+      || !this->m_traits.isctype(*m_position, this->m_mask_space))
+         this->append_literal(*m_position);
+   ++m_position;
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_open_paren()
+{
+   //
+   // skip the '(' and error check:
+   //
+   if(++m_position == m_end)
+   {
+      fail(regex_constants::error_paren, m_position - m_base);
+      return false;
+   }
+   //
+   // begin by checking for a perl-style (?...) extension:
+   //
+   if(
+         ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
+         || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
+     )
+   {
+      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
+         return parse_perl_extension();
+   }
+   //
+   // update our mark count, and append the required state:
+   //
+   unsigned markid = 0;
+   if(0 == (this->flags() & regbase::nosubs))
+   {
+      markid = ++m_mark_count;
+#ifndef NDNBOOST_NO_STD_DISTANCE
+      if(this->flags() & regbase::save_subexpression_location)
+         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));
+#else
+      if(this->flags() & regbase::save_subexpression_location)
+         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>((m_position - m_base) - 1, 0));
+#endif
+   }
+   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+   pb->index = markid;
+   pb->icase = this->flags() & regbase::icase;
+   std::ptrdiff_t last_paren_start = this->getoffset(pb);
+   // back up insertion point for alternations, and set new point:
+   std::ptrdiff_t last_alt_point = m_alt_insert_point;
+   this->m_pdata->m_data.align();
+   m_alt_insert_point = this->m_pdata->m_data.size();
+   //
+   // back up the current flags in case we have a nested (?imsx) group:
+   //
+   regex_constants::syntax_option_type opts = this->flags();
+   bool old_case_change = m_has_case_change;
+   m_has_case_change = false; // no changes to this scope as yet...
+   //
+   // Back up branch reset data in case we have a nested (?|...)
+   //
+   int mark_reset = m_mark_reset;
+   m_mark_reset = -1;
+   //
+   // now recursively add more states, this will terminate when we get to a
+   // matching ')' :
+   //
+   parse_all();
+   //
+   // Unwind pushed alternatives:
+   //
+   if(0 == unwind_alts(last_paren_start))
+      return false;
+   //
+   // restore flags:
+   //
+   if(m_has_case_change)
+   {
+      // the case has changed in one or more of the alternatives
+      // within the scoped (...) block: we have to add a state
+      // to reset the case sensitivity:
+      static_cast<re_case*>(
+         this->append_state(syntax_element_toggle_case, sizeof(re_case))
+         )->icase = opts & regbase::icase;
+   }
+   this->flags(opts);
+   m_has_case_change = old_case_change;
+   //
+   // restore branch reset:
+   //
+   m_mark_reset = mark_reset;
+   //
+   // we either have a ')' or we have run out of characters prematurely:
+   //
+   if(m_position == m_end)
+   {
+      this->fail(regex_constants::error_paren, ::ndnboost::re_detail::distance(m_base, m_end));
+      return false;
+   }
+   NDNBOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
+#ifndef NDNBOOST_NO_STD_DISTANCE
+   if(markid && (this->flags() & regbase::save_subexpression_location))
+      this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);
+#else
+   if(markid && (this->flags() & regbase::save_subexpression_location))
+      this->m_pdata->m_subs.at(markid - 1).second = (m_position - m_base);
+#endif
+   ++m_position;
+   //
+   // append closing parenthesis state:
+   //
+   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
+   pb->index = markid;
+   pb->icase = this->flags() & regbase::icase;
+   this->m_paren_start = last_paren_start;
+   //
+   // restore the alternate insertion point:
+   //
+   this->m_alt_insert_point = last_alt_point;
+   //
+   // allow backrefs to this mark:
+   //
+   if((markid > 0) && (markid < sizeof(unsigned) * CHAR_BIT))
+      this->m_backrefs |= 1u << (markid - 1);
+
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_basic_escape()
+{
+   ++m_position;
+   bool result = true;
+   switch(this->m_traits.escape_syntax_type(*m_position))
+   {
+   case regex_constants::syntax_open_mark:
+      return parse_open_paren();
+   case regex_constants::syntax_close_mark:
+      return false;
+   case regex_constants::syntax_plus:
+      if(this->flags() & regex_constants::bk_plus_qm)
+      {
+         ++m_position;
+         return parse_repeat(1);
+      }
+      else
+         return parse_literal();
+   case regex_constants::syntax_question:
+      if(this->flags() & regex_constants::bk_plus_qm)
+      {
+         ++m_position;
+         return parse_repeat(0, 1);
+      }
+      else
+         return parse_literal();
+   case regex_constants::syntax_open_brace:
+      if(this->flags() & regbase::no_intervals)
+         return parse_literal();
+      ++m_position;
+      return parse_repeat_range(true);
+   case regex_constants::syntax_close_brace:
+      if(this->flags() & regbase::no_intervals)
+         return parse_literal();
+      fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
+      return false;
+   case regex_constants::syntax_or:
+      if(this->flags() & regbase::bk_vbar)
+         return parse_alt();
+      else
+         result = parse_literal();
+      break;
+   case regex_constants::syntax_digit:
+      return parse_backref();
+   case regex_constants::escape_type_start_buffer:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         ++m_position;
+         this->append_state(syntax_element_buffer_start);
+      }
+      else
+         result = parse_literal();
+      break;
+   case regex_constants::escape_type_end_buffer:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         ++m_position;
+         this->append_state(syntax_element_buffer_end);
+      }
+      else
+         result = parse_literal();
+      break;
+   case regex_constants::escape_type_word_assert:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         ++m_position;
+         this->append_state(syntax_element_word_boundary);
+      }
+      else
+         result = parse_literal();
+      break;
+   case regex_constants::escape_type_not_word_assert:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         ++m_position;
+         this->append_state(syntax_element_within_word);
+      }
+      else
+         result = parse_literal();
+      break;
+   case regex_constants::escape_type_left_word:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         ++m_position;
+         this->append_state(syntax_element_word_start);
+      }
+      else
+         result = parse_literal();
+      break;
+   case regex_constants::escape_type_right_word:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         ++m_position;
+         this->append_state(syntax_element_word_end);
+      }
+      else
+         result = parse_literal();
+      break;
+   default:
+      if(this->flags() & regbase::emacs_ex)
+      {
+         bool negate = true;
+         switch(*m_position)
+         {
+         case 'w':
+            negate = false;
+            NDNBOOST_FALLTHROUGH;
+         case 'W':
+            {
+            basic_char_set<charT, traits> char_set;
+            if(negate)
+               char_set.negate();
+            char_set.add_class(this->m_word_mask);
+            if(0 == this->append_set(char_set))
+            {
+               fail(regex_constants::error_ctype, m_position - m_base);
+               return false;
+            }
+            ++m_position;
+            return true;
+            }
+         case 's':
+            negate = false;
+            NDNBOOST_FALLTHROUGH;
+         case 'S':
+            return add_emacs_code(negate);
+         case 'c':
+         case 'C':
+            // not supported yet:
+            fail(regex_constants::error_escape, m_position - m_base, "The \\c and \\C escape sequences are not supported by POSIX basic regular expressions: try the Perl syntax instead.");
+            return false;
+         default:
+            break;
+         }
+      }
+      result = parse_literal();
+      break;
+   }
+   return result;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_extended_escape()
+{
+   ++m_position;
+   if(m_position == m_end)
+   {
+      fail(regex_constants::error_escape, m_position - m_base, "Incomplete escape sequence found.");
+      return false;
+   }
+   bool negate = false; // in case this is a character class escape: \w \d etc
+   switch(this->m_traits.escape_syntax_type(*m_position))
+   {
+   case regex_constants::escape_type_not_class:
+      negate = true;
+      NDNBOOST_FALLTHROUGH;
+   case regex_constants::escape_type_class:
+      {
+escape_type_class_jump:
+         typedef typename traits::char_class_type m_type;
+         m_type m = this->m_traits.lookup_classname(m_position, m_position+1);
+         if(m != 0)
+         {
+            basic_char_set<charT, traits> char_set;
+            if(negate)
+               char_set.negate();
+            char_set.add_class(m);
+            if(0 == this->append_set(char_set))
+            {
+               fail(regex_constants::error_ctype, m_position - m_base);
+               return false;
+            }
+            ++m_position;
+            return true;
+         }
+         //
+         // not a class, just a regular unknown escape:
+         //
+         this->append_literal(unescape_character());
+         break;
+      }
+   case regex_constants::syntax_digit:
+      return parse_backref();
+   case regex_constants::escape_type_left_word:
+      ++m_position;
+      this->append_state(syntax_element_word_start);
+      break;
+   case regex_constants::escape_type_right_word:
+      ++m_position;
+      this->append_state(syntax_element_word_end);
+      break;
+   case regex_constants::escape_type_start_buffer:
+      ++m_position;
+      this->append_state(syntax_element_buffer_start);
+      break;
+   case regex_constants::escape_type_end_buffer:
+      ++m_position;
+      this->append_state(syntax_element_buffer_end);
+      break;
+   case regex_constants::escape_type_word_assert:
+      ++m_position;
+      this->append_state(syntax_element_word_boundary);
+      break;
+   case regex_constants::escape_type_not_word_assert:
+      ++m_position;
+      this->append_state(syntax_element_within_word);
+      break;
+   case regex_constants::escape_type_Z:
+      ++m_position;
+      this->append_state(syntax_element_soft_buffer_end);
+      break;
+   case regex_constants::escape_type_Q:
+      return parse_QE();
+   case regex_constants::escape_type_C:
+      return parse_match_any();
+   case regex_constants::escape_type_X:
+      ++m_position;
+      this->append_state(syntax_element_combining);
+      break;
+   case regex_constants::escape_type_G:
+      ++m_position;
+      this->append_state(syntax_element_restart_continue);
+      break;
+   case regex_constants::escape_type_not_property:
+      negate = true;
+      NDNBOOST_FALLTHROUGH;
+   case regex_constants::escape_type_property:
+      {
+         ++m_position;
+         char_class_type m;
+         if(m_position == m_end)
+         {
+            fail(regex_constants::error_escape, m_position - m_base, "Incomplete property escape found.");
+            return false;
+         }
+         // maybe have \p{ddd}
+         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+         {
+            const charT* base = m_position;
+            // skip forward until we find enclosing brace:
+            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+               ++m_position;
+            if(m_position == m_end)
+            {
+               fail(regex_constants::error_escape, m_position - m_base, "Closing } missing from property escape sequence.");
+               return false;
+            }
+            m = this->m_traits.lookup_classname(++base, m_position++);
+         }
+         else
+         {
+            m = this->m_traits.lookup_classname(m_position, m_position+1);
+            ++m_position;
+         }
+         if(m != 0)
+         {
+            basic_char_set<charT, traits> char_set;
+            if(negate)
+               char_set.negate();
+            char_set.add_class(m);
+            if(0 == this->append_set(char_set))
+            {
+               fail(regex_constants::error_ctype, m_position - m_base);
+               return false;
+            }
+            return true;
+         }
+         fail(regex_constants::error_ctype, m_position - m_base, "Escape sequence was neither a valid property nor a valid character class name.");
+         return false;
+      }
+   case regex_constants::escape_type_reset_start_mark:
+      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+      {
+         re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+         pb->index = -5;
+         pb->icase = this->flags() & regbase::icase;
+         this->m_pdata->m_data.align();
+         ++m_position;
+         return true;
+      }
+      goto escape_type_class_jump;
+   case regex_constants::escape_type_line_ending:
+      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+      {
+         const charT* e = get_escape_R_string<charT>();
+         const charT* old_position = m_position;
+         const charT* old_end = m_end;
+         const charT* old_base = m_base;
+         m_position = e;
+         m_base = e;
+         m_end = e + traits::length(e);
+         bool r = parse_all();
+         m_position = ++old_position;
+         m_end = old_end;
+         m_base = old_base;
+         return r;
+      }
+      goto escape_type_class_jump;
+   case regex_constants::escape_type_extended_backref:
+      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+      {
+         bool have_brace = false;
+         bool negative = false;
+         static const char* incomplete_message = "Incomplete \\g escape found.";
+         if(++m_position == m_end)
+         {
+            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
+            return false;
+         }
+         // maybe have \g{ddd}
+         regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position);
+         regex_constants::syntax_type syn_end = 0;
+         if((syn == regex_constants::syntax_open_brace) 
+            || (syn == regex_constants::escape_type_left_word)
+            || (syn == regex_constants::escape_type_end_buffer))
+         {
+            if(++m_position == m_end)
+            {
+               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
+               return false;
+            }
+            have_brace = true;
+            switch(syn)
+            {
+            case regex_constants::syntax_open_brace:
+               syn_end = regex_constants::syntax_close_brace;
+               break;
+            case regex_constants::escape_type_left_word:
+               syn_end = regex_constants::escape_type_right_word;
+               break;
+            default:
+               syn_end = regex_constants::escape_type_end_buffer;
+               break;
+            }
+         }
+         negative = (*m_position == static_cast<charT>('-'));
+         if((negative) && (++m_position == m_end))
+         {
+            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
+            return false;
+         }
+         const charT* pc = m_position;
+         int i = this->m_traits.toi(pc, m_end, 10);
+         if((i < 0) && syn_end)
+         {
+            // Check for a named capture, get the leftmost one if there is more than one:
+            const charT* base = m_position;
+            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end))
+            {
+               ++m_position;
+            }
+            i = hash_value_from_capture_name(base, m_position);
+            pc = m_position;
+         }
+         if(negative)
+            i = 1 + m_mark_count - i;
+         if(((i > 0) && (this->m_backrefs & (1u << (i-1)))) || ((i > 10000) && (this->m_pdata->get_id(i) > 0) && (this->m_backrefs & (1u << (this->m_pdata->get_id(i)-1)))))
+         {
+            m_position = pc;
+            re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
+            pb->index = i;
+            pb->icase = this->flags() & regbase::icase;
+         }
+         else
+         {
+            fail(regex_constants::error_backref, m_position - m_base);
+            return false;
+         }
+         m_position = pc;
+         if(have_brace)
+         {
+            if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end))
+            {
+               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
+               return false;
+            }
+            ++m_position;
+         }
+         return true;
+      }
+      goto escape_type_class_jump;
+   case regex_constants::escape_type_control_v:
+      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+         goto escape_type_class_jump;
+      NDNBOOST_FALLTHROUGH;
+   default:
+      this->append_literal(unescape_character());
+      break;
+   }
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_match_any()
+{
+   //
+   // we have a '.' that can match any character:
+   //
+   ++m_position;
+   static_cast<re_dot*>(
+      this->append_state(syntax_element_wild, sizeof(re_dot))
+      )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s 
+      ? re_detail::force_not_newline 
+         : this->flags() & regbase::mod_s ?
+            re_detail::force_newline : re_detail::dont_care);
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)
+{
+   bool greedy = true;
+   bool pocessive = false;
+   std::size_t insert_point;
+   // 
+   // when we get to here we may have a non-greedy ? mark still to come:
+   //
+   if((m_position != m_end) 
+      && (
+            (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+            || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))
+         )
+      )
+   {
+      // OK we have a perl or emacs regex, check for a '?':
+      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
+      {
+         greedy = false;
+         ++m_position;
+      }
+      // for perl regexes only check for pocessive ++ repeats.
+      if((m_position != m_end)
+         && (0 == (this->flags() & regbase::main_option_type)) 
+         && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))
+      {
+         pocessive = true;
+         ++m_position;
+      }
+   }
+   if(0 == this->m_last_state)
+   {
+      fail(regex_constants::error_badrepeat, ::ndnboost::re_detail::distance(m_base, m_position), "Nothing to repeat.");
+      return false;
+   }
+   if(this->m_last_state->type == syntax_element_endmark)
+   {
+      // insert a repeat before the '(' matching the last ')':
+      insert_point = this->m_paren_start;
+   }
+   else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))
+   {
+      // the last state was a literal with more than one character, split it in two:
+      re_literal* lit = static_cast<re_literal*>(this->m_last_state);
+      charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];
+      --(lit->length);
+      // now append new state:
+      lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
+      lit->length = 1;
+      (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;
+      insert_point = this->getoffset(this->m_last_state);
+   }
+   else
+   {
+      // repeat the last state whatever it was, need to add some error checking here:
+      switch(this->m_last_state->type)
+      {
+      case syntax_element_start_line:
+      case syntax_element_end_line:
+      case syntax_element_word_boundary:
+      case syntax_element_within_word:
+      case syntax_element_word_start:
+      case syntax_element_word_end:
+      case syntax_element_buffer_start:
+      case syntax_element_buffer_end:
+      case syntax_element_alt:
+      case syntax_element_soft_buffer_end:
+      case syntax_element_restart_continue:
+      case syntax_element_jump:
+      case syntax_element_startmark:
+      case syntax_element_backstep:
+         // can't legally repeat any of the above:
+         fail(regex_constants::error_badrepeat, m_position - m_base);
+         return false;
+      default:
+         // do nothing...
+         break;
+      }
+      insert_point = this->getoffset(this->m_last_state);
+   }
+   //
+   // OK we now know what to repeat, so insert the repeat around it:
+   //
+   re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));
+   rep->min = low;
+   rep->max = high;
+   rep->greedy = greedy;
+   rep->leading = false;
+   // store our repeater position for later:
+   std::ptrdiff_t rep_off = this->getoffset(rep);
+   // and append a back jump to the repeat:
+   re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));
+   jmp->alt.i = rep_off - this->getoffset(jmp);
+   this->m_pdata->m_data.align();
+   // now fill in the alt jump for the repeat:
+   rep = static_cast<re_repeat*>(this->getaddress(rep_off));
+   rep->alt.i = this->m_pdata->m_data.size() - rep_off;
+   //
+   // If the repeat is pocessive then bracket the repeat with a (?>...)
+   // independent sub-expression construct:
+   //
+   if(pocessive)
+   {
+      if(m_position != m_end)
+      {
+         //
+         // Check for illegal following quantifier, we have to do this here, because
+         // the extra states we insert below circumvents our usual error checking :-(
+         //
+         switch(this->m_traits.syntax_type(*m_position))
+         {
+         case regex_constants::syntax_star:
+         case regex_constants::syntax_plus:
+         case regex_constants::syntax_question:
+         case regex_constants::syntax_open_brace:
+            fail(regex_constants::error_badrepeat, m_position - m_base);
+            return false;
+         }
+      }
+      re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
+      pb->index = -3;
+      pb->icase = this->flags() & regbase::icase;
+      jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));
+      this->m_pdata->m_data.align();
+      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
+      pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
+      pb->index = -3;
+      pb->icase = this->flags() & regbase::icase;
+   }
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
+{
+   static const char* incomplete_message = "Missing } in quantified repetition.";
+   //
+   // parse a repeat-range:
+   //
+   std::size_t min, max;
+   int v;
+   // skip whitespace:
+   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+      ++m_position;
+   if(this->m_position == this->m_end)
+   {
+      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
+      {
+         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+         return false;
+      }
+      // Treat the opening '{' as a literal character, rewind to start of error:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
+      return parse_literal();
+   }
+   // get min:
+   v = this->m_traits.toi(m_position, m_end, 10);
+   // skip whitespace:
+   if(v < 0)
+   {
+      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
+      {
+         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+         return false;
+      }
+      // Treat the opening '{' as a literal character, rewind to start of error:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
+      return parse_literal();
+   }
+   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+      ++m_position;
+   if(this->m_position == this->m_end)
+   {
+      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
+      {
+         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+         return false;
+      }
+      // Treat the opening '{' as a literal character, rewind to start of error:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
+      return parse_literal();
+   }
+   min = v;
+   // see if we have a comma:
+   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)
+   {
+      // move on and error check:
+      ++m_position;
+      // skip whitespace:
+      while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+         ++m_position;
+      if(this->m_position == this->m_end)
+      {
+         if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
+         {
+            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+            return false;
+         }
+         // Treat the opening '{' as a literal character, rewind to start of error:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
+         return parse_literal();
+      }
+      // get the value if any:
+      v = this->m_traits.toi(m_position, m_end, 10);
+      max = (v >= 0) ? (std::size_t)v : (std::numeric_limits<std::size_t>::max)();
+   }
+   else
+   {
+      // no comma, max = min:
+      max = min;
+   }
+   // skip whitespace:
+   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+      ++m_position;
+   // OK now check trailing }:
+   if(this->m_position == this->m_end)
+   {
+      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
+      {
+         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+         return false;
+      }
+      // Treat the opening '{' as a literal character, rewind to start of error:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
+      return parse_literal();
+   }
+   if(isbasic)
+   {
+      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)
+      {
+         ++m_position;
+         if(this->m_position == this->m_end)
+         {
+            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+            return false;
+         }
+      }
+      else
+      {
+         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
+         return false;
+      }
+   }
+   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)
+      ++m_position;
+   else
+   {
+      // Treat the opening '{' as a literal character, rewind to start of error:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
+      return parse_literal();
+   }
+   //
+   // finally go and add the repeat, unless error:
+   //
+   if(min > max)
+   {
+      // Backtrack to error location:
+      m_position -= 2;
+      while(this->m_traits.isctype(*m_position, this->m_word_mask)) --m_position;
+         ++m_position;
+      fail(regex_constants::error_badbrace, m_position - m_base);
+      return false;
+   }
+   return parse_repeat(min, max);
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_alt()
+{
+   //
+   // error check: if there have been no previous states,
+   // or if the last state was a '(' then error:
+   //
+   if(
+      ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))
+      &&
+      !(
+         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
+           &&
+         ((this->flags() & regbase::no_empty_expressions) == 0)
+        )
+      )
+   {
+      fail(regex_constants::error_empty, this->m_position - this->m_base, "A regular expression can start with the alternation operator |.");
+      return false;
+   }
+   //
+   // Reset mark count if required:
+   //
+   if(m_max_mark < m_mark_count)
+      m_max_mark = m_mark_count;
+   if(m_mark_reset >= 0)
+      m_mark_count = m_mark_reset;
+
+   ++m_position;
+   //
+   // we need to append a trailing jump: 
+   //
+   re_syntax_base* pj = this->append_state(re_detail::syntax_element_jump, sizeof(re_jump));
+   std::ptrdiff_t jump_offset = this->getoffset(pj);
+   //
+   // now insert the alternative:
+   //
+   re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));
+   jump_offset += re_alt_size;
+   this->m_pdata->m_data.align();
+   palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);
+   //
+   // update m_alt_insert_point so that the next alternate gets
+   // inserted at the start of the second of the two we've just created:
+   //
+   this->m_alt_insert_point = this->m_pdata->m_data.size();
+   //
+   // the start of this alternative must have a case changes state
+   // if the current block has messed around with case changes:
+   //
+   if(m_has_case_change)
+   {
+      static_cast<re_case*>(
+         this->append_state(syntax_element_toggle_case, sizeof(re_case))
+         )->icase = this->m_icase;
+   }
+   //
+   // push the alternative onto our stack, a recursive
+   // implementation here is easier to understand (and faster
+   // as it happens), but causes all kinds of stack overflow problems
+   // on programs with small stacks (COM+).
+   //
+   m_alt_jumps.push_back(jump_offset);
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_set()
+{
+   static const char* incomplete_message = "Character set declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
+   ++m_position;
+   if(m_position == m_end)
+   {
+      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+      return false;
+   }
+   basic_char_set<charT, traits> char_set;
+
+   const charT* base = m_position;  // where the '[' was
+   const charT* item_base = m_position;  // where the '[' or '^' was
+
+   while(m_position != m_end)
+   {
+      switch(this->m_traits.syntax_type(*m_position))
+      {
+      case regex_constants::syntax_caret:
+         if(m_position == base)
+         {
+            char_set.negate();
+            ++m_position;
+            item_base = m_position;
+         }
+         else
+            parse_set_literal(char_set);
+         break;
+      case regex_constants::syntax_close_set:
+         if(m_position == item_base)
+         {
+            parse_set_literal(char_set);
+            break;
+         }
+         else
+         {
+            ++m_position;
+            if(0 == this->append_set(char_set))
+            {
+               fail(regex_constants::error_ctype, m_position - m_base);
+               return false;
+            }
+         }
+         return true;
+      case regex_constants::syntax_open_set:
+         if(parse_inner_set(char_set))
+            break;
+         return true;
+      case regex_constants::syntax_escape:
+         {
+            // 
+            // look ahead and see if this is a character class shortcut
+            // \d \w \s etc...
+            //
+            ++m_position;
+            if(this->m_traits.escape_syntax_type(*m_position)
+               == regex_constants::escape_type_class)
+            {
+               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
+               if(m != 0)
+               {
+                  char_set.add_class(m);
+                  ++m_position;
+                  break;
+               }
+            }
+            else if(this->m_traits.escape_syntax_type(*m_position)
+               == regex_constants::escape_type_not_class)
+            {
+               // negated character class:
+               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
+               if(m != 0)
+               {
+                  char_set.add_negated_class(m);
+                  ++m_position;
+                  break;
+               }
+            }
+            // not a character class, just a regular escape:
+            --m_position;
+            parse_set_literal(char_set);
+            break;
+         }
+      default:
+         parse_set_literal(char_set);
+         break;
+      }
+   }
+   return m_position != m_end;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, traits>& char_set)
+{
+   static const char* incomplete_message = "Character class declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
+   //
+   // we have either a character class [:name:]
+   // a collating element [.name.]
+   // or an equivalence class [=name=]
+   //
+   if(m_end == ++m_position)
+   {
+      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+      return false;
+   }
+   switch(this->m_traits.syntax_type(*m_position))
+   {
+   case regex_constants::syntax_dot:
+      //
+      // a collating element is treated as a literal:
+      //
+      --m_position;
+      parse_set_literal(char_set);
+      return true;
+   case regex_constants::syntax_colon:
+      {
+      // check that character classes are actually enabled:
+      if((this->flags() & (regbase::main_option_type | regbase::no_char_classes)) 
+         == (regbase::basic_syntax_group  | regbase::no_char_classes))
+      {
+         --m_position;
+         parse_set_literal(char_set);
+         return true;
+      }
+      // skip the ':'
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      const charT* name_first = m_position;
+      // skip at least one character, then find the matching ':]'
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      while((m_position != m_end) 
+         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon)) 
+         ++m_position;
+      const charT* name_last = m_position;
+      if(m_end == m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      if((m_end == ++m_position) 
+         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      //
+      // check for negated class:
+      //
+      bool negated = false;
+      if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)
+      {
+         ++name_first;
+         negated = true;
+      }
+      typedef typename traits::char_class_type m_type;
+      m_type m = this->m_traits.lookup_classname(name_first, name_last);
+      if(m == 0)
+      {
+         if(char_set.empty() && (name_last - name_first == 1))
+         {
+            // maybe a special case:
+            ++m_position;
+            if( (m_position != m_end) 
+               && (this->m_traits.syntax_type(*m_position) 
+                  == regex_constants::syntax_close_set))
+            {
+               if(this->m_traits.escape_syntax_type(*name_first) 
+                  == regex_constants::escape_type_left_word)
+               {
+                  ++m_position;
+                  this->append_state(syntax_element_word_start);
+                  return false;
+               }
+               if(this->m_traits.escape_syntax_type(*name_first) 
+                  == regex_constants::escape_type_right_word)
+               {
+                  ++m_position;
+                  this->append_state(syntax_element_word_end);
+                  return false;
+               }
+            }
+         }
+         fail(regex_constants::error_ctype, name_first - m_base);
+         return false;
+      }
+      if(negated == false)
+         char_set.add_class(m);
+      else
+         char_set.add_negated_class(m);
+      ++m_position;
+      break;
+   }
+   case regex_constants::syntax_equal:
+      {
+      // skip the '='
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      const charT* name_first = m_position;
+      // skip at least one character, then find the matching '=]'
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      while((m_position != m_end) 
+         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)) 
+         ++m_position;
+      const charT* name_last = m_position;
+      if(m_end == m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      if((m_end == ++m_position) 
+         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+      {
+         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
+         return false;
+      }
+      string_type m = this->m_traits.lookup_collatename(name_first, name_last);
+      if((0 == m.size()) || (m.size() > 2))
+      {
+         fail(regex_constants::error_collate, name_first - m_base);
+         return false;
+      }
+      digraph<charT> d;
+      d.first = m[0];
+      if(m.size() > 1)
+         d.second = m[1];
+      else
+         d.second = 0;
+      char_set.add_equivalent(d);
+      ++m_position;
+      break;
+   }
+   default:
+      --m_position;
+      parse_set_literal(char_set);
+      break;
+   }
+   return true;
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)
+{
+   digraph<charT> start_range(get_next_set_literal(char_set));
+   if(m_end == m_position)
+   {
+      fail(regex_constants::error_brack, m_position - m_base);
+      return;
+   }
+   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
+   {
+      // we have a range:
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_brack, m_position - m_base);
+         return;
+      }
+      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)
+      {
+         digraph<charT> end_range = get_next_set_literal(char_set);
+         char_set.add_range(start_range, end_range);
+         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
+         {
+            if(m_end == ++m_position)
+            {
+               fail(regex_constants::error_brack, m_position - m_base);
+               return;
+            }
+            if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)
+            {
+               // trailing - :
+               --m_position;
+               return;
+            }
+            fail(regex_constants::error_range, m_position - m_base);
+            return;
+         }
+         return;
+      }
+      --m_position;
+   }
+   char_set.add_single(start_range);
+}
+
+template <class charT, class traits>
+digraph<charT> basic_regex_parser<charT, traits>::get_next_set_literal(basic_char_set<charT, traits>& char_set)
+{
+   digraph<charT> result;
+   switch(this->m_traits.syntax_type(*m_position))
+   {
+   case regex_constants::syntax_dash:
+      if(!char_set.empty())
+      {
+         // see if we are at the end of the set:
+         if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+         {
+            fail(regex_constants::error_range, m_position - m_base);
+            return result;
+         }
+         --m_position;
+      }
+      result.first = *m_position++;
+      return result;
+   case regex_constants::syntax_escape:
+      // check to see if escapes are supported first:
+      if(this->flags() & regex_constants::no_escape_in_lists)
+      {
+         result = *m_position++;
+         break;
+      }
+      ++m_position;
+      result = unescape_character();
+      break;
+   case regex_constants::syntax_open_set:
+   {
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_collate, m_position - m_base);
+         return result;
+      }
+      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)
+      {
+         --m_position;
+         result.first = *m_position;
+         ++m_position;
+         return result;
+      }
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_collate, m_position - m_base);
+         return result;
+      }
+      const charT* name_first = m_position;
+      // skip at least one character, then find the matching ':]'
+      if(m_end == ++m_position)
+      {
+         fail(regex_constants::error_collate, name_first - m_base);
+         return result;
+      }
+      while((m_position != m_end) 
+         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)) 
+         ++m_position;
+      const charT* name_last = m_position;
+      if(m_end == m_position)
+      {
+         fail(regex_constants::error_collate, name_first - m_base);
+         return result;
+      }
+      if((m_end == ++m_position) 
+         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+      {
+         fail(regex_constants::error_collate, name_first - m_base);
+         return result;
+      }
+      ++m_position;
+      string_type s = this->m_traits.lookup_collatename(name_first, name_last);
+      if(s.empty() || (s.size() > 2))
+      {
+         fail(regex_constants::error_collate, name_first - m_base);
+         return result;
+      }
+      result.first = s[0];
+      if(s.size() > 1)
+         result.second = s[1];
+      else
+         result.second = 0;
+      return result;
+   }
+   default:
+      result = *m_position++;
+   }
+   return result;
+}
+
+//
+// does a value fit in the specified charT type?
+//
+template <class charT>
+bool valid_value(charT, int v, const mpl::true_&)
+{
+   return (v >> (sizeof(charT) * CHAR_BIT)) == 0;
+}
+template <class charT>
+bool valid_value(charT, int, const mpl::false_&)
+{
+   return true; // v will alsways fit in a charT
+}
+template <class charT>
+bool valid_value(charT c, int v)
+{
+   return valid_value(c, v, mpl::bool_<(sizeof(charT) < sizeof(int))>());
+}
+
+template <class charT, class traits>
+charT basic_regex_parser<charT, traits>::unescape_character()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   charT result(0);
+   if(m_position == m_end)
+   {
+      fail(regex_constants::error_escape, m_position - m_base, "Escape sequence terminated prematurely.");
+      return false;
+   }
+   switch(this->m_traits.escape_syntax_type(*m_position))
+   {
+   case regex_constants::escape_type_control_a:
+      result = charT('\a');
+      break;
+   case regex_constants::escape_type_e:
+      result = charT(27);
+      break;
+   case regex_constants::escape_type_control_f:
+      result = charT('\f');
+      break;
+   case regex_constants::escape_type_control_n:
+      result = charT('\n');
+      break;
+   case regex_constants::escape_type_control_r:
+      result = charT('\r');
+      break;
+   case regex_constants::escape_type_control_t:
+      result = charT('\t');
+      break;
+   case regex_constants::escape_type_control_v:
+      result = charT('\v');
+      break;
+   case regex_constants::escape_type_word_assert:
+      result = charT('\b');
+      break;
+   case regex_constants::escape_type_ascii_control:
+      ++m_position;
+      if(m_position == m_end)
+      {
+         // Rewind to start of escape:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+         fail(regex_constants::error_escape, m_position - m_base, "ASCII escape sequence terminated prematurely.");
+         return result;
+      }
+      result = static_cast<charT>(*m_position % 32);
+      break;
+   case regex_constants::escape_type_hex:
+      ++m_position;
+      if(m_position == m_end)
+      {
+         // Rewind to start of escape:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+         fail(regex_constants::error_escape, m_position - m_base, "Hexadecimal escape sequence terminated prematurely.");
+         return result;
+      }
+      // maybe have \x{ddd}
+      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+      {
+         ++m_position;
+         if(m_position == m_end)
+         {
+            // Rewind to start of escape:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+            fail(regex_constants::error_escape, m_position - m_base, "Missing } in hexadecimal escape sequence.");
+            return result;
+         }
+         int i = this->m_traits.toi(m_position, m_end, 16);
+         if((m_position == m_end)
+            || (i < 0)
+            || ((std::numeric_limits<charT>::is_specialized) && (i > (int)(std::numeric_limits<charT>::max)()))
+            || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+         {
+            // Rewind to start of escape:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+            fail(regex_constants::error_badbrace, m_position - m_base, "Hexadecimal escape sequence was invalid.");
+            return result;
+         }
+         ++m_position;
+         result = charT(i);
+      }
+      else
+      {
+         std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), static_cast<std::ptrdiff_t>(m_end - m_position));
+         int i = this->m_traits.toi(m_position, m_position + len, 16);
+         if((i < 0)
+            || !valid_value(charT(0), i))
+         {
+            // Rewind to start of escape:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+            fail(regex_constants::error_escape, m_position - m_base, "Escape sequence did not encode a valid character.");
+            return result;
+         }
+         result = charT(i);
+      }
+      return result;
+   case regex_constants::syntax_digit:
+      {
+      // an octal escape sequence, the first character must be a zero
+      // followed by up to 3 octal digits:
+      std::ptrdiff_t len = (std::min)(::ndnboost::re_detail::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
+      const charT* bp = m_position;
+      int val = this->m_traits.toi(bp, bp + 1, 8);
+      if(val != 0)
+      {
+         // Rewind to start of escape:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+         // Oops not an octal escape after all:
+         fail(regex_constants::error_escape, m_position - m_base, "Invalid octal escape sequence.");
+         return result;
+      }
+      val = this->m_traits.toi(m_position, m_position + len, 8);
+      if(val < 0) 
+      {
+         // Rewind to start of escape:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+         fail(regex_constants::error_escape, m_position - m_base, "Octal escape sequence is invalid.");
+         return result;
+      }
+      return static_cast<charT>(val);
+      }
+   case regex_constants::escape_type_named_char:
+      {
+         ++m_position;
+         if(m_position == m_end)
+         {
+            // Rewind to start of escape:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+            fail(regex_constants::error_escape, m_position - m_base);
+            return false;
+         }
+         // maybe have \N{name}
+         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+         {
+            const charT* base = m_position;
+            // skip forward until we find enclosing brace:
+            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+               ++m_position;
+            if(m_position == m_end)
+            {
+               // Rewind to start of escape:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+               fail(regex_constants::error_escape, m_position - m_base);
+               return false;
+            }
+            string_type s = this->m_traits.lookup_collatename(++base, m_position++);
+            if(s.empty())
+            {
+               // Rewind to start of escape:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+               fail(regex_constants::error_collate, m_position - m_base);
+               return false;
+            }
+            if(s.size() == 1)
+            {
+               return s[0];
+            }
+         }
+         // fall through is a failure:
+         // Rewind to start of escape:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+         fail(regex_constants::error_escape, m_position - m_base);
+         return false;
+      }
+   default:
+      result = *m_position;
+      break;
+   }
+   ++m_position;
+   return result;
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_backref()
+{
+   NDNBOOST_ASSERT(m_position != m_end);
+   const charT* pc = m_position;
+   int i = this->m_traits.toi(pc, pc + 1, 10);
+   if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))
+   {
+      // not a backref at all but an octal escape sequence:
+      charT c = unescape_character();
+      this->append_literal(c);
+   }
+   else if((i > 0) && (this->m_backrefs & (1u << (i-1))))
+   {
+      m_position = pc;
+      re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
+      pb->index = i;
+      pb->icase = this->flags() & regbase::icase;
+   }
+   else
+   {
+      // Rewind to start of escape:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+      fail(regex_constants::error_backref, m_position - m_base);
+      return false;
+   }
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_QE()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   //
+   // parse a \Q...\E sequence:
+   //
+   ++m_position; // skip the Q
+   const charT* start = m_position;
+   const charT* end;
+   do
+   {
+      while((m_position != m_end) 
+         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))
+         ++m_position;
+      if(m_position == m_end)
+      {
+         //  a \Q...\E sequence may terminate with the end of the expression:
+         end = m_position;
+         break;  
+      }
+      if(++m_position == m_end) // skip the escape
+      {
+         fail(regex_constants::error_escape, m_position - m_base, "Unterminated \\Q...\\E sequence.");
+         return false;
+      }
+      // check to see if it's a \E:
+      if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)
+      {
+         ++m_position;
+         end = m_position - 2;
+         break;
+      }
+      // otherwise go round again:
+   }while(true);
+   //
+   // now add all the character between the two escapes as literals:
+   //
+   while(start != end)
+   {
+      this->append_literal(*start);
+      ++start;
+   }
+   return true;
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_perl_extension()
+{
+   if(++m_position == m_end)
+   {
+      // Rewind to start of (? sequence:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+      fail(regex_constants::error_perl_extension, m_position - m_base);
+      return false;
+   }
+   //
+   // treat comments as a special case, as these
+   // are the only ones that don't start with a leading
+   // startmark state:
+   //
+   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)
+   {
+      while((m_position != m_end) 
+         && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
+      {}      
+      return true;
+   }
+   //
+   // backup some state, and prepare the way:
+   //
+   int markid = 0;
+   std::ptrdiff_t jump_offset = 0;
+   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+   pb->icase = this->flags() & regbase::icase;
+   std::ptrdiff_t last_paren_start = this->getoffset(pb);
+   // back up insertion point for alternations, and set new point:
+   std::ptrdiff_t last_alt_point = m_alt_insert_point;
+   this->m_pdata->m_data.align();
+   m_alt_insert_point = this->m_pdata->m_data.size();
+   std::ptrdiff_t expected_alt_point = m_alt_insert_point;
+   bool restore_flags = true;
+   regex_constants::syntax_option_type old_flags = this->flags();
+   bool old_case_change = m_has_case_change;
+   m_has_case_change = false;
+   charT name_delim;
+   int mark_reset = m_mark_reset;
+   int max_mark = m_max_mark;
+   m_mark_reset = -1;
+   m_max_mark = m_mark_count;
+   int v;
+   //
+   // select the actual extension used:
+   //
+   switch(this->m_traits.syntax_type(*m_position))
+   {
+   case regex_constants::syntax_or:
+      m_mark_reset = m_mark_count;
+      NDNBOOST_FALLTHROUGH;
+   case regex_constants::syntax_colon:
+      //
+      // a non-capturing mark:
+      //
+      pb->index = markid = 0;
+      ++m_position;
+      break;
+   case regex_constants::syntax_digit:
+      {
+      //
+      // a recursive subexpression:
+      //
+      v = this->m_traits.toi(m_position, m_end, 10);
+      if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base, "The recursive sub-expression refers to an invalid marking group, or is unterminated.");
+         return false;
+      }
+insert_recursion:
+      pb->index = markid = 0;
+      re_recurse* pr = static_cast<re_recurse*>(this->append_state(syntax_element_recurse, sizeof(re_recurse)));
+      pr->alt.i = v;
+      pr->state_id = 0;
+      static_cast<re_case*>(
+            this->append_state(syntax_element_toggle_case, sizeof(re_case))
+            )->icase = this->flags() & regbase::icase;
+      break;
+      }
+   case regex_constants::syntax_plus:
+      //
+      // A forward-relative recursive subexpression:
+      //
+      ++m_position;
+      v = this->m_traits.toi(m_position, m_end, 10);
+      if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
+         return false;
+      }
+      v += m_mark_count;
+      goto insert_recursion;
+   case regex_constants::syntax_dash:
+      //
+      // Possibly a backward-relative recursive subexpression:
+      //
+      ++m_position;
+      v = this->m_traits.toi(m_position, m_end, 10);
+      if(v <= 0)
+      {
+         --m_position;
+         // Oops not a relative recursion at all, but a (?-imsx) group:
+         goto option_group_jump;
+      }
+      v = m_mark_count + 1 - v;
+      if(v <= 0)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
+         return false;
+      }
+      goto insert_recursion;
+   case regex_constants::syntax_equal:
+      pb->index = markid = -1;
+      ++m_position;
+      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+      this->m_pdata->m_data.align();
+      m_alt_insert_point = this->m_pdata->m_data.size();
+      break;
+   case regex_constants::syntax_not:
+      pb->index = markid = -2;
+      ++m_position;
+      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+      this->m_pdata->m_data.align();
+      m_alt_insert_point = this->m_pdata->m_data.size();
+      break;
+   case regex_constants::escape_type_left_word:
+      {
+         // a lookbehind assertion:
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);
+         if(t == regex_constants::syntax_not)
+            pb->index = markid = -2;
+         else if(t == regex_constants::syntax_equal)
+            pb->index = markid = -1;
+         else
+         {
+            // Probably a named capture which also starts (?< :
+            name_delim = '>';
+            --m_position;
+            goto named_capture_jump;
+         }
+         ++m_position;
+         jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+         this->append_state(syntax_element_backstep, sizeof(re_brace));
+         this->m_pdata->m_data.align();
+         m_alt_insert_point = this->m_pdata->m_data.size();
+         break;
+      }
+   case regex_constants::escape_type_right_word:
+      //
+      // an independent sub-expression:
+      //
+      pb->index = markid = -3;
+      ++m_position;
+      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+      this->m_pdata->m_data.align();
+      m_alt_insert_point = this->m_pdata->m_data.size();
+      break;
+   case regex_constants::syntax_open_mark:
+      {
+      // a conditional expression:
+      pb->index = markid = -4;
+      if(++m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base);
+         return false;
+      }
+      v = this->m_traits.toi(m_position, m_end, 10);
+      if(m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base);
+         return false;
+      }
+      if(*m_position == charT('R'))
+      {
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(*m_position == charT('&'))
+         {
+            const charT* base = ++m_position;
+            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+               ++m_position;
+            if(m_position == m_end)
+            {
+               // Rewind to start of (? sequence:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+               fail(regex_constants::error_perl_extension, m_position - m_base);
+               return false;
+            }
+            v = -static_cast<int>(hash_value_from_capture_name(base, m_position));
+         }
+         else
+         {
+            v = -this->m_traits.toi(m_position, m_end, 10);
+         }
+         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+         br->index = v < 0 ? (v - 1) : 0;
+         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+      }
+      else if((*m_position == charT('\'')) || (*m_position == charT('<')))
+      {
+         const charT* base = ++m_position;
+         while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\'')))
+            ++m_position;
+         if(m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
+         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+         br->index = v;
+         if(((*m_position != charT('>')) && (*m_position != charT('\''))) || (++m_position == m_end))
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base, "Unterminated named capture.");
+            return false;
+         }
+         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+      }
+      else if(*m_position == charT('D'))
+      {
+         const char* def = "DEFINE";
+         while(*def && (m_position != m_end) && (*m_position == charT(*def)))
+            ++m_position, ++def;
+         if((m_position == m_end) || *def)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+         br->index = 9999; // special magic value!
+         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+      }
+      else if(v > 0)
+      {
+         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+         br->index = v;
+         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+      }
+      else
+      {
+         // verify that we have a lookahead or lookbehind assert:
+         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)
+         {
+            if(++m_position == m_end)
+            {
+               // Rewind to start of (? sequence:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+               fail(regex_constants::error_perl_extension, m_position - m_base);
+               return false;
+            }
+            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
+               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
+            {
+               // Rewind to start of (? sequence:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+               fail(regex_constants::error_perl_extension, m_position - m_base);
+               return false;
+            }
+            m_position -= 3;
+         }
+         else
+         {
+            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
+               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
+            {
+               // Rewind to start of (? sequence:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+               fail(regex_constants::error_perl_extension, m_position - m_base);
+               return false;
+            }
+            m_position -= 2;
+         }
+      }
+      break;
+      }
+   case regex_constants::syntax_close_mark:
+      // Rewind to start of (? sequence:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+      fail(regex_constants::error_perl_extension, m_position - m_base);
+      return false;
+   case regex_constants::escape_type_end_buffer:
+      {
+      name_delim = *m_position;
+named_capture_jump:
+      markid = 0;
+      if(0 == (this->flags() & regbase::nosubs))
+      {
+         markid = ++m_mark_count;
+   #ifndef NDNBOOST_NO_STD_DISTANCE
+         if(this->flags() & regbase::save_subexpression_location)
+            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));
+   #else
+         if(this->flags() & regbase::save_subexpression_location)
+            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>((m_position - m_base) - 2, 0));
+   #endif
+      }
+      pb->index = markid;
+      const charT* base = ++m_position;
+      if(m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base);
+         return false;
+      }
+      while((m_position != m_end) && (*m_position != name_delim))
+         ++m_position;
+      if(m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base);
+         return false;
+      }
+      this->m_pdata->set_name(base, m_position, markid);
+      ++m_position;
+      break;
+      }
+   default:
+      if(*m_position == charT('R'))
+      {
+         ++m_position;
+         v = 0;
+         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         goto insert_recursion;
+      }
+      if(*m_position == charT('&'))
+      {
+         ++m_position;
+         const charT* base = m_position;
+         while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+            ++m_position;
+         if(m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
+         goto insert_recursion;
+      }
+      if(*m_position == charT('P'))
+      {
+         ++m_position;
+         if(m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_perl_extension, m_position - m_base);
+            return false;
+         }
+         if(*m_position == charT('>'))
+         {
+            ++m_position;
+            const charT* base = m_position;
+            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+               ++m_position;
+            if(m_position == m_end)
+            {
+               // Rewind to start of (? sequence:
+               --m_position;
+               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+               fail(regex_constants::error_perl_extension, m_position - m_base);
+               return false;
+            }
+            v = static_cast<int>(hash_value_from_capture_name(base, m_position));
+            goto insert_recursion;
+         }
+      }
+      //
+      // lets assume that we have a (?imsx) group and try and parse it:
+      //
+option_group_jump:
+      regex_constants::syntax_option_type opts = parse_options();
+      if(m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base);
+         return false;
+      }
+      // make a note of whether we have a case change:
+      m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
+      pb->index = markid = 0;
+      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)
+      {
+         // update flags and carry on as normal:
+         this->flags(opts);
+         restore_flags = false;
+         old_case_change |= m_has_case_change; // defer end of scope by one ')'
+      }
+      else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)
+      {
+         // update flags and carry on until the matching ')' is found:
+         this->flags(opts);
+         ++m_position;
+      }
+      else
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base);
+         return false;
+      }
+
+      // finally append a case change state if we need it:
+      if(m_has_case_change)
+      {
+         static_cast<re_case*>(
+            this->append_state(syntax_element_toggle_case, sizeof(re_case))
+            )->icase = opts & regbase::icase;
+      }
+
+   }
+   //
+   // now recursively add more states, this will terminate when we get to a
+   // matching ')' :
+   //
+   parse_all();
+   //
+   // Unwind alternatives:
+   //
+   if(0 == unwind_alts(last_paren_start))
+   {
+      // Rewind to start of (? sequence:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+      fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid alternation operators within (?...) block.");
+      return false;
+   }
+   //
+   // we either have a ')' or we have run out of characters prematurely:
+   //
+   if(m_position == m_end)
+   {
+      // Rewind to start of (? sequence:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+      this->fail(regex_constants::error_paren, ::ndnboost::re_detail::distance(m_base, m_end));
+      return false;
+   }
+   NDNBOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
+   ++m_position;
+   //
+   // restore the flags:
+   //
+   if(restore_flags)
+   {
+      // append a case change state if we need it:
+      if(m_has_case_change)
+      {
+         static_cast<re_case*>(
+            this->append_state(syntax_element_toggle_case, sizeof(re_case))
+            )->icase = old_flags & regbase::icase;
+      }
+      this->flags(old_flags);
+   }
+   //
+   // set up the jump pointer if we have one:
+   //
+   if(jump_offset)
+   {
+      this->m_pdata->m_data.align();
+      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
+      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
+      if((this->m_last_state == jmp) && (markid != -2))
+      {
+         // Oops... we didn't have anything inside the assertion.
+         // Note we don't get here for negated forward lookahead as (?!)
+         // does have some uses.
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid or empty zero width assertion.");
+         return false;
+      }
+   }
+   //
+   // verify that if this is conditional expression, that we do have
+   // an alternative, if not add one:
+   //
+   if(markid == -4)
+   {
+      re_syntax_base* b = this->getaddress(expected_alt_point);
+      // Make sure we have exactly one alternative following this state:
+      if(b->type != syntax_element_alt)
+      {
+         re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));
+         alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);
+      }
+      else if(this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)
+      {
+         // Can't have seen more than one alternative:
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_bad_pattern, m_position - m_base, "More than one alternation operator | was encountered inside a conditional expression.");
+         return false;
+      }
+      else
+      {
+         // We must *not* have seen an alternative inside a (DEFINE) block:
+         b = this->getaddress(b->next.i, b);
+         if((b->type == syntax_element_assert_backref) && (static_cast<re_brace*>(b)->index == 9999))
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_bad_pattern, m_position - m_base, "Alternation operators are not allowed inside a DEFINE block.");
+            return false;
+         }
+      }
+      // check for invalid repetition of next state:
+      b = this->getaddress(expected_alt_point);
+      b = this->getaddress(static_cast<re_alt*>(b)->next.i, b);
+      if((b->type != syntax_element_assert_backref)
+         && (b->type != syntax_element_startmark))
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_badrepeat, m_position - m_base, "A repetition operator cannot be applied to a zero-width assertion.");
+         return false;
+      }
+   }
+   //
+   // append closing parenthesis state:
+   //
+   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
+   pb->index = markid;
+   pb->icase = this->flags() & regbase::icase;
+   this->m_paren_start = last_paren_start;
+   //
+   // restore the alternate insertion point:
+   //
+   this->m_alt_insert_point = last_alt_point;
+   //
+   // and the case change data:
+   //
+   m_has_case_change = old_case_change;
+   //
+   // And the mark_reset data:
+   //
+   if(m_max_mark > m_mark_count)
+   {
+      m_mark_count = m_max_mark;
+   }
+   m_mark_reset = mark_reset;
+   m_max_mark = max_mark;
+
+
+   if(markid > 0)
+   {
+#ifndef NDNBOOST_NO_STD_DISTANCE
+      if(this->flags() & regbase::save_subexpression_location)
+         this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position) - 1;
+#else
+      if(this->flags() & regbase::save_subexpression_location)
+         this->m_pdata->m_subs.at(markid - 1).second = (m_position - m_base) - 1;
+#endif
+      //
+      // allow backrefs to this mark:
+      //
+      if((markid > 0) && (markid < (int)(sizeof(unsigned) * CHAR_BIT)))
+         this->m_backrefs |= 1u << (markid - 1);
+   }
+   return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::add_emacs_code(bool negate)
+{
+   //
+   // parses an emacs style \sx or \Sx construct.
+   //
+   if(++m_position == m_end)
+   {
+      // Rewind to start of sequence:
+      --m_position;
+      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
+      fail(regex_constants::error_escape, m_position - m_base);
+      return false;
+   }
+   basic_char_set<charT, traits> char_set;
+   if(negate)
+      char_set.negate();
+
+   static const charT s_punct[5] = { 'p', 'u', 'n', 'c', 't', };
+
+   switch(*m_position)
+   {
+   case 's':
+   case ' ':
+      char_set.add_class(this->m_mask_space);
+      break;
+   case 'w':
+      char_set.add_class(this->m_word_mask);
+      break;
+   case '_':
+      char_set.add_single(digraph<charT>(charT('$'))); 
+      char_set.add_single(digraph<charT>(charT('&'))); 
+      char_set.add_single(digraph<charT>(charT('*'))); 
+      char_set.add_single(digraph<charT>(charT('+'))); 
+      char_set.add_single(digraph<charT>(charT('-'))); 
+      char_set.add_single(digraph<charT>(charT('_'))); 
+      char_set.add_single(digraph<charT>(charT('<'))); 
+      char_set.add_single(digraph<charT>(charT('>'))); 
+      break;
+   case '.':
+      char_set.add_class(this->m_traits.lookup_classname(s_punct, s_punct+5));
+      break;
+   case '(':
+      char_set.add_single(digraph<charT>(charT('('))); 
+      char_set.add_single(digraph<charT>(charT('['))); 
+      char_set.add_single(digraph<charT>(charT('{'))); 
+      break;
+   case ')':
+      char_set.add_single(digraph<charT>(charT(')'))); 
+      char_set.add_single(digraph<charT>(charT(']'))); 
+      char_set.add_single(digraph<charT>(charT('}'))); 
+      break;
+   case '"':
+      char_set.add_single(digraph<charT>(charT('"'))); 
+      char_set.add_single(digraph<charT>(charT('\''))); 
+      char_set.add_single(digraph<charT>(charT('`'))); 
+      break;
+   case '\'':
+      char_set.add_single(digraph<charT>(charT('\''))); 
+      char_set.add_single(digraph<charT>(charT(','))); 
+      char_set.add_single(digraph<charT>(charT('#'))); 
+      break;
+   case '<':
+      char_set.add_single(digraph<charT>(charT(';'))); 
+      break;
+   case '>':
+      char_set.add_single(digraph<charT>(charT('\n'))); 
+      char_set.add_single(digraph<charT>(charT('\f'))); 
+      break;
+   default:
+      fail(regex_constants::error_ctype, m_position - m_base);
+      return false;
+   }
+   if(0 == this->append_set(char_set))
+   {
+      fail(regex_constants::error_ctype, m_position - m_base);
+      return false;
+   }
+   ++m_position;
+   return true;
+}
+
+template <class charT, class traits>
+regex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()
+{
+   // we have a (?imsx-imsx) group, convert it into a set of flags:
+   regex_constants::syntax_option_type f = this->flags();
+   bool breakout = false;
+   do
+   {
+      switch(*m_position)
+      {
+      case 's':
+         f |= regex_constants::mod_s;
+         f &= ~regex_constants::no_mod_s;
+         break;
+      case 'm':
+         f &= ~regex_constants::no_mod_m;
+         break;
+      case 'i':
+         f |= regex_constants::icase;
+         break;
+      case 'x':
+         f |= regex_constants::mod_x;
+         break;
+      default:
+         breakout = true;
+         continue;
+      }
+      if(++m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_paren, m_position - m_base);
+         return false;
+      }
+   }
+   while(!breakout);
+   
+   breakout = false;
+
+   if(*m_position == static_cast<charT>('-'))
+   {
+      if(++m_position == m_end)
+      {
+         // Rewind to start of (? sequence:
+         --m_position;
+         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+         fail(regex_constants::error_paren, m_position - m_base);
+         return false;
+      }
+      do
+      {
+         switch(*m_position)
+         {
+         case 's':
+            f &= ~regex_constants::mod_s;
+            f |= regex_constants::no_mod_s;
+            break;
+         case 'm':
+            f |= regex_constants::no_mod_m;
+            break;
+         case 'i':
+            f &= ~regex_constants::icase;
+            break;
+         case 'x':
+            f &= ~regex_constants::mod_x;
+            break;
+         default:
+            breakout = true;
+            continue;
+         }
+         if(++m_position == m_end)
+         {
+            // Rewind to start of (? sequence:
+            --m_position;
+            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
+            fail(regex_constants::error_paren, m_position - m_base);
+            return false;
+         }
+      }
+      while(!breakout);
+   }
+   return f;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::unwind_alts(std::ptrdiff_t last_paren_start)
+{
+   //
+   // If we didn't actually add any states after the last 
+   // alternative then that's an error:
+   //
+   if((this->m_alt_insert_point == static_cast<std::ptrdiff_t>(this->m_pdata->m_data.size()))
+      && m_alt_jumps.size() && (m_alt_jumps.back() > last_paren_start)
+      &&
+      !(
+         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
+           &&
+         ((this->flags() & regbase::no_empty_expressions) == 0)
+        )
+      )
+   {
+      fail(regex_constants::error_empty, this->m_position - this->m_base, "Can't terminate a sub-expression with an alternation operator |.");
+      return false;
+   }
+   // 
+   // Fix up our alternatives:
+   //
+   while(m_alt_jumps.size() && (m_alt_jumps.back() > last_paren_start))
+   {
+      //
+      // fix up the jump to point to the end of the states
+      // that we've just added:
+      //
+      std::ptrdiff_t jump_offset = m_alt_jumps.back();
+      m_alt_jumps.pop_back();
+      this->m_pdata->m_data.align();
+      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
+      NDNBOOST_ASSERT(jmp->type == syntax_element_jump);
+      jmp->alt.i = this->m_pdata->m_data.size() - jump_offset;
+   }
+   return true;
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace re_detail
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/ndnboost/regex/v4/c_regex_traits.hpp b/include/ndnboost/regex/v4/c_regex_traits.hpp
new file mode 100644
index 0000000..62add91
--- /dev/null
+++ b/include/ndnboost/regex/v4/c_regex_traits.hpp
@@ -0,0 +1,211 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         c_regex_traits.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression traits class that wraps the global C locale.
+  */
+
+#ifndef NDNBOOST_C_REGEX_TRAITS_HPP_INCLUDED
+#define NDNBOOST_C_REGEX_TRAITS_HPP_INCLUDED
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_WORKAROUND_HPP
+#include <ndnboost/regex/v4/regex_workaround.hpp>
+#endif
+
+#include <cctype>
+
+#ifdef NDNBOOST_NO_STDC_NAMESPACE
+namespace std{
+   using ::strlen; using ::tolower;
+}
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+
+template <class charT>
+struct c_regex_traits;
+
+template<>
+struct NDNBOOST_REGEX_DECL c_regex_traits<char>
+{
+   c_regex_traits(){}
+   typedef char char_type;
+   typedef std::size_t size_type;
+   typedef std::string string_type;
+   struct locale_type{};
+   typedef ndnboost::uint32_t char_class_type;
+
+   static size_type length(const char_type* p) 
+   { 
+      return (std::strlen)(p); 
+   }
+
+   char translate(char c) const 
+   { 
+      return c; 
+   }
+   char translate_nocase(char c) const 
+   { 
+      return static_cast<char>((std::tolower)(static_cast<unsigned char>(c))); 
+   }
+
+   static string_type NDNBOOST_REGEX_CALL transform(const char* p1, const char* p2);
+   static string_type NDNBOOST_REGEX_CALL transform_primary(const char* p1, const char* p2);
+
+   static char_class_type NDNBOOST_REGEX_CALL lookup_classname(const char* p1, const char* p2);
+   static string_type NDNBOOST_REGEX_CALL lookup_collatename(const char* p1, const char* p2);
+
+   static bool NDNBOOST_REGEX_CALL isctype(char, char_class_type);
+   static int NDNBOOST_REGEX_CALL value(char, int);
+
+   locale_type imbue(locale_type l)
+   { return l; }
+   locale_type getloc()const
+   { return locale_type(); }
+
+private:
+   // this type is not copyable:
+   c_regex_traits(const c_regex_traits&);
+   c_regex_traits& operator=(const c_regex_traits&);
+};
+
+#ifndef NDNBOOST_NO_WREGEX
+template<>
+struct NDNBOOST_REGEX_DECL c_regex_traits<wchar_t>
+{
+   c_regex_traits(){}
+   typedef wchar_t char_type;
+   typedef std::size_t size_type;
+   typedef std::wstring string_type;
+   struct locale_type{};
+   typedef ndnboost::uint32_t char_class_type;
+
+   static size_type length(const char_type* p) 
+   { 
+      return (std::wcslen)(p); 
+   }
+
+   wchar_t translate(wchar_t c) const 
+   { 
+      return c; 
+   }
+   wchar_t translate_nocase(wchar_t c) const 
+   { 
+      return (std::towlower)(c); 
+   }
+
+   static string_type NDNBOOST_REGEX_CALL transform(const wchar_t* p1, const wchar_t* p2);
+   static string_type NDNBOOST_REGEX_CALL transform_primary(const wchar_t* p1, const wchar_t* p2);
+
+   static char_class_type NDNBOOST_REGEX_CALL lookup_classname(const wchar_t* p1, const wchar_t* p2);
+   static string_type NDNBOOST_REGEX_CALL lookup_collatename(const wchar_t* p1, const wchar_t* p2);
+
+   static bool NDNBOOST_REGEX_CALL isctype(wchar_t, char_class_type);
+   static int NDNBOOST_REGEX_CALL value(wchar_t, int);
+
+   locale_type imbue(locale_type l)
+   { return l; }
+   locale_type getloc()const
+   { return locale_type(); }
+
+private:
+   // this type is not copyable:
+   c_regex_traits(const c_regex_traits&);
+   c_regex_traits& operator=(const c_regex_traits&);
+};
+
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+//
+// Provide an unsigned short version as well, so the user can link to this
+// no matter whether they build with /Zc:wchar_t or not (MSVC specific).
+//
+template<>
+struct NDNBOOST_REGEX_DECL c_regex_traits<unsigned short>
+{
+   c_regex_traits(){}
+   typedef unsigned short char_type;
+   typedef std::size_t size_type;
+   typedef std::basic_string<unsigned short> string_type;
+   struct locale_type{};
+   typedef ndnboost::uint32_t char_class_type;
+
+   static size_type length(const char_type* p) 
+   { 
+      return (std::wcslen)((const wchar_t*)p); 
+   }
+
+   unsigned short translate(unsigned short c) const 
+   { 
+      return c; 
+   }
+   unsigned short translate_nocase(unsigned short c) const 
+   { 
+      return (std::towlower)((wchar_t)c); 
+   }
+
+   static string_type NDNBOOST_REGEX_CALL transform(const unsigned short* p1, const unsigned short* p2);
+   static string_type NDNBOOST_REGEX_CALL transform_primary(const unsigned short* p1, const unsigned short* p2);
+
+   static char_class_type NDNBOOST_REGEX_CALL lookup_classname(const unsigned short* p1, const unsigned short* p2);
+   static string_type NDNBOOST_REGEX_CALL lookup_collatename(const unsigned short* p1, const unsigned short* p2);
+
+   static bool NDNBOOST_REGEX_CALL isctype(unsigned short, char_class_type);
+   static int NDNBOOST_REGEX_CALL value(unsigned short, int);
+
+   locale_type imbue(locale_type l)
+   { return l; }
+   locale_type getloc()const
+   { return locale_type(); }
+
+private:
+   // this type is not copyable:
+   c_regex_traits(const c_regex_traits&);
+   c_regex_traits& operator=(const c_regex_traits&);
+};
+
+#endif
+
+#endif // NDNBOOST_NO_WREGEX
+
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
+
diff --git a/include/ndnboost/regex/v4/char_regex_traits.hpp b/include/ndnboost/regex/v4/char_regex_traits.hpp
new file mode 100644
index 0000000..e5e5228
--- /dev/null
+++ b/include/ndnboost/regex/v4/char_regex_traits.hpp
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         char_regex_traits.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares deprecated traits classes char_regex_traits<>.
+  */
+
+
+#ifndef NDNBOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
+#define NDNBOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+
+namespace deprecated{
+//
+// class char_regex_traits_i
+// provides case insensitive traits classes (deprecated):
+template <class charT>
+class char_regex_traits_i : public regex_traits<charT> {};
+
+template<>
+class char_regex_traits_i<char> : public regex_traits<char>
+{
+public:
+   typedef char char_type;
+   typedef unsigned char uchar_type;
+   typedef unsigned int size_type;
+   typedef regex_traits<char> base_type;
+
+};
+
+#ifndef NDNBOOST_NO_WREGEX
+template<>
+class char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>
+{
+public:
+   typedef wchar_t char_type;
+   typedef unsigned short uchar_type;
+   typedef unsigned int size_type;
+   typedef regex_traits<wchar_t> base_type;
+
+};
+#endif
+} // namespace deprecated
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // include
+
diff --git a/include/ndnboost/regex/v4/cpp_regex_traits.hpp b/include/ndnboost/regex/v4/cpp_regex_traits.hpp
new file mode 100644
index 0000000..5ec8657
--- /dev/null
+++ b/include/ndnboost/regex/v4/cpp_regex_traits.hpp
@@ -0,0 +1,1099 @@
+/*
+ *
+ * Copyright (c) 2004 John Maddock
+ * Copyright 2011 Garmin Ltd. or its subsidiaries
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         cpp_regex_traits.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
+  */
+
+#ifndef NDNBOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
+#define NDNBOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/integer.hpp>
+
+#ifndef NDNBOOST_NO_STD_LOCALE
+
+#ifndef NDNBOOST_RE_PAT_EXCEPT_HPP
+#include <ndnboost/regex/pattern_except.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#include <ndnboost/regex/v4/regex_traits_defaults.hpp>
+#endif
+#ifdef NDNBOOST_HAS_THREADS
+#include <ndnboost/regex/pending/static_mutex.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_PRIMARY_TRANSFORM
+#include <ndnboost/regex/v4/primary_transform.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_OBJECT_CACHE_HPP
+#include <ndnboost/regex/pending/object_cache.hpp>
+#endif
+
+#include <istream>
+#include <ios>
+#include <climits>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4786 4251)
+#endif
+
+namespace ndnboost{ 
+
+//
+// forward declaration is needed by some compilers:
+//
+template <class charT>
+class cpp_regex_traits;
+   
+namespace re_detail{
+
+//
+// class parser_buf:
+// acts as a stream buffer which wraps around a pair of pointers:
+//
+template <class charT,
+          class traits = ::std::char_traits<charT> >
+class parser_buf : public ::std::basic_streambuf<charT, traits>
+{
+   typedef ::std::basic_streambuf<charT, traits> base_type;
+   typedef typename base_type::int_type int_type;
+   typedef typename base_type::char_type char_type;
+   typedef typename base_type::pos_type pos_type;
+   typedef ::std::streamsize streamsize;
+   typedef typename base_type::off_type off_type;
+public:
+   parser_buf() : base_type() { setbuf(0, 0); }
+   const charT* getnext() { return this->gptr(); }
+protected:
+   std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
+   typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
+   typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
+private:
+   parser_buf& operator=(const parser_buf&);
+   parser_buf(const parser_buf&);
+};
+
+template<class charT, class traits>
+std::basic_streambuf<charT, traits>*
+parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
+{
+   this->setg(s, s, s + n);
+   return this;
+}
+
+template<class charT, class traits>
+typename parser_buf<charT, traits>::pos_type
+parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
+{
+   typedef typename ndnboost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
+
+   if(which & ::std::ios_base::out)
+      return pos_type(off_type(-1));
+   std::ptrdiff_t size = this->egptr() - this->eback();
+   std::ptrdiff_t pos = this->gptr() - this->eback();
+   charT* g = this->eback();
+   switch(static_cast<cast_type>(way))
+   {
+   case ::std::ios_base::beg:
+      if((off < 0) || (off > size))
+         return pos_type(off_type(-1));
+      else
+         this->setg(g, g + off, g + size);
+      break;
+   case ::std::ios_base::end:
+      if((off < 0) || (off > size))
+         return pos_type(off_type(-1));
+      else
+         this->setg(g, g + size - off, g + size);
+      break;
+   case ::std::ios_base::cur:
+   {
+      std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
+      if((newpos < 0) || (newpos > size))
+         return pos_type(off_type(-1));
+      else
+         this->setg(g, g + newpos, g + size);
+      break;
+   }
+   default: ;
+   }
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244)
+#endif
+   return static_cast<pos_type>(this->gptr() - this->eback());
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template<class charT, class traits>
+typename parser_buf<charT, traits>::pos_type
+parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
+{
+   if(which & ::std::ios_base::out)
+      return pos_type(off_type(-1));
+   off_type size = static_cast<off_type>(this->egptr() - this->eback());
+   charT* g = this->eback();
+   if(off_type(sp) <= size)
+   {
+      this->setg(g, g + off_type(sp), g + size);
+   }
+   return pos_type(off_type(-1));
+}
+
+//
+// class cpp_regex_traits_base:
+// acts as a container for locale and the facets we are using.
+//
+template <class charT>
+struct cpp_regex_traits_base
+{
+   cpp_regex_traits_base(const std::locale& l)
+   { imbue(l); }
+   std::locale imbue(const std::locale& l);
+
+   std::locale m_locale;
+   std::ctype<charT> const* m_pctype;
+#ifndef NDNBOOST_NO_STD_MESSAGES
+   std::messages<charT> const* m_pmessages;
+#endif
+   std::collate<charT> const* m_pcollate;
+
+   bool operator<(const cpp_regex_traits_base& b)const
+   {
+      if(m_pctype == b.m_pctype)
+      {
+#ifndef NDNBOOST_NO_STD_MESSAGES
+         if(m_pmessages == b.m_pmessages)
+         {
+            return m_pcollate < b.m_pcollate;
+         }
+         return m_pmessages < b.m_pmessages;
+#else
+         return m_pcollate < b.m_pcollate;
+#endif
+      }
+      return m_pctype < b.m_pctype;
+   }
+   bool operator==(const cpp_regex_traits_base& b)const
+   {
+      return (m_pctype == b.m_pctype) 
+#ifndef NDNBOOST_NO_STD_MESSAGES
+         && (m_pmessages == b.m_pmessages) 
+#endif
+         && (m_pcollate == b.m_pcollate);
+   }
+};
+
+template <class charT>
+std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
+{
+   std::locale result(m_locale);
+   m_locale = l;
+   m_pctype = &NDNBOOST_USE_FACET(std::ctype<charT>, l);
+#ifndef NDNBOOST_NO_STD_MESSAGES
+   m_pmessages = NDNBOOST_HAS_FACET(std::messages<charT>, l) ? &NDNBOOST_USE_FACET(std::messages<charT>, l) : 0;
+#endif
+   m_pcollate = &NDNBOOST_USE_FACET(std::collate<charT>, l);
+   return result;
+}
+
+//
+// class cpp_regex_traits_char_layer:
+// implements methods that require specialisation for narrow characters:
+//
+template <class charT>
+class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
+{
+   typedef std::basic_string<charT> string_type;
+   typedef std::map<charT, regex_constants::syntax_type> map_type;
+   typedef typename map_type::const_iterator map_iterator_type;
+public:
+   cpp_regex_traits_char_layer(const std::locale& l)
+      : cpp_regex_traits_base<charT>(l)
+   {
+      init();
+   }
+   cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
+      : cpp_regex_traits_base<charT>(b)
+   {
+      init();
+   }
+   void init();
+
+   regex_constants::syntax_type syntax_type(charT c)const
+   {
+      map_iterator_type i = m_char_map.find(c);
+      return ((i == m_char_map.end()) ? 0 : i->second);
+   }
+   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+   {
+      map_iterator_type i = m_char_map.find(c);
+      if(i == m_char_map.end())
+      {
+         if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
+         if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
+         return 0;
+      }
+      return i->second;
+   }
+
+private:
+   string_type get_default_message(regex_constants::syntax_type);
+   // TODO: use a hash table when available!
+   map_type m_char_map;
+};
+
+template <class charT>
+void cpp_regex_traits_char_layer<charT>::init()
+{
+   // we need to start by initialising our syntax map so we know which
+   // character is used for which purpose:
+#ifndef NDNBOOST_NO_STD_MESSAGES
+#ifndef __IBMCPP__
+   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
+#else
+   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
+#endif
+   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
+   if(cat_name.size() && (this->m_pmessages != 0))
+   {
+      cat = this->m_pmessages->open(
+         cat_name, 
+         this->m_locale);
+      if((int)cat < 0)
+      {
+         std::string m("Unable to open message catalog: ");
+         std::runtime_error err(m + cat_name);
+         ndnboost::re_detail::raise_runtime_error(err);
+      }
+   }
+   //
+   // if we have a valid catalog then load our messages:
+   //
+   if((int)cat >= 0)
+   {
+#ifndef NDNBOOST_NO_EXCEPTIONS
+      try{
+#endif
+         for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+         {
+            string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
+            for(typename string_type::size_type j = 0; j < mss.size(); ++j)
+            {
+               m_char_map[mss[j]] = i;
+            }
+         }
+         this->m_pmessages->close(cat);
+#ifndef NDNBOOST_NO_EXCEPTIONS
+      }
+      catch(...)
+      {
+         if(this->m_pmessages)
+            this->m_pmessages->close(cat);
+         throw;
+      }
+#endif
+   }
+   else
+   {
+#endif
+      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+      {
+         const char* ptr = get_default_syntax(i);
+         while(ptr && *ptr)
+         {
+            m_char_map[this->m_pctype->widen(*ptr)] = i;
+            ++ptr;
+         }
+      }
+#ifndef NDNBOOST_NO_STD_MESSAGES
+   }
+#endif
+}
+
+template <class charT>
+typename cpp_regex_traits_char_layer<charT>::string_type 
+   cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
+{
+   const char* ptr = get_default_syntax(i);
+   string_type result;
+   while(ptr && *ptr)
+   {
+      result.append(1, this->m_pctype->widen(*ptr));
+      ++ptr;
+   }
+   return result;
+}
+
+//
+// specialised version for narrow characters:
+//
+template <>
+class NDNBOOST_REGEX_DECL cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
+{
+   typedef std::string string_type;
+public:
+   cpp_regex_traits_char_layer(const std::locale& l)
+   : cpp_regex_traits_base<char>(l)
+   {
+      init();
+   }
+   cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
+   : cpp_regex_traits_base<char>(l)
+   {
+      init();
+   }
+
+   regex_constants::syntax_type syntax_type(char c)const
+   {
+      return m_char_map[static_cast<unsigned char>(c)];
+   }
+   regex_constants::escape_syntax_type escape_syntax_type(char c) const
+   {
+      return m_char_map[static_cast<unsigned char>(c)];
+   }
+
+private:
+   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
+   void init();
+};
+
+#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+enum
+{
+   char_class_space=1<<0, 
+   char_class_print=1<<1, 
+   char_class_cntrl=1<<2, 
+   char_class_upper=1<<3, 
+   char_class_lower=1<<4,
+   char_class_alpha=1<<5, 
+   char_class_digit=1<<6, 
+   char_class_punct=1<<7, 
+   char_class_xdigit=1<<8,
+   char_class_alnum=char_class_alpha|char_class_digit, 
+   char_class_graph=char_class_alnum|char_class_punct,
+   char_class_blank=1<<9,
+   char_class_word=1<<10,
+   char_class_unicode=1<<11,
+   char_class_horizontal_space=1<<12,
+   char_class_vertical_space=1<<13
+};
+
+#endif
+
+//
+// class cpp_regex_traits_implementation:
+// provides pimpl implementation for cpp_regex_traits.
+//
+template <class charT>
+class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
+{
+public:
+   typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
+   typedef typename std::ctype<charT>::mask                  native_mask_type;
+#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 1u << 27);
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 1u << 28);
+#endif
+
+   typedef std::basic_string<charT> string_type;
+   typedef charT char_type;
+   //cpp_regex_traits_implementation();
+   cpp_regex_traits_implementation(const std::locale& l)
+      : cpp_regex_traits_char_layer<charT>(l)
+   {
+      init();
+   }
+   cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
+      : cpp_regex_traits_char_layer<charT>(l)
+   {
+      init();
+   }
+   std::string error_string(regex_constants::error_type n) const
+   {
+      if(!m_error_strings.empty())
+      {
+         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
+         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
+      }
+      return get_default_error_string(n);
+   }
+   char_class_type lookup_classname(const charT* p1, const charT* p2) const
+   {
+      char_class_type result = lookup_classname_imp(p1, p2);
+      if(result == 0)
+      {
+         string_type temp(p1, p2);
+         this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
+         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
+      }
+      return result;
+   }
+   string_type lookup_collatename(const charT* p1, const charT* p2) const;
+   string_type transform_primary(const charT* p1, const charT* p2) const;
+   string_type transform(const charT* p1, const charT* p2) const;
+private:
+   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID
+   std::map<string_type, char_class_type>  m_custom_class_names; // character class names
+   std::map<string_type, string_type>      m_custom_collate_names; // collating element names
+   unsigned                       m_collate_type;    // the form of the collation string
+   charT                          m_collate_delim;   // the collation group delimiter
+   //
+   // helpers:
+   //
+   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
+   void init();
+#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+public:
+   bool isctype(charT c, char_class_type m)const;
+#endif
+};
+
+#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+#if !defined(NDNBOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;
+
+#endif
+#endif
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::string_type 
+   cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
+{
+   //
+   // PRECONDITIONS:
+   //
+   // A bug in gcc 3.2 (and maybe other versions as well) treats
+   // p1 as a null terminated string, for efficiency reasons 
+   // we work around this elsewhere, but just assert here that
+   // we adhere to gcc's (buggy) preconditions...
+   //
+   NDNBOOST_ASSERT(*p2 == 0);
+
+   string_type result;
+   //
+   // swallowing all exceptions here is a bad idea
+   // however at least one std lib will always throw
+   // std::bad_alloc for certain arguments...
+   //
+#ifndef NDNBOOST_NO_EXCEPTIONS
+   try{
+#endif
+      //
+      // What we do here depends upon the format of the sort key returned by
+      // sort key returned by this->transform:
+      //
+      switch(m_collate_type)
+      {
+      case sort_C:
+      case sort_unknown:
+         // the best we can do is translate to lower case, then get a regular sort key:
+         {
+            result.assign(p1, p2);
+            this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
+            result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
+            break;
+         }
+      case sort_fixed:
+         {
+            // get a regular sort key, and then truncate it:
+            result.assign(this->m_pcollate->transform(p1, p2));
+            result.erase(this->m_collate_delim);
+            break;
+         }
+      case sort_delim:
+            // get a regular sort key, and then truncate everything after the delim:
+            result.assign(this->m_pcollate->transform(p1, p2));
+            std::size_t i;
+            for(i = 0; i < result.size(); ++i)
+            {
+               if(result[i] == m_collate_delim)
+                  break;
+            }
+            result.erase(i);
+            break;
+      }
+#ifndef NDNBOOST_NO_EXCEPTIONS
+   }catch(...){}
+#endif
+   while(result.size() && (charT(0) == *result.rbegin()))
+      result.erase(result.size() - 1);
+   if(result.empty())
+   {
+      // character is ignorable at the primary level:
+      result = string_type(1, charT(0));
+   }
+   return result;
+}
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::string_type 
+   cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
+{
+   //
+   // PRECONDITIONS:
+   //
+   // A bug in gcc 3.2 (and maybe other versions as well) treats
+   // p1 as a null terminated string, for efficiency reasons 
+   // we work around this elsewhere, but just assert here that
+   // we adhere to gcc's (buggy) preconditions...
+   //
+   NDNBOOST_ASSERT(*p2 == 0);
+   //
+   // swallowing all exceptions here is a bad idea
+   // however at least one std lib will always throw
+   // std::bad_alloc for certain arguments...
+   //
+   string_type result;
+#ifndef NDNBOOST_NO_EXCEPTIONS
+   try{
+#endif
+      result = this->m_pcollate->transform(p1, p2);
+      //
+      // Borland's STLPort version returns a NULL-terminated
+      // string that has garbage at the end - each call to
+      // std::collate<wchar_t>::transform returns a different string!
+      // So as a workaround, we'll truncate the string at the first NULL
+      // which _seems_ to work....
+#if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x580)
+      result.erase(result.find(charT(0)));
+#else
+      //
+      // some implementations (Dinkumware) append unnecessary trailing \0's:
+      while(result.size() && (charT(0) == *result.rbegin()))
+         result.erase(result.size() - 1);
+#endif
+      NDNBOOST_ASSERT(std::find(result.begin(), result.end(), charT(0)) == result.end());
+#ifndef NDNBOOST_NO_EXCEPTIONS
+   }
+   catch(...)
+   {
+   }
+#endif
+   return result;
+}
+
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::string_type 
+   cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
+{
+   typedef typename std::map<string_type, string_type>::const_iterator iter_type;
+   if(m_custom_collate_names.size())
+   {
+      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
+      if(pos != m_custom_collate_names.end())
+         return pos->second;
+   }
+#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)\
+               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+   std::string name(p1, p2);
+#else
+   std::string name;
+   const charT* p0 = p1;
+   while(p0 != p2)
+      name.append(1, char(*p0++));
+#endif
+   name = lookup_default_collate_name(name);
+#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)\
+               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+   if(name.size())
+      return string_type(name.begin(), name.end());
+#else
+   if(name.size())
+   {
+      string_type result;
+      typedef std::string::const_iterator iter;
+      iter b = name.begin();
+      iter e = name.end();
+      while(b != e)
+         result.append(1, charT(*b++));
+      return result;
+   }
+#endif
+   if(p2 - p1 == 1)
+      return string_type(1, *p1);
+   return string_type();
+}
+
+template <class charT>
+void cpp_regex_traits_implementation<charT>::init()
+{
+#ifndef NDNBOOST_NO_STD_MESSAGES
+#ifndef __IBMCPP__
+   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
+#else
+   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
+#endif
+   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
+   if(cat_name.size() && (this->m_pmessages != 0))
+   {
+      cat = this->m_pmessages->open(
+         cat_name, 
+         this->m_locale);
+      if((int)cat < 0)
+      {
+         std::string m("Unable to open message catalog: ");
+         std::runtime_error err(m + cat_name);
+         ndnboost::re_detail::raise_runtime_error(err);
+      }
+   }
+   //
+   // if we have a valid catalog then load our messages:
+   //
+   if((int)cat >= 0)
+   {
+      //
+      // Error messages:
+      //
+      for(ndnboost::regex_constants::error_type i = static_cast<ndnboost::regex_constants::error_type>(0); 
+         i <= ndnboost::regex_constants::error_unknown; 
+         i = static_cast<ndnboost::regex_constants::error_type>(i + 1))
+      {
+         const char* p = get_default_error_string(i);
+         string_type default_message;
+         while(*p)
+         {
+            default_message.append(1, this->m_pctype->widen(*p));
+            ++p;
+         }
+         string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
+         std::string result;
+         for(std::string::size_type j = 0; j < s.size(); ++j)
+         {
+            result.append(1, this->m_pctype->narrow(s[j], 0));
+         }
+         m_error_strings[i] = result;
+      }
+      //
+      // Custom class names:
+      //
+#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+      static const char_class_type masks[16] = 
+      {
+         std::ctype<charT>::alnum,
+         std::ctype<charT>::alpha,
+         std::ctype<charT>::cntrl,
+         std::ctype<charT>::digit,
+         std::ctype<charT>::graph,
+         cpp_regex_traits_implementation<charT>::mask_horizontal,
+         std::ctype<charT>::lower,
+         std::ctype<charT>::print,
+         std::ctype<charT>::punct,
+         std::ctype<charT>::space,
+         std::ctype<charT>::upper,
+         cpp_regex_traits_implementation<charT>::mask_vertical,
+         std::ctype<charT>::xdigit,
+         cpp_regex_traits_implementation<charT>::mask_blank,
+         cpp_regex_traits_implementation<charT>::mask_word,
+         cpp_regex_traits_implementation<charT>::mask_unicode,
+      };
+#else
+      static const char_class_type masks[16] = 
+      {
+         ::ndnboost::re_detail::char_class_alnum,
+         ::ndnboost::re_detail::char_class_alpha,
+         ::ndnboost::re_detail::char_class_cntrl,
+         ::ndnboost::re_detail::char_class_digit,
+         ::ndnboost::re_detail::char_class_graph,
+         ::ndnboost::re_detail::char_class_horizontal_space,
+         ::ndnboost::re_detail::char_class_lower,
+         ::ndnboost::re_detail::char_class_print,
+         ::ndnboost::re_detail::char_class_punct,
+         ::ndnboost::re_detail::char_class_space,
+         ::ndnboost::re_detail::char_class_upper,
+         ::ndnboost::re_detail::char_class_vertical_space,
+         ::ndnboost::re_detail::char_class_xdigit,
+         ::ndnboost::re_detail::char_class_blank,
+         ::ndnboost::re_detail::char_class_word,
+         ::ndnboost::re_detail::char_class_unicode,
+      };
+#endif
+      static const string_type null_string;
+      for(unsigned int j = 0; j <= 13; ++j)
+      {
+         string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
+         if(s.size())
+            this->m_custom_class_names[s] = masks[j];
+      }
+   }
+#endif
+   //
+   // get the collation format used by m_pcollate:
+   //
+   m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
+}
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type 
+   cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
+{
+#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+   static const char_class_type masks[22] = 
+   {
+      0,
+      std::ctype<char>::alnum, 
+      std::ctype<char>::alpha,
+      cpp_regex_traits_implementation<charT>::mask_blank,
+      std::ctype<char>::cntrl,
+      std::ctype<char>::digit,
+      std::ctype<char>::digit,
+      std::ctype<char>::graph,
+      cpp_regex_traits_implementation<charT>::mask_horizontal,
+      std::ctype<char>::lower,
+      std::ctype<char>::lower,
+      std::ctype<char>::print,
+      std::ctype<char>::punct,
+      std::ctype<char>::space,
+      std::ctype<char>::space,
+      std::ctype<char>::upper,
+      cpp_regex_traits_implementation<charT>::mask_unicode,
+      std::ctype<char>::upper,
+      cpp_regex_traits_implementation<charT>::mask_vertical,
+      std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word, 
+      std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word, 
+      std::ctype<char>::xdigit,
+   };
+#else
+   static const char_class_type masks[22] = 
+   {
+      0,
+      ::ndnboost::re_detail::char_class_alnum, 
+      ::ndnboost::re_detail::char_class_alpha,
+      ::ndnboost::re_detail::char_class_blank,
+      ::ndnboost::re_detail::char_class_cntrl,
+      ::ndnboost::re_detail::char_class_digit,
+      ::ndnboost::re_detail::char_class_digit,
+      ::ndnboost::re_detail::char_class_graph,
+      ::ndnboost::re_detail::char_class_horizontal_space,
+      ::ndnboost::re_detail::char_class_lower,
+      ::ndnboost::re_detail::char_class_lower,
+      ::ndnboost::re_detail::char_class_print,
+      ::ndnboost::re_detail::char_class_punct,
+      ::ndnboost::re_detail::char_class_space,
+      ::ndnboost::re_detail::char_class_space,
+      ::ndnboost::re_detail::char_class_upper,
+      ::ndnboost::re_detail::char_class_unicode,
+      ::ndnboost::re_detail::char_class_upper,
+      ::ndnboost::re_detail::char_class_vertical_space,
+      ::ndnboost::re_detail::char_class_alnum | ::ndnboost::re_detail::char_class_word, 
+      ::ndnboost::re_detail::char_class_alnum | ::ndnboost::re_detail::char_class_word, 
+      ::ndnboost::re_detail::char_class_xdigit,
+   };
+#endif
+   if(m_custom_class_names.size())
+   {
+      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
+      map_iter pos = m_custom_class_names.find(string_type(p1, p2));
+      if(pos != m_custom_class_names.end())
+         return pos->second;
+   }
+   std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
+   NDNBOOST_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
+   return masks[state_id];
+}
+
+#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+template <class charT>
+bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const
+{
+   return
+      ((mask & ::ndnboost::re_detail::char_class_space) && (this->m_pctype->is(std::ctype<charT>::space, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_print) && (this->m_pctype->is(std::ctype<charT>::print, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_cntrl) && (this->m_pctype->is(std::ctype<charT>::cntrl, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_upper) && (this->m_pctype->is(std::ctype<charT>::upper, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_lower) && (this->m_pctype->is(std::ctype<charT>::lower, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_alpha) && (this->m_pctype->is(std::ctype<charT>::alpha, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_digit) && (this->m_pctype->is(std::ctype<charT>::digit, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_punct) && (this->m_pctype->is(std::ctype<charT>::punct, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_xdigit) && (this->m_pctype->is(std::ctype<charT>::xdigit, c)))
+      || ((mask & ::ndnboost::re_detail::char_class_blank) && (this->m_pctype->is(std::ctype<charT>::space, c)) && !::ndnboost::re_detail::is_separator(c))
+      || ((mask & ::ndnboost::re_detail::char_class_word) && (c == '_'))
+      || ((mask & ::ndnboost::re_detail::char_class_unicode) && ::ndnboost::re_detail::is_extended(c))
+      || ((mask & ::ndnboost::re_detail::char_class_vertical_space) && (is_separator(c) || (c == '\v')))
+      || ((mask & ::ndnboost::re_detail::char_class_horizontal_space) && this->m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v')));
+}
+#endif
+
+
+template <class charT>
+inline ndnboost::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l NDNBOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
+{
+   cpp_regex_traits_base<charT> key(l);
+   return ::ndnboost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
+}
+
+} // re_detail
+
+template <class charT>
+class cpp_regex_traits
+{
+private:
+   typedef std::ctype<charT>            ctype_type;
+public:
+   typedef charT                        char_type;
+   typedef std::size_t                  size_type;
+   typedef std::basic_string<char_type> string_type;
+   typedef std::locale                  locale_type;
+   typedef ndnboost::uint_least32_t        char_class_type;
+
+   struct boost_extensions_tag{};
+
+   cpp_regex_traits()
+      : m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
+   { }
+   static size_type length(const char_type* p)
+   {
+      return std::char_traits<charT>::length(p);
+   }
+   regex_constants::syntax_type syntax_type(charT c)const
+   {
+      return m_pimpl->syntax_type(c);
+   }
+   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+   {
+      return m_pimpl->escape_syntax_type(c);
+   }
+   charT translate(charT c) const
+   {
+      return c;
+   }
+   charT translate_nocase(charT c) const
+   {
+      return m_pimpl->m_pctype->tolower(c);
+   }
+   charT translate(charT c, bool icase) const
+   {
+      return icase ? m_pimpl->m_pctype->tolower(c) : c;
+   }
+   charT tolower(charT c) const
+   {
+      return m_pimpl->m_pctype->tolower(c);
+   }
+   charT toupper(charT c) const
+   {
+      return m_pimpl->m_pctype->toupper(c);
+   }
+   string_type transform(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->transform(p1, p2);
+   }
+   string_type transform_primary(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->transform_primary(p1, p2);
+   }
+   char_class_type lookup_classname(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->lookup_classname(p1, p2);
+   }
+   string_type lookup_collatename(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->lookup_collatename(p1, p2);
+   }
+   bool isctype(charT c, char_class_type f) const
+   {
+#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+      typedef typename std::ctype<charT>::mask ctype_mask;
+
+      static const ctype_mask mask_base = 
+         static_cast<ctype_mask>(
+            std::ctype<charT>::alnum 
+            | std::ctype<charT>::alpha
+            | std::ctype<charT>::cntrl
+            | std::ctype<charT>::digit
+            | std::ctype<charT>::graph
+            | std::ctype<charT>::lower
+            | std::ctype<charT>::print
+            | std::ctype<charT>::punct
+            | std::ctype<charT>::space
+            | std::ctype<charT>::upper
+            | std::ctype<charT>::xdigit);
+
+      if((f & mask_base) 
+         && (m_pimpl->m_pctype->is(
+            static_cast<ctype_mask>(f & mask_base), c)))
+         return true;
+      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
+         return true;
+      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
+         return true;
+      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_blank) 
+         && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
+         && !re_detail::is_separator(c))
+         return true;
+      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_vertical) 
+         && (::ndnboost::re_detail::is_separator(c) || (c == '\v')))
+         return true;
+      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_horizontal) 
+         && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, re_detail::cpp_regex_traits_implementation<charT>::mask_vertical))
+         return true;
+      return false;
+#else
+      return m_pimpl->isctype(c, f);
+#endif
+   }
+   int toi(const charT*& p1, const charT* p2, int radix)const;
+   int value(charT c, int radix)const
+   {
+      const charT* pc = &c;
+      return toi(pc, pc + 1, radix);
+   }
+   locale_type imbue(locale_type l)
+   {
+      std::locale result(getloc());
+      m_pimpl = re_detail::create_cpp_regex_traits<charT>(l);
+      return result;
+   }
+   locale_type getloc()const
+   {
+      return m_pimpl->m_locale;
+   }
+   std::string error_string(regex_constants::error_type n) const
+   {
+      return m_pimpl->error_string(n);
+   }
+
+   //
+   // extension:
+   // set the name of the message catalog in use (defaults to "boost_regex").
+   //
+   static std::string catalog_name(const std::string& name);
+   static std::string get_catalog_name();
+
+private:
+   ndnboost::shared_ptr<const re_detail::cpp_regex_traits_implementation<charT> > m_pimpl;
+   //
+   // catalog name handler:
+   //
+   static std::string& get_catalog_name_inst();
+
+#ifdef NDNBOOST_HAS_THREADS
+   static static_mutex& get_mutex_inst();
+#endif
+};
+
+
+template <class charT>
+int cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
+{
+   re_detail::parser_buf<charT>   sbuf;            // buffer for parsing numbers.
+   std::basic_istream<charT>      is(&sbuf);       // stream for parsing numbers.
+
+   // we do NOT want to parse any thousands separators inside the stream:
+   last = std::find(first, last, NDNBOOST_USE_FACET(std::numpunct<charT>, is.getloc()).thousands_sep());
+
+   sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
+   is.clear();
+   if(std::abs(radix) == 16) is >> std::hex;
+   else if(std::abs(radix) == 8) is >> std::oct;
+   else is >> std::dec;
+   int val;
+   if(is >> val)
+   {
+      first = first + ((last - first) - sbuf.in_avail());
+      return val;
+   }
+   else
+      return -1;
+}
+
+template <class charT>
+std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
+{
+#ifdef NDNBOOST_HAS_THREADS
+   static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+   std::string result(get_catalog_name_inst());
+   get_catalog_name_inst() = name;
+   return result;
+}
+
+template <class charT>
+std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
+{
+   static std::string s_name;
+   return s_name;
+}
+
+template <class charT>
+std::string cpp_regex_traits<charT>::get_catalog_name()
+{
+#ifdef NDNBOOST_HAS_THREADS
+   static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+   std::string result(get_catalog_name_inst());
+   return result;
+}
+
+#ifdef NDNBOOST_HAS_THREADS
+template <class charT>
+static_mutex& cpp_regex_traits<charT>::get_mutex_inst()
+{
+   static static_mutex s_mutex = NDNBOOST_STATIC_MUTEX_INIT;
+   return s_mutex;
+}
+#endif
+
+
+} // boost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+#endif
+
+
diff --git a/include/ndnboost/regex/v4/cregex.hpp b/include/ndnboost/regex/v4/cregex.hpp
new file mode 100644
index 0000000..bfe61f0
--- /dev/null
+++ b/include/ndnboost/regex/v4/cregex.hpp
@@ -0,0 +1,330 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         cregex.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares POSIX API functions
+  *                + ndnboost::RegEx high level wrapper.
+  */
+
+#ifndef NDNBOOST_RE_CREGEX_HPP_INCLUDED
+#define NDNBOOST_RE_CREGEX_HPP_INCLUDED
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+#include <ndnboost/regex/v4/match_flags.hpp>
+#include <ndnboost/regex/v4/error_type.hpp>
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+/* include these defs only for POSIX compatablity */
+#ifdef __cplusplus
+namespace ndnboost{
+extern "C" {
+#endif
+
+#if defined(__cplusplus) && !defined(NDNBOOST_NO_STDC_NAMESPACE)
+typedef std::ptrdiff_t regoff_t;
+typedef std::size_t regsize_t;
+#else
+typedef ptrdiff_t regoff_t;
+typedef size_t regsize_t;
+#endif
+
+typedef struct
+{
+   unsigned int re_magic;
+#ifdef __cplusplus
+   std::size_t  re_nsub;      /* number of parenthesized subexpressions */
+#else
+   size_t re_nsub; 
+#endif
+   const char*  re_endp;       /* end pointer for REG_PEND */
+   void* guts;                /* none of your business :-) */
+   match_flag_type eflags;        /* none of your business :-) */
+} regex_tA;
+
+#ifndef NDNBOOST_NO_WREGEX
+typedef struct
+{
+   unsigned int re_magic;
+#ifdef __cplusplus
+   std::size_t  re_nsub;         /* number of parenthesized subexpressions */
+#else
+   size_t re_nsub;
+#endif
+   const wchar_t* re_endp;       /* end pointer for REG_PEND */
+   void* guts;                   /* none of your business :-) */
+   match_flag_type eflags;           /* none of your business :-) */
+} regex_tW;
+#endif
+
+typedef struct
+{
+   regoff_t rm_so;      /* start of match */
+   regoff_t rm_eo;      /* end of match */
+} regmatch_t;
+
+/* regcomp() flags */
+typedef enum{
+   REG_BASIC = 0000,
+   REG_EXTENDED = 0001,
+   REG_ICASE = 0002,
+   REG_NOSUB = 0004,
+   REG_NEWLINE = 0010,
+   REG_NOSPEC = 0020,
+   REG_PEND = 0040,
+   REG_DUMP = 0200,
+   REG_NOCOLLATE = 0400,
+   REG_ESCAPE_IN_LISTS = 01000,
+   REG_NEWLINE_ALT = 02000,
+   REG_PERLEX = 04000,
+
+   REG_PERL = REG_EXTENDED | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | REG_PERLEX,
+   REG_AWK = REG_EXTENDED | REG_ESCAPE_IN_LISTS,
+   REG_GREP = REG_BASIC | REG_NEWLINE_ALT,
+   REG_EGREP = REG_EXTENDED | REG_NEWLINE_ALT,
+
+   REG_ASSERT = 15,
+   REG_INVARG = 16,
+   REG_ATOI = 255,   /* convert name to number (!) */
+   REG_ITOA = 0400   /* convert number to name (!) */
+} reg_comp_flags;
+
+/* regexec() flags */
+typedef enum{
+   REG_NOTBOL =    00001,
+   REG_NOTEOL =    00002,
+   REG_STARTEND =  00004
+} reg_exec_flags;
+
+/*
+ * POSIX error codes:
+ */
+typedef unsigned reg_error_t;
+typedef reg_error_t reg_errcode_t;  /* backwards compatibility */
+
+static const reg_error_t REG_NOERROR = 0;   /* Success.  */
+static const reg_error_t REG_NOMATCH = 1;   /* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+static const reg_error_t REG_BADPAT = 2;    /* Invalid pattern.  */
+static const reg_error_t REG_ECOLLATE = 3;  /* Undefined collating element.  */
+static const reg_error_t REG_ECTYPE = 4;    /* Invalid character class name.  */
+static const reg_error_t REG_EESCAPE = 5;   /* Trailing backslash.  */
+static const reg_error_t REG_ESUBREG = 6;   /* Invalid back reference.  */
+static const reg_error_t REG_EBRACK = 7;    /* Unmatched left bracket.  */
+static const reg_error_t REG_EPAREN = 8;    /* Parenthesis imbalance.  */
+static const reg_error_t REG_EBRACE = 9;    /* Unmatched \{.  */
+static const reg_error_t REG_BADBR = 10;    /* Invalid contents of \{\}.  */
+static const reg_error_t REG_ERANGE = 11;   /* Invalid range end.  */
+static const reg_error_t REG_ESPACE = 12;   /* Ran out of memory.  */
+static const reg_error_t REG_BADRPT = 13;   /* No preceding re for repetition op.  */
+static const reg_error_t REG_EEND = 14;     /* unexpected end of expression */
+static const reg_error_t REG_ESIZE = 15;    /* expression too big */
+static const reg_error_t REG_ERPAREN = 8;   /* = REG_EPAREN : unmatched right parenthesis */
+static const reg_error_t REG_EMPTY = 17;    /* empty expression */
+static const reg_error_t REG_E_MEMORY = 15; /* = REG_ESIZE : out of memory */
+static const reg_error_t REG_ECOMPLEXITY = 18; /* complexity too high */
+static const reg_error_t REG_ESTACK = 19;   /* out of stack space */
+static const reg_error_t REG_E_PERL = 20;   /* Perl (?...) error */
+static const reg_error_t REG_E_UNKNOWN = 21; /* unknown error */
+static const reg_error_t REG_ENOSYS = 21;   /* = REG_E_UNKNOWN : Reserved. */
+
+NDNBOOST_REGEX_DECL int NDNBOOST_REGEX_CCALL regcompA(regex_tA*, const char*, int);
+NDNBOOST_REGEX_DECL regsize_t NDNBOOST_REGEX_CCALL regerrorA(int, const regex_tA*, char*, regsize_t);
+NDNBOOST_REGEX_DECL int NDNBOOST_REGEX_CCALL regexecA(const regex_tA*, const char*, regsize_t, regmatch_t*, int);
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CCALL regfreeA(regex_tA*);
+
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL int NDNBOOST_REGEX_CCALL regcompW(regex_tW*, const wchar_t*, int);
+NDNBOOST_REGEX_DECL regsize_t NDNBOOST_REGEX_CCALL regerrorW(int, const regex_tW*, wchar_t*, regsize_t);
+NDNBOOST_REGEX_DECL int NDNBOOST_REGEX_CCALL regexecW(const regex_tW*, const wchar_t*, regsize_t, regmatch_t*, int);
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CCALL regfreeW(regex_tW*);
+#endif
+
+#ifdef UNICODE
+#define regcomp regcompW
+#define regerror regerrorW
+#define regexec regexecW
+#define regfree regfreeW
+#define regex_t regex_tW
+#else
+#define regcomp regcompA
+#define regerror regerrorA
+#define regexec regexecA
+#define regfree regfreeA
+#define regex_t regex_tA
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+} /* namespace */
+#endif
+
+#if defined(__cplusplus)
+/*
+ * C++ high level wrapper goes here:
+ */
+#include <string>
+#include <vector>
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+class RegEx;
+
+namespace re_detail{
+
+class RegExData;
+struct pred1;
+struct pred2;
+struct pred3;
+struct pred4;
+
+}  /* namespace re_detail */
+
+#if (defined(NDNBOOST_MSVC) || defined(__BORLANDC__)) && !defined(NDNBOOST_DISABLE_WIN32)
+typedef bool (__cdecl *GrepCallback)(const RegEx& expression);
+typedef bool (__cdecl *GrepFileCallback)(const char* file, const RegEx& expression);
+typedef bool (__cdecl *FindFilesCallback)(const char* file);
+#else
+typedef bool (*GrepCallback)(const RegEx& expression);
+typedef bool (*GrepFileCallback)(const char* file, const RegEx& expression);
+typedef bool (*FindFilesCallback)(const char* file);
+#endif
+
+class NDNBOOST_REGEX_DECL RegEx
+{
+private:
+   re_detail::RegExData* pdata;
+public:
+   RegEx();
+   RegEx(const RegEx& o);
+   ~RegEx();
+   explicit RegEx(const char* c, bool icase = false);
+   explicit RegEx(const std::string& s, bool icase = false);
+   RegEx& operator=(const RegEx& o);
+   RegEx& operator=(const char* p);
+   RegEx& operator=(const std::string& s){ return this->operator=(s.c_str()); }
+   unsigned int SetExpression(const char* p, bool icase = false);
+   unsigned int SetExpression(const std::string& s, bool icase = false){ return SetExpression(s.c_str(), icase); }
+   std::string Expression()const;
+   unsigned int error_code()const;
+   /*
+    * now matching operators:
+    */
+   bool Match(const char* p, match_flag_type flags = match_default);
+   bool Match(const std::string& s, match_flag_type flags = match_default) { return Match(s.c_str(), flags); }
+   bool Search(const char* p, match_flag_type flags = match_default);
+   bool Search(const std::string& s, match_flag_type flags = match_default) { return Search(s.c_str(), flags); }
+   unsigned int Grep(GrepCallback cb, const char* p, match_flag_type flags = match_default);
+   unsigned int Grep(GrepCallback cb, const std::string& s, match_flag_type flags = match_default) { return Grep(cb, s.c_str(), flags); }
+   unsigned int Grep(std::vector<std::string>& v, const char* p, match_flag_type flags = match_default);
+   unsigned int Grep(std::vector<std::string>& v, const std::string& s, match_flag_type flags = match_default) { return Grep(v, s.c_str(), flags); }
+   unsigned int Grep(std::vector<std::size_t>& v, const char* p, match_flag_type flags = match_default);
+   unsigned int Grep(std::vector<std::size_t>& v, const std::string& s, match_flag_type flags = match_default) { return Grep(v, s.c_str(), flags); }
+#ifndef NDNBOOST_REGEX_NO_FILEITER
+   unsigned int GrepFiles(GrepFileCallback cb, const char* files, bool recurse = false, match_flag_type flags = match_default);
+   unsigned int GrepFiles(GrepFileCallback cb, const std::string& files, bool recurse = false, match_flag_type flags = match_default) { return GrepFiles(cb, files.c_str(), recurse, flags); }
+   unsigned int FindFiles(FindFilesCallback cb, const char* files, bool recurse = false, match_flag_type flags = match_default);
+   unsigned int FindFiles(FindFilesCallback cb, const std::string& files, bool recurse = false, match_flag_type flags = match_default) { return FindFiles(cb, files.c_str(), recurse, flags); }
+#endif
+
+   std::string Merge(const std::string& in, const std::string& fmt,
+                       bool copy = true, match_flag_type flags = match_default);
+   std::string Merge(const char* in, const char* fmt,
+                       bool copy = true, match_flag_type flags = match_default);
+
+   std::size_t Split(std::vector<std::string>& v, std::string& s, match_flag_type flags = match_default, unsigned max_count = ~0);
+   /*
+    * now operators for returning what matched in more detail:
+    */
+   std::size_t Position(int i = 0)const;
+   std::size_t Length(int i = 0)const;
+   bool Matched(int i = 0)const;
+   std::size_t Marks()const;
+   std::string What(int i = 0)const;
+   std::string operator[](int i)const { return What(i); }
+
+   static const std::size_t npos;
+
+   friend struct re_detail::pred1;
+   friend struct re_detail::pred2;
+   friend struct re_detail::pred3;
+   friend struct re_detail::pred4;
+};
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} /* namespace ndnboost */
+
+#endif /* __cplusplus */
+
+#endif /* include guard */
+
+
+
+
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/error_type.hpp b/include/ndnboost/regex/v4/error_type.hpp
new file mode 100644
index 0000000..154e9c0
--- /dev/null
+++ b/include/ndnboost/regex/v4/error_type.hpp
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright (c) 2003-2005
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         error_type.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression error type enumerator.
+  */
+
+#ifndef NDNBOOST_REGEX_ERROR_TYPE_HPP
+#define NDNBOOST_REGEX_ERROR_TYPE_HPP
+
+#ifdef __cplusplus
+namespace ndnboost{
+#endif
+
+#ifdef __cplusplus
+namespace regex_constants{
+
+enum error_type{
+
+   error_ok = 0,         /* not used */
+   error_no_match = 1,   /* not used */
+   error_bad_pattern = 2,
+   error_collate = 3,
+   error_ctype = 4,
+   error_escape = 5,
+   error_backref = 6,
+   error_brack = 7,
+   error_paren = 8,
+   error_brace = 9,
+   error_badbrace = 10,
+   error_range = 11,
+   error_space = 12,
+   error_badrepeat = 13,
+   error_end = 14,    /* not used */
+   error_size = 15,
+   error_right_paren = 16,  /* not used */
+   error_empty = 17,
+   error_complexity = 18,
+   error_stack = 19,
+   error_perl_extension = 20,
+   error_unknown = 21
+};
+
+}
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/include/ndnboost/regex/v4/fileiter.hpp b/include/ndnboost/regex/v4/fileiter.hpp
new file mode 100644
index 0000000..75b99f8
--- /dev/null
+++ b/include/ndnboost/regex/v4/fileiter.hpp
@@ -0,0 +1,455 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         fileiter.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares various platform independent file and
+  *                directory iterators, plus binary file input in
+  *                the form of class map_file.
+  */
+
+#ifndef NDNBOOST_RE_FILEITER_HPP_INCLUDED
+#define NDNBOOST_RE_FILEITER_HPP_INCLUDED
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+#include <ndnboost/assert.hpp>
+
+#ifndef NDNBOOST_REGEX_NO_FILEITER
+
+#if (defined(__CYGWIN__) || defined(__CYGWIN32__)) && !defined(NDNBOOST_REGEX_NO_W32)
+#error "Sorry, can't mix <windows.h> with STL code and gcc compiler: if you ran configure, try again with configure --disable-ms-windows"
+#define NDNBOOST_REGEX_FI_WIN32_MAP
+#define NDNBOOST_REGEX_FI_POSIX_DIR
+#elif (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) && !defined(NDNBOOST_REGEX_NO_W32)
+#define NDNBOOST_REGEX_FI_WIN32_MAP
+#define NDNBOOST_REGEX_FI_WIN32_DIR
+#else
+#define NDNBOOST_REGEX_FI_POSIX_MAP
+#define NDNBOOST_REGEX_FI_POSIX_DIR
+#endif
+
+#if defined(NDNBOOST_REGEX_FI_WIN32_MAP)||defined(NDNBOOST_REGEX_FI_WIN32_DIR)
+#include <windows.h>
+#endif
+
+#if defined(NDNBOOST_REGEX_FI_WIN32_DIR)
+
+#include <cstddef>
+
+namespace ndnboost{
+   namespace re_detail{
+
+#ifndef NDNBOOST_NO_ANSI_APIS
+typedef WIN32_FIND_DATAA _fi_find_data;
+#else
+typedef WIN32_FIND_DATAW _fi_find_data;
+#endif
+typedef HANDLE _fi_find_handle;
+
+   } // namespace re_detail
+
+} // namespace ndnboost
+
+#define _fi_invalid_handle INVALID_HANDLE_VALUE
+#define _fi_dir FILE_ATTRIBUTE_DIRECTORY
+
+#elif defined(NDNBOOST_REGEX_FI_POSIX_DIR)
+
+#include <cstddef>
+#include <cstdio>
+#include <cctype>
+#include <iterator>
+#include <list>
+#include <cassert>
+#include <dirent.h>
+
+#if defined(__SUNPRO_CC)
+using std::list;
+#endif
+
+#ifndef MAX_PATH
+#define MAX_PATH 256
+#endif
+
+namespace ndnboost{
+   namespace re_detail{
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+
+struct _fi_find_data
+{
+   unsigned dwFileAttributes;
+   char cFileName[MAX_PATH];
+};
+
+struct _fi_priv_data;
+
+typedef _fi_priv_data* _fi_find_handle;
+#define _fi_invalid_handle 0
+#define _fi_dir 1
+
+_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData);
+bool _fi_FindNextFile(_fi_find_handle hFindFile,   _fi_find_data* lpFindFileData);
+bool _fi_FindClose(_fi_find_handle hFindFile);
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+
+   } // namespace re_detail
+} // namespace ndnboost
+
+#ifdef FindFirstFile
+ #undef FindFirstFile
+#endif
+#ifdef FindNextFile
+ #undef FindNextFile
+#endif
+#ifdef FindClose
+ #undef FindClose
+#endif
+
+#define FindFirstFileA _fi_FindFirstFile
+#define FindNextFileA _fi_FindNextFile
+#define FindClose _fi_FindClose
+
+#endif
+
+namespace ndnboost{
+   namespace re_detail{
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+
+#ifdef NDNBOOST_REGEX_FI_WIN32_MAP // win32 mapfile
+
+class NDNBOOST_REGEX_DECL mapfile
+{
+   HANDLE hfile;
+   HANDLE hmap;
+   const char* _first;
+   const char* _last;
+public:
+
+   typedef const char* iterator;
+
+   mapfile(){ hfile = hmap = 0; _first = _last = 0; }
+   mapfile(const char* file){ hfile = hmap = 0; _first = _last = 0; open(file); }
+   ~mapfile(){ close(); }
+   void open(const char* file);
+   void close();
+   const char* begin(){ return _first; }
+   const char* end(){ return _last; }
+   size_t size(){ return _last - _first; }
+   bool valid(){ return (hfile != 0) && (hfile != INVALID_HANDLE_VALUE); }
+};
+
+
+#else
+
+class NDNBOOST_REGEX_DECL mapfile_iterator;
+
+class NDNBOOST_REGEX_DECL mapfile
+{
+   typedef char* pointer;
+   std::FILE* hfile;
+   long int _size;
+   pointer* _first;
+   pointer* _last;
+   mutable std::list<pointer*> condemed;
+   enum sizes
+   {
+      buf_size = 4096
+   };
+   void lock(pointer* node)const;
+   void unlock(pointer* node)const;
+public:
+
+   typedef mapfile_iterator iterator;
+
+   mapfile(){ hfile = 0; _size = 0; _first = _last = 0; }
+   mapfile(const char* file){ hfile = 0; _size = 0; _first = _last = 0; open(file); }
+   ~mapfile(){ close(); }
+   void open(const char* file);
+   void close();
+   iterator begin()const;
+   iterator end()const;
+   unsigned long size()const{ return _size; }
+   bool valid()const{ return hfile != 0; }
+   friend class mapfile_iterator;
+};
+
+class NDNBOOST_REGEX_DECL mapfile_iterator
+#if !defined(NDNBOOST_NO_STD_ITERATOR) || defined(NDNBOOST_MSVC_STD_ITERATOR)
+: public std::iterator<std::random_access_iterator_tag, char>
+#endif
+{
+   typedef mapfile::pointer internal_pointer;
+   internal_pointer* node;
+   const mapfile* file;
+   unsigned long offset;
+   long position()const
+   {
+      return file ? ((node - file->_first) * mapfile::buf_size + offset) : 0;
+   }
+   void position(long pos)
+   {
+      if(file)
+      {
+         node = file->_first + (pos / mapfile::buf_size);
+         offset = pos % mapfile::buf_size;
+      }
+   }
+public:
+   typedef std::ptrdiff_t                  difference_type;
+   typedef char                            value_type;
+   typedef const char*                     pointer;
+   typedef const char&                     reference;
+   typedef std::random_access_iterator_tag iterator_category;
+
+   mapfile_iterator() { node = 0; file = 0; offset = 0; }
+   mapfile_iterator(const mapfile* f, long arg_position)
+   {
+      file = f;
+      node = f->_first + arg_position / mapfile::buf_size;
+      offset = arg_position % mapfile::buf_size;
+      if(file)
+         file->lock(node);
+   }
+   mapfile_iterator(const mapfile_iterator& i)
+   {
+      file = i.file;
+      node = i.node;
+      offset = i.offset;
+      if(file)
+         file->lock(node);
+   }
+   ~mapfile_iterator()
+   {
+      if(file && node)
+         file->unlock(node);
+   }
+   mapfile_iterator& operator = (const mapfile_iterator& i);
+   char operator* ()const
+   {
+      NDNBOOST_ASSERT(node >= file->_first);
+      NDNBOOST_ASSERT(node < file->_last);
+      return file ? *(*node + sizeof(int) + offset) : char(0);
+   }
+   char operator[] (long off)const
+   {
+      mapfile_iterator tmp(*this);
+      tmp += off;
+      return *tmp;
+   }
+   mapfile_iterator& operator++ ();
+   mapfile_iterator operator++ (int);
+   mapfile_iterator& operator-- ();
+   mapfile_iterator operator-- (int);
+
+   mapfile_iterator& operator += (long off)
+   {
+      position(position() + off);
+      return *this;
+   }
+   mapfile_iterator& operator -= (long off)
+   {
+      position(position() - off);
+      return *this;
+   }
+
+   friend inline bool operator==(const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return (i.file == j.file) && (i.node == j.node) && (i.offset == j.offset);
+   }
+
+   friend inline bool operator!=(const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return !(i == j);
+   }
+
+   friend inline bool operator<(const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return i.position() < j.position();
+   }
+   friend inline bool operator>(const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return i.position() > j.position();
+   }
+   friend inline bool operator<=(const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return i.position() <= j.position();
+   }
+   friend inline bool operator>=(const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return i.position() >= j.position();
+   }
+
+   friend mapfile_iterator operator + (const mapfile_iterator& i, long off);
+   friend mapfile_iterator operator + (long off, const mapfile_iterator& i)
+   {
+      mapfile_iterator tmp(i);
+      return tmp += off;
+   }
+   friend mapfile_iterator operator - (const mapfile_iterator& i, long off);
+   friend inline long operator - (const mapfile_iterator& i, const mapfile_iterator& j)
+   {
+      return i.position() - j.position();
+   }
+};
+
+#endif
+
+// _fi_sep determines the directory separator, either '\\' or '/'
+NDNBOOST_REGEX_DECL extern const char* _fi_sep;
+
+struct file_iterator_ref
+{
+   _fi_find_handle hf;
+   _fi_find_data _data;
+   long count;
+};
+
+
+class NDNBOOST_REGEX_DECL file_iterator 
+{
+   char* _root;
+   char* _path;
+   char* ptr;
+   file_iterator_ref* ref;
+
+public:
+   typedef std::ptrdiff_t            difference_type;
+   typedef const char*               value_type;
+   typedef const char**              pointer;
+   typedef const char*&              reference;
+   typedef std::input_iterator_tag   iterator_category;
+
+   file_iterator();
+   file_iterator(const char* wild);
+   ~file_iterator();
+   file_iterator(const file_iterator&);
+   file_iterator& operator=(const file_iterator&);
+   const char* root()const { return _root; }
+   const char* path()const { return _path; }
+   const char* name()const { return ptr; }
+   _fi_find_data* data() { return &(ref->_data); }
+   void next();
+   file_iterator& operator++() { next(); return *this; }
+   file_iterator operator++(int);
+   const char* operator*() { return path(); }
+
+   friend inline bool operator == (const file_iterator& f1, const file_iterator& f2)
+   {
+      return ((f1.ref->hf == _fi_invalid_handle) && (f2.ref->hf == _fi_invalid_handle));
+   }
+
+   friend inline bool operator != (const file_iterator& f1, const file_iterator& f2)
+   {
+      return !(f1 == f2);
+   }
+
+};
+
+// dwa 9/13/00 - suppress unused parameter warning
+inline bool operator < (const file_iterator&, const file_iterator&)
+{
+   return false;
+}
+
+
+class NDNBOOST_REGEX_DECL directory_iterator
+{
+   char* _root;
+   char* _path;
+   char* ptr;
+   file_iterator_ref* ref;
+
+public:
+   typedef std::ptrdiff_t            difference_type;
+   typedef const char*               value_type;
+   typedef const char**              pointer;
+   typedef const char*&              reference;
+   typedef std::input_iterator_tag   iterator_category;
+
+   directory_iterator();
+   directory_iterator(const char* wild);
+   ~directory_iterator();
+   directory_iterator(const directory_iterator& other);
+   directory_iterator& operator=(const directory_iterator& other);
+
+   const char* root()const { return _root; }
+   const char* path()const { return _path; }
+   const char* name()const { return ptr; }
+   _fi_find_data* data() { return &(ref->_data); }
+   void next();
+   directory_iterator& operator++() { next(); return *this; }
+   directory_iterator operator++(int);
+   const char* operator*() { return path(); }
+
+   static const char* separator() { return _fi_sep; }
+
+   friend inline bool operator == (const directory_iterator& f1, const directory_iterator& f2)
+   {
+      return ((f1.ref->hf == _fi_invalid_handle) && (f2.ref->hf == _fi_invalid_handle));
+   }
+
+
+   friend inline bool operator != (const directory_iterator& f1, const directory_iterator& f2)
+   {
+      return !(f1 == f2);
+   }
+
+   };
+
+inline bool operator < (const directory_iterator&, const directory_iterator&)
+{
+   return false;
+}
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+
+
+} // namespace re_detail
+using ndnboost::re_detail::directory_iterator;
+using ndnboost::re_detail::file_iterator;
+using ndnboost::re_detail::mapfile;
+} // namespace ndnboost
+
+#endif     // NDNBOOST_REGEX_NO_FILEITER
+#endif     // NDNBOOST_RE_FILEITER_HPP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/instances.hpp b/include/ndnboost/regex/v4/instances.hpp
new file mode 100644
index 0000000..b64e01e
--- /dev/null
+++ b/include/ndnboost/regex/v4/instances.hpp
@@ -0,0 +1,222 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         instances.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Defines those template instances that are placed in the
+  *                library rather than in the users object files.
+  */
+
+//
+// note no include guard, we may include this multiple times:
+//
+#ifndef NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+
+namespace ndnboost{
+
+//
+// this header can be included multiple times, each time with
+// a different character type, NDNBOOST_REGEX_CHAR_T must be defined
+// first:
+//
+#ifndef NDNBOOST_REGEX_CHAR_T
+#  error "NDNBOOST_REGEX_CHAR_T not defined"
+#endif
+
+#ifndef NDNBOOST_REGEX_TRAITS_T
+#  define NDNBOOST_REGEX_TRAITS_T , ndnboost::regex_traits<NDNBOOST_REGEX_CHAR_T >
+#endif
+
+//
+// what follows is compiler specific:
+//
+
+#if  defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+
+#  ifndef NDNBOOST_REGEX_INSTANTIATE
+#     pragma option push -Jgx
+#  endif
+
+template class NDNBOOST_REGEX_DECL basic_regex< NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >;
+template class NDNBOOST_REGEX_DECL match_results< const NDNBOOST_REGEX_CHAR_T* >;
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+template class NDNBOOST_REGEX_DECL ::ndnboost::re_detail::perl_matcher<NDNBOOST_REGEX_CHAR_T const *, match_results< const NDNBOOST_REGEX_CHAR_T* >::allocator_type NDNBOOST_REGEX_TRAITS_T >;
+#endif
+
+#  ifndef NDNBOOST_REGEX_INSTANTIATE
+#     pragma option pop
+#  endif
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+
+#elif defined(NDNBOOST_MSVC) || defined(__ICL)
+
+#  ifndef NDNBOOST_REGEX_INSTANTIATE
+#     ifdef __GNUC__
+#        define template __extension__ extern template
+#     else
+#        if NDNBOOST_MSVC > 1310
+#           define NDNBOOST_REGEX_TEMPLATE_DECL
+#        endif
+#        define template extern template
+#     endif
+#  endif
+
+#ifndef NDNBOOST_REGEX_TEMPLATE_DECL
+#  define NDNBOOST_REGEX_TEMPLATE_DECL NDNBOOST_REGEX_DECL
+#endif
+
+#  ifdef NDNBOOST_MSVC
+#     pragma warning(push)
+#     pragma warning(disable : 4251 4231)
+#     if NDNBOOST_MSVC < 1600
+#     pragma warning(disable : 4660)
+#     endif
+#  endif
+
+template class NDNBOOST_REGEX_TEMPLATE_DECL basic_regex< NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >;
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+template class NDNBOOST_REGEX_TEMPLATE_DECL match_results< const NDNBOOST_REGEX_CHAR_T* >;
+#endif
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+template class NDNBOOST_REGEX_TEMPLATE_DECL ::ndnboost::re_detail::perl_matcher<NDNBOOST_REGEX_CHAR_T const *, match_results< const NDNBOOST_REGEX_CHAR_T* >::allocator_type NDNBOOST_REGEX_TRAITS_T >;
+#endif
+#if !(defined(NDNBOOST_DINKUMWARE_STDLIB) && (NDNBOOST_DINKUMWARE_STDLIB <= 1))\
+   && !(defined(NDNBOOST_INTEL_CXX_VERSION) && (NDNBOOST_INTEL_CXX_VERSION <= 800))\
+   && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))\
+   && !defined(NDNBOOST_REGEX_ICU_INSTANCES)
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+template class NDNBOOST_REGEX_TEMPLATE_DECL match_results< std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator >;
+#endif
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+template class NDNBOOST_REGEX_TEMPLATE_DECL ::ndnboost::re_detail::perl_matcher< std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, ndnboost::regex_traits<NDNBOOST_REGEX_CHAR_T > >;
+#endif
+#endif
+
+
+#  ifdef NDNBOOST_MSVC
+#     pragma warning(pop)
+#  endif
+
+#  ifdef template
+#     undef template
+#  endif
+
+#undef NDNBOOST_REGEX_TEMPLATE_DECL
+
+#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || !defined(NDNBOOST_NO_CXX11_EXTERN_TEMPLATE)
+
+#  ifndef NDNBOOST_REGEX_INSTANTIATE
+#     ifdef __GNUC__
+#        define template __extension__ extern template
+#     else
+#        define template extern template
+#     endif
+#  endif
+
+#if !defined(NDNBOOST_NO_STD_LOCALE) && !defined(NDNBOOST_REGEX_ICU_INSTANCES)
+namespace re_detail{
+template NDNBOOST_REGEX_DECL
+std::locale cpp_regex_traits_base<NDNBOOST_REGEX_CHAR_T>::imbue(const std::locale& l);
+
+template NDNBOOST_REGEX_DECL
+cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::string_type 
+   cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::transform_primary(const NDNBOOST_REGEX_CHAR_T* p1, const NDNBOOST_REGEX_CHAR_T* p2) const;
+template NDNBOOST_REGEX_DECL
+cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::string_type 
+   cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::transform(const NDNBOOST_REGEX_CHAR_T* p1, const NDNBOOST_REGEX_CHAR_T* p2) const;
+template NDNBOOST_REGEX_DECL
+cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::string_type 
+   cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::lookup_collatename(const NDNBOOST_REGEX_CHAR_T* p1, const NDNBOOST_REGEX_CHAR_T* p2) const;
+template NDNBOOST_REGEX_DECL
+void cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::init();
+template NDNBOOST_REGEX_DECL
+cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::char_class_type 
+   cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::lookup_classname_imp(const NDNBOOST_REGEX_CHAR_T* p1, const NDNBOOST_REGEX_CHAR_T* p2) const;
+#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+template NDNBOOST_REGEX_DECL
+bool cpp_regex_traits_implementation<NDNBOOST_REGEX_CHAR_T>::isctype(const NDNBOOST_REGEX_CHAR_T c, char_class_type mask) const;
+#endif
+} // namespace
+template NDNBOOST_REGEX_DECL
+int cpp_regex_traits<NDNBOOST_REGEX_CHAR_T>::toi(const NDNBOOST_REGEX_CHAR_T*& first, const NDNBOOST_REGEX_CHAR_T* last, int radix)const;
+template NDNBOOST_REGEX_DECL
+std::string cpp_regex_traits<NDNBOOST_REGEX_CHAR_T>::catalog_name(const std::string& name);
+template NDNBOOST_REGEX_DECL
+std::string& cpp_regex_traits<NDNBOOST_REGEX_CHAR_T>::get_catalog_name_inst();
+template NDNBOOST_REGEX_DECL
+std::string cpp_regex_traits<NDNBOOST_REGEX_CHAR_T>::get_catalog_name();
+#ifdef NDNBOOST_HAS_THREADS
+template NDNBOOST_REGEX_DECL
+static_mutex& cpp_regex_traits<NDNBOOST_REGEX_CHAR_T>::get_mutex_inst();
+#endif
+#endif
+
+template NDNBOOST_REGEX_DECL basic_regex<NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >& 
+   basic_regex<NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >::do_assign(
+      const NDNBOOST_REGEX_CHAR_T* p1, 
+      const NDNBOOST_REGEX_CHAR_T* p2, 
+      flag_type f);
+template NDNBOOST_REGEX_DECL basic_regex<NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >::locale_type NDNBOOST_REGEX_CALL 
+   basic_regex<NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >::imbue(locale_type l);
+
+template NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL 
+   match_results<const NDNBOOST_REGEX_CHAR_T*>::maybe_assign(
+      const match_results<const NDNBOOST_REGEX_CHAR_T*>& m);
+
+namespace re_detail{
+template NDNBOOST_REGEX_DECL void perl_matcher<NDNBOOST_REGEX_CHAR_T const *, match_results< const NDNBOOST_REGEX_CHAR_T* >::allocator_type NDNBOOST_REGEX_TRAITS_T >::construct_init(
+      const basic_regex<NDNBOOST_REGEX_CHAR_T NDNBOOST_REGEX_TRAITS_T >& e, match_flag_type f);
+template NDNBOOST_REGEX_DECL bool perl_matcher<NDNBOOST_REGEX_CHAR_T const *, match_results< const NDNBOOST_REGEX_CHAR_T* >::allocator_type NDNBOOST_REGEX_TRAITS_T >::match();
+template NDNBOOST_REGEX_DECL bool perl_matcher<NDNBOOST_REGEX_CHAR_T const *, match_results< const NDNBOOST_REGEX_CHAR_T* >::allocator_type NDNBOOST_REGEX_TRAITS_T >::find();
+} // namespace
+
+#if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \
+   && !defined(NDNBOOST_REGEX_ICU_INSTANCES)\
+   && !defined(__SGI_STL_PORT)\
+   && !defined(_STLPORT_VERSION)
+// std:basic_string<>::const_iterator instances as well:
+template NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL 
+   match_results<std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator>::maybe_assign(
+      const match_results<std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator>& m);
+
+namespace re_detail{
+template NDNBOOST_REGEX_DECL void perl_matcher<std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, ndnboost::regex_traits<NDNBOOST_REGEX_CHAR_T > >::construct_init(
+      const basic_regex<NDNBOOST_REGEX_CHAR_T>& e, match_flag_type f);
+template NDNBOOST_REGEX_DECL bool perl_matcher<std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, ndnboost::regex_traits<NDNBOOST_REGEX_CHAR_T > >::match();
+template NDNBOOST_REGEX_DECL bool perl_matcher<std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<NDNBOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, ndnboost::regex_traits<NDNBOOST_REGEX_CHAR_T > >::find();
+} // namespace
+#endif
+
+#  ifdef template
+#     undef template
+#  endif
+
+
+#endif
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/iterator_category.hpp b/include/ndnboost/regex/v4/iterator_category.hpp
new file mode 100644
index 0000000..790417b
--- /dev/null
+++ b/include/ndnboost/regex/v4/iterator_category.hpp
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_match.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Iterator traits for selecting an iterator type as
+  *                an integral constant expression.
+  */
+
+
+#ifndef NDNBOOST_REGEX_ITERATOR_CATEGORY_HPP
+#define NDNBOOST_REGEX_ITERATOR_CATEGORY_HPP
+
+#include <iterator>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/is_pointer.hpp>
+
+namespace ndnboost{
+namespace detail{
+
+template <class I>
+struct is_random_imp
+{
+#ifndef NDNBOOST_NO_STD_ITERATOR_TRAITS
+private:
+   typedef typename std::iterator_traits<I>::iterator_category cat;
+public:
+   NDNBOOST_STATIC_CONSTANT(bool, value = (::ndnboost::is_convertible<cat*, std::random_access_iterator_tag*>::value));
+#else
+   NDNBOOST_STATIC_CONSTANT(bool, value = false);
+#endif
+};
+
+template <class I>
+struct is_random_pointer_imp
+{
+   NDNBOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template <bool is_pointer_type>
+struct is_random_imp_selector
+{
+   template <class I>
+   struct rebind
+   {
+      typedef is_random_imp<I> type;
+   };
+};
+
+template <>
+struct is_random_imp_selector<true>
+{
+   template <class I>
+   struct rebind
+   {
+      typedef is_random_pointer_imp<I> type;
+   };
+};
+
+}
+
+template <class I>
+struct is_random_access_iterator
+{
+private:
+   typedef detail::is_random_imp_selector< ::ndnboost::is_pointer<I>::value> selector;
+   typedef typename selector::template rebind<I> bound_type;
+   typedef typename bound_type::type answer;
+public:
+   NDNBOOST_STATIC_CONSTANT(bool, value = answer::value);
+};
+
+#ifndef NDNBOOST_NO_INCLASS_MEMBER_INITIALIZATION
+template <class I>
+const bool is_random_access_iterator<I>::value;
+#endif
+
+}
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/iterator_traits.hpp b/include/ndnboost/regex/v4/iterator_traits.hpp
new file mode 100644
index 0000000..6795b35
--- /dev/null
+++ b/include/ndnboost/regex/v4/iterator_traits.hpp
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         iterator_traits.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares iterator traits workarounds.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_ITERATOR_TRAITS_HPP
+#define NDNBOOST_REGEX_V4_ITERATOR_TRAITS_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+#if defined(NDNBOOST_NO_STD_ITERATOR_TRAITS) || defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template <class T>
+struct regex_iterator_traits 
+{
+  typedef typename T::iterator_category iterator_category;
+  typedef typename T::value_type        value_type;
+#if !defined(NDNBOOST_NO_STD_ITERATOR)
+  typedef typename T::difference_type   difference_type;
+  typedef typename T::pointer           pointer;
+  typedef typename T::reference         reference;
+#else
+  typedef std::ptrdiff_t                difference_type;
+  typedef value_type*                   pointer;
+  typedef value_type&                   reference;
+#endif
+};
+
+template <class T>
+struct pointer_iterator_traits
+{
+   typedef std::ptrdiff_t difference_type;
+   typedef T value_type;
+   typedef T* pointer;
+   typedef T& reference;
+   typedef std::random_access_iterator_tag iterator_category;
+};
+template <class T>
+struct const_pointer_iterator_traits
+{
+   typedef std::ptrdiff_t difference_type;
+   typedef T value_type;
+   typedef const T* pointer;
+   typedef const T& reference;
+   typedef std::random_access_iterator_tag iterator_category;
+};
+
+template<>
+struct regex_iterator_traits<char*> : pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<const char*> : const_pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<wchar_t*> : pointer_iterator_traits<wchar_t>{};
+template<>
+struct regex_iterator_traits<const wchar_t*> : const_pointer_iterator_traits<wchar_t>{};
+//
+// the follwoing are needed for ICU support:
+//
+template<>
+struct regex_iterator_traits<unsigned char*> : pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<const unsigned char*> : const_pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<int*> : pointer_iterator_traits<int>{};
+template<>
+struct regex_iterator_traits<const int*> : const_pointer_iterator_traits<int>{};
+
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+template<>
+struct regex_iterator_traits<unsigned short*> : pointer_iterator_traits<unsigned short>{};
+template<>
+struct regex_iterator_traits<const unsigned short*> : const_pointer_iterator_traits<unsigned short>{};
+#endif
+
+#if defined(__SGI_STL_PORT) && defined(__STL_DEBUG)
+template<>
+struct regex_iterator_traits<std::string::iterator> : pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<std::string::const_iterator> : const_pointer_iterator_traits<char>{};
+#ifndef NDNBOOST_NO_STD_WSTRING
+template<>
+struct regex_iterator_traits<std::wstring::iterator> : pointer_iterator_traits<wchar_t>{};
+template<>
+struct regex_iterator_traits<std::wstring::const_iterator> : const_pointer_iterator_traits<wchar_t>{};
+#endif // NDNBOOST_NO_WSTRING
+#endif // stport
+
+#else
+
+template <class T>
+struct regex_iterator_traits : public std::iterator_traits<T> {};
+
+#endif
+
+} // namespace re_detail
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/match_flags.hpp b/include/ndnboost/regex/v4/match_flags.hpp
new file mode 100644
index 0000000..d352d0f
--- /dev/null
+++ b/include/ndnboost/regex/v4/match_flags.hpp
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         match_flags.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares match_flags type.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_MATCH_FLAGS
+#define NDNBOOST_REGEX_V4_MATCH_FLAGS
+
+#ifdef __cplusplus
+#  include <ndnboost/cstdint.hpp>
+#endif
+
+#ifdef __cplusplus
+namespace ndnboost{
+   namespace regex_constants{
+#endif
+
+typedef enum _match_flags
+{
+   match_default = 0,
+   match_not_bol = 1,                                /* first is not start of line */
+   match_not_eol = match_not_bol << 1,               /* last is not end of line */
+   match_not_bob = match_not_eol << 1,               /* first is not start of buffer */
+   match_not_eob = match_not_bob << 1,               /* last is not end of buffer */
+   match_not_bow = match_not_eob << 1,               /* first is not start of word */
+   match_not_eow = match_not_bow << 1,               /* last is not end of word */
+   match_not_dot_newline = match_not_eow << 1,       /* \n is not matched by '.' */
+   match_not_dot_null = match_not_dot_newline << 1,  /* '\0' is not matched by '.' */
+   match_prev_avail = match_not_dot_null << 1,       /* *--first is a valid expression */
+   match_init = match_prev_avail << 1,               /* internal use */
+   match_any = match_init << 1,                      /* don't care what we match */
+   match_not_null = match_any << 1,                  /* string can't be null */
+   match_continuous = match_not_null << 1,           /* each grep match must continue from */
+                                                     /* uninterupted from the previous one */
+   match_partial = match_continuous << 1,            /* find partial matches */
+   
+   match_stop = match_partial << 1,                  /* stop after first match (grep) V3 only */
+   match_not_initial_null = match_stop,              /* don't match initial null, V4 only */
+   match_all = match_stop << 1,                      /* must find the whole of input even if match_any is set */
+   match_perl = match_all << 1,                      /* Use perl matching rules */
+   match_posix = match_perl << 1,                    /* Use POSIX matching rules */
+   match_nosubs = match_posix << 1,                  /* don't trap marked subs */
+   match_extra = match_nosubs << 1,                  /* include full capture information for repeated captures */
+   match_single_line = match_extra << 1,             /* treat text as single line and ignor any \n's when matching ^ and $. */
+   match_unused1 = match_single_line << 1,           /* unused */
+   match_unused2 = match_unused1 << 1,               /* unused */
+   match_unused3 = match_unused2 << 1,               /* unused */
+   match_max = match_unused3,
+
+   format_perl = 0,                                  /* perl style replacement */
+   format_default = 0,                               /* ditto. */
+   format_sed = match_max << 1,                      /* sed style replacement. */
+   format_all = format_sed << 1,                     /* enable all extentions to sytax. */
+   format_no_copy = format_all << 1,                 /* don't copy non-matching segments. */
+   format_first_only = format_no_copy << 1,          /* Only replace first occurance. */
+   format_is_if = format_first_only << 1,            /* internal use only. */
+   format_literal = format_is_if << 1                /* treat string as a literal */
+
+} match_flags;
+
+#if (defined(_MSC_VER) && (_MSC_VER < 1300)) || defined(__BORLANDC__)
+typedef unsigned long match_flag_type;
+#else
+typedef match_flags match_flag_type;
+
+
+#ifdef __cplusplus
+inline match_flags operator&(match_flags m1, match_flags m2)
+{ return static_cast<match_flags>(static_cast<ndnboost::int32_t>(m1) & static_cast<ndnboost::int32_t>(m2)); }
+inline match_flags operator|(match_flags m1, match_flags m2)
+{ return static_cast<match_flags>(static_cast<ndnboost::int32_t>(m1) | static_cast<ndnboost::int32_t>(m2)); }
+inline match_flags operator^(match_flags m1, match_flags m2)
+{ return static_cast<match_flags>(static_cast<ndnboost::int32_t>(m1) ^ static_cast<ndnboost::int32_t>(m2)); }
+inline match_flags operator~(match_flags m1)
+{ return static_cast<match_flags>(~static_cast<ndnboost::int32_t>(m1)); }
+inline match_flags& operator&=(match_flags& m1, match_flags m2)
+{ m1 = m1&m2; return m1; }
+inline match_flags& operator|=(match_flags& m1, match_flags m2)
+{ m1 = m1|m2; return m1; }
+inline match_flags& operator^=(match_flags& m1, match_flags m2)
+{ m1 = m1^m2; return m1; }
+#endif
+#endif
+
+#ifdef __cplusplus
+} /* namespace regex_constants */
+/*
+ * import names into boost for backwards compatiblity:
+ */
+using regex_constants::match_flag_type;
+using regex_constants::match_default;
+using regex_constants::match_not_bol;
+using regex_constants::match_not_eol;
+using regex_constants::match_not_bob;
+using regex_constants::match_not_eob;
+using regex_constants::match_not_bow;
+using regex_constants::match_not_eow;
+using regex_constants::match_not_dot_newline;
+using regex_constants::match_not_dot_null;
+using regex_constants::match_prev_avail;
+/* using regex_constants::match_init; */
+using regex_constants::match_any;
+using regex_constants::match_not_null;
+using regex_constants::match_continuous;
+using regex_constants::match_partial;
+/*using regex_constants::match_stop; */
+using regex_constants::match_all;
+using regex_constants::match_perl;
+using regex_constants::match_posix;
+using regex_constants::match_nosubs;
+using regex_constants::match_extra;
+using regex_constants::match_single_line;
+/*using regex_constants::match_max; */
+using regex_constants::format_all;
+using regex_constants::format_sed;
+using regex_constants::format_perl;
+using regex_constants::format_default;
+using regex_constants::format_no_copy;
+using regex_constants::format_first_only;
+/*using regex_constants::format_is_if;*/
+
+} /* namespace ndnboost */
+#endif /* __cplusplus */
+#endif /* include guard */
+
diff --git a/include/ndnboost/regex/v4/match_results.hpp b/include/ndnboost/regex/v4/match_results.hpp
new file mode 100644
index 0000000..8bb981f
--- /dev/null
+++ b/include/ndnboost/regex/v4/match_results.hpp
@@ -0,0 +1,702 @@
+/*
+ *
+ * Copyright (c) 1998-2009
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         match_results.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares template class match_results.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_MATCH_RESULTS_HPP
+#define NDNBOOST_REGEX_V4_MATCH_RESULTS_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231)
+#  if NDNBOOST_MSVC < 1600
+#     pragma warning(disable : 4660)
+#  endif
+#endif
+
+namespace re_detail{
+
+class named_subexpressions;
+
+}
+
+template <class BidiIterator, class Allocator>
+class match_results
+{ 
+private:
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+   typedef          std::vector<sub_match<BidiIterator>, Allocator> vector_type;
+#else
+   typedef          std::vector<sub_match<BidiIterator> >           vector_type;
+#endif
+public: 
+   typedef          sub_match<BidiIterator>                         value_type;
+#if  !defined(NDNBOOST_NO_STD_ALLOCATOR) && !(defined(NDNBOOST_MSVC) && defined(_STLPORT_VERSION))
+   typedef typename Allocator::const_reference                              const_reference;
+#else
+   typedef          const value_type&                                       const_reference;
+#endif
+   typedef          const_reference                                         reference;
+   typedef typename vector_type::const_iterator                             const_iterator;
+   typedef          const_iterator                                          iterator;
+   typedef typename re_detail::regex_iterator_traits<
+                                    BidiIterator>::difference_type          difference_type;
+   typedef typename Allocator::size_type                                    size_type;
+   typedef          Allocator                                               allocator_type;
+   typedef typename re_detail::regex_iterator_traits<
+                                    BidiIterator>::value_type               char_type;
+   typedef          std::basic_string<char_type>                            string_type;
+   typedef          re_detail::named_subexpressions                         named_sub_type;
+
+   // construct/copy/destroy:
+   explicit match_results(const Allocator& a = Allocator())
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+      : m_subs(a), m_base(), m_last_closed_paren(0), m_is_singular(true) {}
+#else
+      : m_subs(), m_base(), m_last_closed_paren(0), m_is_singular(true) { (void)a; }
+#endif
+   match_results(const match_results& m)
+      : m_subs(m.m_subs), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular) 
+   {
+      if(!m_is_singular)
+      {
+         m_base = m.m_base;
+         m_null = m.m_null;
+      }
+   }
+   match_results& operator=(const match_results& m)
+   {
+      m_subs = m.m_subs;
+      m_named_subs = m.m_named_subs;
+      m_last_closed_paren = m.m_last_closed_paren;
+      m_is_singular = m.m_is_singular;
+      if(!m_is_singular)
+      {
+         m_base = m.m_base;
+         m_null = m.m_null;
+      }
+      return *this;
+   }
+   ~match_results(){}
+
+   // size:
+   size_type size() const
+   { return empty() ? 0 : m_subs.size() - 2; }
+   size_type max_size() const
+   { return m_subs.max_size(); }
+   bool empty() const
+   { return m_subs.size() < 2; }
+   // element access:
+   difference_type length(int sub = 0) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      sub += 2;
+      if((sub < (int)m_subs.size()) && (sub > 0))
+         return m_subs[sub].length();
+      return 0;
+   }
+   difference_type length(const char_type* sub) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      const char_type* sub_end = sub;
+      while(*sub_end) ++sub_end;
+      return length(named_subexpression_index(sub, sub_end));
+   }
+   template <class charT>
+   difference_type length(const charT* sub) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      const charT* sub_end = sub;
+      while(*sub_end) ++sub_end;
+      return length(named_subexpression_index(sub, sub_end));
+   }
+   template <class charT, class Traits, class A>
+   difference_type length(const std::basic_string<charT, Traits, A>& sub) const
+   {
+      return length(sub.c_str());
+   }
+   difference_type position(size_type sub = 0) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      sub += 2;
+      if(sub < m_subs.size())
+      {
+         const sub_match<BidiIterator>& s = m_subs[sub];
+         if(s.matched || (sub == 2))
+         {
+            return ::ndnboost::re_detail::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
+         }
+      }
+      return ~static_cast<difference_type>(0);
+   }
+   difference_type position(const char_type* sub) const
+   {
+      const char_type* sub_end = sub;
+      while(*sub_end) ++sub_end;
+      return position(named_subexpression_index(sub, sub_end));
+   }
+   template <class charT>
+   difference_type position(const charT* sub) const
+   {
+      const charT* sub_end = sub;
+      while(*sub_end) ++sub_end;
+      return position(named_subexpression_index(sub, sub_end));
+   }
+   template <class charT, class Traits, class A>
+   difference_type position(const std::basic_string<charT, Traits, A>& sub) const
+   {
+      return position(sub.c_str());
+   }
+   string_type str(int sub = 0) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      sub += 2;
+      string_type result;
+      if(sub < (int)m_subs.size() && (sub > 0))
+      {
+         const sub_match<BidiIterator>& s = m_subs[sub];
+         if(s.matched)
+         {
+            result = s.str();
+         }
+      }
+      return result;
+   }
+   string_type str(const char_type* sub) const
+   {
+      return (*this)[sub].str();
+   }
+   template <class Traits, class A>
+   string_type str(const std::basic_string<char_type, Traits, A>& sub) const
+   {
+      return (*this)[sub].str();
+   }
+   template <class charT>
+   string_type str(const charT* sub) const
+   {
+      return (*this)[sub].str();
+   }
+   template <class charT, class Traits, class A>
+   string_type str(const std::basic_string<charT, Traits, A>& sub) const
+   {
+      return (*this)[sub].str();
+   }
+   const_reference operator[](int sub) const
+   {
+      if(m_is_singular && m_subs.empty())
+         raise_logic_error();
+      sub += 2;
+      if(sub < (int)m_subs.size() && (sub >= 0))
+      {
+         return m_subs[sub];
+      }
+      return m_null;
+   }
+   //
+   // Named sub-expressions:
+   //
+   const_reference named_subexpression(const char_type* i, const char_type* j) const
+   {
+      //
+      // Scan for the leftmost *matched* subexpression with the specified named:
+      //
+      if(m_is_singular)
+         raise_logic_error();
+      re_detail::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);
+      while((r.first != r.second) && ((*this)[r.first->index].matched == false))
+         ++r.first;
+      return r.first != r.second ? (*this)[r.first->index] : m_null;
+   }
+   template <class charT>
+   const_reference named_subexpression(const charT* i, const charT* j) const
+   {
+      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+      if(i == j)
+         return m_null;
+      std::vector<char_type> s;
+      while(i != j)
+         s.insert(s.end(), *i++);
+      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
+   }
+   int named_subexpression_index(const char_type* i, const char_type* j) const
+   {
+      //
+      // Scan for the leftmost *matched* subexpression with the specified named.
+      // If none found then return the leftmost expression with that name,
+      // otherwise an invalid index:
+      //
+      if(m_is_singular)
+         raise_logic_error();
+      re_detail::named_subexpressions::range_type s, r;
+      s = r = m_named_subs->equal_range(i, j);
+      while((r.first != r.second) && ((*this)[r.first->index].matched == false))
+         ++r.first;
+      if(r.first == r.second)
+         r = s;
+      return r.first != r.second ? r.first->index : -20;
+   }
+   template <class charT>
+   int named_subexpression_index(const charT* i, const charT* j) const
+   {
+      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+      if(i == j)
+         return -20;
+      std::vector<char_type> s;
+      while(i != j)
+         s.insert(s.end(), *i++);
+      return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
+   }
+   template <class Traits, class A>
+   const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
+   {
+      return named_subexpression(s.c_str(), s.c_str() + s.size());
+   }
+   const_reference operator[](const char_type* p) const
+   {
+      const char_type* e = p;
+      while(*e) ++e;
+      return named_subexpression(p, e);
+   }
+
+   template <class charT>
+   const_reference operator[](const charT* p) const
+   {
+      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+      if(*p == 0)
+         return m_null;
+      std::vector<char_type> s;
+      while(*p)
+         s.insert(s.end(), *p++);
+      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
+   }
+   template <class charT, class Traits, class A>
+   const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
+   {
+      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+      if(ns.empty())
+         return m_null;
+      std::vector<char_type> s;
+      for(unsigned i = 0; i < ns.size(); ++i)
+         s.insert(s.end(), ns[i]);
+      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
+   }
+
+   const_reference prefix() const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      return (*this)[-1];
+   }
+
+   const_reference suffix() const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      return (*this)[-2];
+   }
+   const_iterator begin() const
+   {
+      return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
+   }
+   const_iterator end() const
+   {
+      return m_subs.end();
+   }
+   // format:
+   template <class OutputIterator, class Functor>
+   OutputIterator format(OutputIterator out,
+                         Functor fmt,
+                         match_flag_type flags = format_default) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
+      F func(fmt);
+      return func(*this, out, flags);
+   }
+   template <class Functor>
+   string_type format(Functor fmt, match_flag_type flags = format_default) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      std::basic_string<char_type> result;
+      re_detail::string_out_iterator<std::basic_string<char_type> > i(result);
+
+      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, re_detail::string_out_iterator<std::basic_string<char_type> > >::type F;
+      F func(fmt);
+
+      func(*this, i, flags);
+      return result;
+   }
+   // format with locale:
+   template <class OutputIterator, class Functor, class RegexT>
+   OutputIterator format(OutputIterator out,
+                         Functor fmt,
+                         match_flag_type flags,
+                         const RegexT& re) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      typedef ::ndnboost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
+      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
+      F func(fmt);
+      return func(*this, out, flags, re.get_traits());
+   }
+   template <class RegexT, class Functor>
+   string_type format(Functor fmt,
+                      match_flag_type flags,
+                      const RegexT& re) const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      typedef ::ndnboost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
+      std::basic_string<char_type> result;
+      re_detail::string_out_iterator<std::basic_string<char_type> > i(result);
+
+      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, re_detail::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;
+      F func(fmt);
+
+      func(*this, i, flags, re.get_traits());
+      return result;
+   }
+
+   const_reference get_last_closed_paren()const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
+   }
+
+   allocator_type get_allocator() const
+   {
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+      return m_subs.get_allocator();
+#else
+     return allocator_type();
+#endif
+   }
+   void swap(match_results& that)
+   {
+      std::swap(m_subs, that.m_subs);
+      std::swap(m_named_subs, that.m_named_subs);
+      std::swap(m_last_closed_paren, that.m_last_closed_paren);
+      if(m_is_singular)
+      {
+         if(!that.m_is_singular)
+         {
+            m_base = that.m_base;
+            m_null = that.m_null;
+         }
+      }
+      else if(that.m_is_singular)
+      {
+         that.m_base = m_base;
+         that.m_null = m_null;
+      }
+      else
+      {
+         std::swap(m_base, that.m_base);
+         std::swap(m_null, that.m_null);
+      }
+      std::swap(m_is_singular, that.m_is_singular);
+   }
+   bool operator==(const match_results& that)const
+   {
+      if(m_is_singular)
+      {
+         return that.m_is_singular;
+      }
+      else if(that.m_is_singular)
+      {
+         return false;
+      }
+      return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
+   }
+   bool operator!=(const match_results& that)const
+   { return !(*this == that); }
+
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+   typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;
+
+   const capture_sequence_type& captures(int i)const
+   {
+      if(m_is_singular)
+         raise_logic_error();
+      return (*this)[i].captures();
+   }
+#endif
+
+   //
+   // private access functions:
+   void NDNBOOST_REGEX_CALL set_second(BidiIterator i)
+   {
+      NDNBOOST_ASSERT(m_subs.size() > 2);
+      m_subs[2].second = i;
+      m_subs[2].matched = true;
+      m_subs[0].first = i;
+      m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
+      m_null.first = i;
+      m_null.second = i;
+      m_null.matched = false;
+      m_is_singular = false;
+   }
+
+   void NDNBOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
+   {
+      if(pos)
+         m_last_closed_paren = static_cast<int>(pos);
+      pos += 2;
+      NDNBOOST_ASSERT(m_subs.size() > pos);
+      m_subs[pos].second = i;
+      m_subs[pos].matched = m;
+      if((pos == 2) && !escape_k)
+      {
+         m_subs[0].first = i;
+         m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
+         m_null.first = i;
+         m_null.second = i;
+         m_null.matched = false;
+         m_is_singular = false;
+      }
+   }
+   void NDNBOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)
+   {
+      value_type v(j);
+      size_type len = m_subs.size();
+      if(len > n + 2)
+      {
+         m_subs.erase(m_subs.begin()+n+2, m_subs.end());
+         std::fill(m_subs.begin(), m_subs.end(), v);
+      }
+      else
+      {
+         std::fill(m_subs.begin(), m_subs.end(), v);
+         if(n+2 != len)
+            m_subs.insert(m_subs.end(), n+2-len, v);
+      }
+      m_subs[1].first = i;
+      m_last_closed_paren = 0;
+   }
+   void NDNBOOST_REGEX_CALL set_base(BidiIterator pos)
+   {
+      m_base = pos;
+   }
+   BidiIterator base()const
+   {
+      return m_base;
+   }
+   void NDNBOOST_REGEX_CALL set_first(BidiIterator i)
+   {
+      NDNBOOST_ASSERT(m_subs.size() > 2);
+      // set up prefix:
+      m_subs[1].second = i;
+      m_subs[1].matched = (m_subs[1].first != i);
+      // set up $0:
+      m_subs[2].first = i;
+      // zero out everything else:
+      for(size_type n = 3; n < m_subs.size(); ++n)
+      {
+         m_subs[n].first = m_subs[n].second = m_subs[0].second;
+         m_subs[n].matched = false;
+      }
+   }
+   void NDNBOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)
+   {
+      NDNBOOST_ASSERT(pos+2 < m_subs.size());
+      if(pos || escape_k)
+      {
+         m_subs[pos+2].first = i;
+         if(escape_k)
+         {
+            m_subs[1].second = i;
+            m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
+         }
+      }
+      else
+         set_first(i);
+   }
+   void NDNBOOST_REGEX_CALL maybe_assign(const match_results<BidiIterator, Allocator>& m);
+
+   void NDNBOOST_REGEX_CALL set_named_subs(ndnboost::shared_ptr<named_sub_type> subs)
+   {
+      m_named_subs = subs;
+   }
+
+private:
+   //
+   // Error handler called when an uninitialized match_results is accessed:
+   //
+   static void raise_logic_error()
+   {
+      std::logic_error e("Attempt to access an uninitialzed ndnboost::match_results<> class.");
+      ndnboost::throw_exception(e);
+   }
+
+
+   vector_type            m_subs;                      // subexpressions
+   BidiIterator   m_base;                              // where the search started from
+   sub_match<BidiIterator> m_null;                     // a null match
+   ndnboost::shared_ptr<named_sub_type> m_named_subs;     // Shared copy of named subs in the regex object
+   int m_last_closed_paren;                            // Last ) to be seen - used for formatting
+   bool m_is_singular;                                 // True if our stored iterators are singular
+};
+
+template <class BidiIterator, class Allocator>
+void NDNBOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
+{
+   if(m_is_singular)
+   {
+      *this = m;
+      return;
+   }
+   const_iterator p1, p2;
+   p1 = begin();
+   p2 = m.begin();
+   //
+   // Distances are measured from the start of *this* match, unless this isn't
+   // a valid match in which case we use the start of the whole sequence.  Note that
+   // no subsequent match-candidate can ever be to the left of the first match found.
+   // This ensures that when we are using bidirectional iterators, that distances 
+   // measured are as short as possible, and therefore as efficient as possible
+   // to compute.  Finally note that we don't use the "matched" data member to test
+   // whether a sub-expression is a valid match, because partial matches set this
+   // to false for sub-expression 0.
+   //
+   BidiIterator l_end = this->suffix().second;
+   BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
+   difference_type len1 = 0;
+   difference_type len2 = 0;
+   difference_type base1 = 0;
+   difference_type base2 = 0;
+   std::size_t i;
+   for(i = 0; i < size(); ++i, ++p1, ++p2)
+   {
+      //
+      // Leftmost takes priority over longest; handle special cases
+      // where distances need not be computed first (an optimisation
+      // for bidirectional iterators: ensure that we don't accidently
+      // compute the length of the whole sequence, as this can be really
+      // expensive).
+      //
+      if(p1->first == l_end)
+      {
+         if(p2->first != l_end)
+         {
+            // p2 must be better than p1, and no need to calculate
+            // actual distances:
+            base1 = 1;
+            base2 = 0;
+            break;
+         }
+         else
+         {
+            // *p1 and *p2 are either unmatched or match end-of sequence,
+            // either way no need to calculate distances:
+            if((p1->matched == false) && (p2->matched == true))
+               break;
+            if((p1->matched == true) && (p2->matched == false))
+               return;
+            continue;
+         }
+      }
+      else if(p2->first == l_end)
+      {
+         // p1 better than p2, and no need to calculate distances:
+         return;
+      }
+      base1 = ::ndnboost::re_detail::distance(l_base, p1->first);
+      base2 = ::ndnboost::re_detail::distance(l_base, p2->first);
+      NDNBOOST_ASSERT(base1 >= 0);
+      NDNBOOST_ASSERT(base2 >= 0);
+      if(base1 < base2) return;
+      if(base2 < base1) break;
+
+      len1 = ::ndnboost::re_detail::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
+      len2 = ::ndnboost::re_detail::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
+      NDNBOOST_ASSERT(len1 >= 0);
+      NDNBOOST_ASSERT(len2 >= 0);
+      if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
+         break;
+      if((p1->matched == true) && (p2->matched == false))
+         return;
+   }
+   if(i == size())
+      return;
+   if(base2 < base1)
+      *this = m;
+   else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
+      *this = m;
+}
+
+template <class BidiIterator, class Allocator>
+void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
+{
+   a.swap(b);
+}
+
+#ifndef NDNBOOST_NO_STD_LOCALE
+template <class charT, class traits, class BidiIterator, class Allocator>
+std::basic_ostream<charT, traits>&
+   operator << (std::basic_ostream<charT, traits>& os,
+                const match_results<BidiIterator, Allocator>& s)
+{
+   return (os << s.str());
+}
+#else
+template <class BidiIterator, class Allocator>
+std::ostream& operator << (std::ostream& os,
+                           const match_results<BidiIterator, Allocator>& s)
+{
+   return (os << s.str());
+}
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
diff --git a/include/ndnboost/regex/v4/mem_block_cache.hpp b/include/ndnboost/regex/v4/mem_block_cache.hpp
new file mode 100644
index 0000000..fe71a3b
--- /dev/null
+++ b/include/ndnboost/regex/v4/mem_block_cache.hpp
@@ -0,0 +1,99 @@
+ /*
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         mem_block_cache.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: memory block cache used by the non-recursive matcher.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
+#define NDNBOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
+
+#include <new>
+#ifdef NDNBOOST_HAS_THREADS
+#include <ndnboost/regex/pending/static_mutex.hpp>
+#endif
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+struct mem_block_node
+{
+   mem_block_node* next;
+};
+
+struct mem_block_cache
+{
+   // this member has to be statically initialsed:
+   mem_block_node* next;
+   unsigned cached_blocks;
+#ifdef NDNBOOST_HAS_THREADS
+   ndnboost::static_mutex mut;
+#endif
+
+   ~mem_block_cache()
+   {
+      while(next)
+      {
+         mem_block_node* old = next;
+         next = next->next;
+         ::operator delete(old);
+      }
+   }
+   void* get()
+   {
+#ifdef NDNBOOST_HAS_THREADS
+      ndnboost::static_mutex::scoped_lock g(mut);
+#endif
+     if(next)
+      {
+         mem_block_node* result = next;
+         next = next->next;
+         --cached_blocks;
+         return result;
+      }
+      return ::operator new(NDNBOOST_REGEX_BLOCKSIZE);
+   }
+   void put(void* p)
+   {
+#ifdef NDNBOOST_HAS_THREADS
+      ndnboost::static_mutex::scoped_lock g(mut);
+#endif
+      if(cached_blocks >= NDNBOOST_REGEX_MAX_CACHE_BLOCKS)
+      {
+         ::operator delete(p);
+      }
+      else
+      {
+         mem_block_node* old = static_cast<mem_block_node*>(p);
+         old->next = next;
+         next = old;
+         ++cached_blocks;
+      }
+   }
+};
+
+extern mem_block_cache block_cache;
+
+}
+} // namespace ndnboost
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/perl_matcher.hpp b/include/ndnboost/regex/v4/perl_matcher.hpp
new file mode 100644
index 0000000..24cf0af
--- /dev/null
+++ b/include/ndnboost/regex/v4/perl_matcher.hpp
@@ -0,0 +1,587 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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 NDNBOOST_REGEX_MATCHER_HPP
+#define NDNBOOST_REGEX_MATCHER_HPP
+
+#include <ndnboost/regex/v4/iterator_category.hpp>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable: 4800)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+//
+// error checking API:
+//
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL verify_options(ndnboost::regex_constants::syntax_option_type ef, match_flag_type mf);
+//
+// function can_start:
+//
+template <class charT>
+inline bool can_start(charT c, const unsigned char* map, unsigned char mask)
+{
+   return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));
+}
+inline bool can_start(char c, const unsigned char* map, unsigned char mask)
+{
+   return map[(unsigned char)c] & mask;
+}
+inline bool can_start(signed char c, const unsigned char* map, unsigned char mask)
+{
+   return map[(unsigned char)c] & mask;
+}
+inline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)
+{
+   return map[c] & mask;
+}
+inline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)
+{
+   return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);
+}
+#if !defined(__hpux) && !defined(__WINSCW__)// WCHAR_MIN not usable in pp-directives.
+#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
+inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)
+{
+   return ((c >= static_cast<wchar_t>(1u << CHAR_BIT)) ? true : map[c] & mask);
+}
+#endif
+#endif
+#if !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
+inline bool can_start(unsigned int c, const unsigned char* map, unsigned char mask)
+{
+   return (((c >= static_cast<unsigned int>(1u << CHAR_BIT)) ? true : map[c] & mask));
+}
+#endif
+
+
+//
+// Unfortunately Rogue Waves standard library appears to have a bug
+// in std::basic_string::compare that results in eroneous answers
+// in some cases (tested with Borland C++ 5.1, Rogue Wave lib version
+// 0x020101) the test case was:
+// {39135,0} < {0xff,0}
+// which succeeds when it should not.
+//
+#ifndef _RWSTD_VER
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)
+template <class C, class T, class A>
+inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
+{ 
+   if(0 == *p)
+   {
+      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))
+         return 0;
+   }
+   return s.compare(p); 
+}
+#endif
+#else
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)
+template <class C, class T, class A>
+inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
+{ 
+   if(0 == *p)
+   {
+      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))
+         return 0;
+   }
+   return s.compare(p); 
+}
+#endif
+inline int string_compare(const std::string& s, const char* p)
+{ return std::strcmp(s.c_str(), p); }
+# ifndef NDNBOOST_NO_WREGEX
+inline int string_compare(const std::wstring& s, const wchar_t* p)
+{ return std::wcscmp(s.c_str(), p); }
+#endif
+#endif
+template <class Seq, class C>
+inline int string_compare(const Seq& s, const C* p)
+{
+   std::size_t i = 0;
+   while((i < s.size()) && (p[i] == s[i]))
+   {
+      ++i;
+   }
+   return (i == s.size()) ? -p[i] : s[i] - p[i];
+}
+# define STR_COMP(s,p) string_compare(s,p)
+
+template<class charT>
+inline const charT* re_skip_past_null(const charT* p)
+{
+  while (*p != static_cast<charT>(0)) ++p;
+  return ++p;
+}
+
+template <class iterator, class charT, class traits_type, class char_classT>
+iterator NDNBOOST_REGEX_CALL re_is_set_member(iterator next, 
+                          iterator last, 
+                          const re_set_long<char_classT>* set_, 
+                          const regex_data<charT, traits_type>& e, bool icase)
+{   
+   const charT* p = reinterpret_cast<const charT*>(set_+1);
+   iterator ptr;
+   unsigned int i;
+   //bool icase = e.m_flags & regex_constants::icase;
+
+   if(next == last) return next;
+
+   typedef typename traits_type::string_type traits_string_type;
+   const ::ndnboost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);
+   
+   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
+   // referenced
+   (void)traits_inst;
+
+   // try and match a single character, could be a multi-character
+   // collating element...
+   for(i = 0; i < set_->csingles; ++i)
+   {
+      ptr = next;
+      if(*p == static_cast<charT>(0))
+      {
+         // treat null string as special case:
+         if(traits_inst.translate(*ptr, icase) != *p)
+         {
+            while(*p == static_cast<charT>(0))++p;
+            continue;
+         }
+         return set_->isnot ? next : (ptr == next) ? ++next : ptr;
+      }
+      else
+      {
+         while(*p && (ptr != last))
+         {
+            if(traits_inst.translate(*ptr, icase) != *p)
+               break;
+            ++p;
+            ++ptr;
+         }
+
+         if(*p == static_cast<charT>(0)) // if null we've matched
+            return set_->isnot ? next : (ptr == next) ? ++next : ptr;
+
+         p = re_skip_past_null(p);     // skip null
+      }
+   }
+
+   charT col = traits_inst.translate(*next, icase);
+
+
+   if(set_->cranges || set_->cequivalents)
+   {
+      traits_string_type s1;
+      //
+      // try and match a range, NB only a single character can match
+      if(set_->cranges)
+      {
+         if((e.m_flags & regex_constants::collate) == 0)
+            s1.assign(1, col);
+         else
+         {
+            charT a[2] = { col, charT(0), };
+            s1 = traits_inst.transform(a, a + 1);
+         }
+         for(i = 0; i < set_->cranges; ++i)
+         {
+            if(STR_COMP(s1, p) >= 0)
+            {
+               do{ ++p; }while(*p);
+               ++p;
+               if(STR_COMP(s1, p) <= 0)
+                  return set_->isnot ? next : ++next;
+            }
+            else
+            {
+               // skip first string
+               do{ ++p; }while(*p);
+               ++p;
+            }
+            // skip second string
+            do{ ++p; }while(*p);
+            ++p;
+         }
+      }
+      //
+      // try and match an equivalence class, NB only a single character can match
+      if(set_->cequivalents)
+      {
+         charT a[2] = { col, charT(0), };
+         s1 = traits_inst.transform_primary(a, a +1);
+         for(i = 0; i < set_->cequivalents; ++i)
+         {
+            if(STR_COMP(s1, p) == 0)
+               return set_->isnot ? next : ++next;
+            // skip string
+            do{ ++p; }while(*p);
+            ++p;
+         }
+      }
+   }
+   if(traits_inst.isctype(col, set_->cclasses) == true)
+      return set_->isnot ? next : ++next;
+   if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))
+      return set_->isnot ? next : ++next;
+   return set_->isnot ? ++next : next;
+}
+
+template <class BidiIterator>
+class repeater_count
+{
+   repeater_count** stack;
+   repeater_count* next;
+   int state_id;
+   std::size_t count;        // the number of iterations so far
+   BidiIterator start_pos;   // where the last repeat started
+public:
+   repeater_count(repeater_count** s)
+   {
+      stack = s;
+      next = 0;
+      state_id = -1;
+      count = 0;
+   }
+   repeater_count(int i, repeater_count** s, BidiIterator start)
+      : start_pos(start)
+   {
+      state_id = i;
+      stack = s;
+      next = *stack;
+      *stack = this;
+      if(state_id > next->state_id)
+         count = 0;
+      else
+      {
+         repeater_count* p = next;
+         while(p && (p->state_id != state_id))
+            p = p->next;
+         if(p)
+         {
+            count = p->count;
+            start_pos = p->start_pos;
+         }
+         else
+            count = 0;
+      }
+   }
+   ~repeater_count()
+   {
+      if(next)
+         *stack = next;
+   }
+   std::size_t get_count() { return count; }
+   int get_id() { return state_id; }
+   std::size_t operator++() { return ++count; }
+   bool check_null_repeat(const BidiIterator& pos, std::size_t max)
+   {
+      // this is called when we are about to start a new repeat,
+      // if the last one was NULL move our count to max,
+      // otherwise save the current position.
+      bool result = (count == 0) ? false : (pos == start_pos);
+      if(result)
+         count = max;
+      else
+         start_pos = pos;
+      return result;
+   }
+};
+
+struct saved_state;
+
+enum saved_state_type
+{
+   saved_type_end = 0,
+   saved_type_paren = 1,
+   saved_type_recurse = 2,
+   saved_type_assertion = 3,
+   saved_state_alt = 4,
+   saved_state_repeater_count = 5,
+   saved_state_extra_block = 6,
+   saved_state_greedy_single_repeat = 7,
+   saved_state_rep_slow_dot = 8,
+   saved_state_rep_fast_dot = 9,
+   saved_state_rep_char = 10,
+   saved_state_rep_short_set = 11,
+   saved_state_rep_long_set = 12,
+   saved_state_non_greedy_long_repeat = 13, 
+   saved_state_count = 14
+};
+
+template <class Results>
+struct recursion_info
+{
+   typedef typename Results::value_type value_type;
+   typedef typename value_type::iterator iterator;
+   int idx;
+   const re_syntax_base* preturn_address;
+   Results results;
+   repeater_count<iterator>* repeater_stack;
+};
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231)
+#  if NDNBOOST_MSVC < 1600
+#     pragma warning(disable : 4660)
+#  endif
+#endif
+
+template <class BidiIterator, class Allocator, class traits>
+class perl_matcher
+{
+public:
+   typedef typename traits::char_type char_type;
+   typedef perl_matcher<BidiIterator, Allocator, traits> self_type;
+   typedef bool (self_type::*matcher_proc_type)(void);
+   typedef std::size_t traits_size_type;
+   typedef typename is_byte<char_type>::width_type width_type;
+   typedef typename regex_iterator_traits<BidiIterator>::difference_type difference_type;
+   typedef match_results<BidiIterator, Allocator> results_type;
+
+   perl_matcher(BidiIterator first, BidiIterator end, 
+      match_results<BidiIterator, Allocator>& what, 
+      const basic_regex<char_type, traits>& e,
+      match_flag_type f,
+      BidiIterator l_base)
+      :  m_result(what), base(first), last(end), 
+         position(first), backstop(l_base), re(e), traits_inst(e.get_traits()), 
+         m_independent(false), next_count(&rep_obj), rep_obj(&next_count)
+   {
+      construct_init(e, f);
+   }
+
+   bool match();
+   bool find();
+
+   void setf(match_flag_type f)
+   { m_match_flags |= f; }
+   void unsetf(match_flag_type f)
+   { m_match_flags &= ~f; }
+
+private:
+   void construct_init(const basic_regex<char_type, traits>& e, match_flag_type f);
+
+   bool find_imp();
+   bool match_imp();
+#ifdef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+   typedef bool (perl_matcher::*protected_proc_type)();
+   bool protected_call(protected_proc_type);
+#endif
+   void estimate_max_state_count(std::random_access_iterator_tag*);
+   void estimate_max_state_count(void*);
+   bool match_prefix();
+   bool match_all_states();
+
+   // match procs, stored in s_match_vtable:
+   bool match_startmark();
+   bool match_endmark();
+   bool match_literal();
+   bool match_start_line();
+   bool match_end_line();
+   bool match_wild();
+   bool match_match();
+   bool match_word_boundary();
+   bool match_within_word();
+   bool match_word_start();
+   bool match_word_end();
+   bool match_buffer_start();
+   bool match_buffer_end();
+   bool match_backref();
+   bool match_long_set();
+   bool match_set();
+   bool match_jump();
+   bool match_alt();
+   bool match_rep();
+   bool match_combining();
+   bool match_soft_buffer_end();
+   bool match_restart_continue();
+   bool match_long_set_repeat();
+   bool match_set_repeat();
+   bool match_char_repeat();
+   bool match_dot_repeat_fast();
+   bool match_dot_repeat_slow();
+   bool match_dot_repeat_dispatch()
+   {
+      return ::ndnboost::is_random_access_iterator<BidiIterator>::value ? match_dot_repeat_fast() : match_dot_repeat_slow();
+   }
+   bool match_backstep();
+   bool match_assert_backref();
+   bool match_toggle_case();
+#ifdef NDNBOOST_REGEX_RECURSIVE
+   bool backtrack_till_match(std::size_t count);
+#endif
+   bool match_recursion();
+
+   // find procs stored in s_find_vtable:
+   bool find_restart_any();
+   bool find_restart_word();
+   bool find_restart_line();
+   bool find_restart_buf();
+   bool find_restart_lit();
+
+private:
+   // final result structure to be filled in:
+   match_results<BidiIterator, Allocator>& m_result;
+   // temporary result for POSIX matches:
+   scoped_ptr<match_results<BidiIterator, Allocator> > m_temp_match;
+   // pointer to actual result structure to fill in:
+   match_results<BidiIterator, Allocator>* m_presult;
+   // start of sequence being searched:
+   BidiIterator base;
+   // end of sequence being searched:
+   BidiIterator last; 
+   // current character being examined:
+   BidiIterator position;
+   // where to restart next search after failed match attempt:
+   BidiIterator restart;
+   // where the current search started from, acts as base for $` during grep:
+   BidiIterator search_base;
+   // how far we can go back when matching lookbehind:
+   BidiIterator backstop;
+   // the expression being examined:
+   const basic_regex<char_type, traits>& re;
+   // the expression's traits class:
+   const ::ndnboost::regex_traits_wrapper<traits>& traits_inst;
+   // the next state in the machine being matched:
+   const re_syntax_base* pstate;
+   // matching flags in use:
+   match_flag_type m_match_flags;
+   // how many states we have examined so far:
+   std::ptrdiff_t state_count;
+   // max number of states to examine before giving up:
+   std::ptrdiff_t max_state_count;
+   // whether we should ignore case or not:
+   bool icase;
+   // set to true when (position == last), indicates that we may have a partial match:
+   bool m_has_partial_match;
+   // set to true whenever we get a match:
+   bool m_has_found_match;
+   // set to true whenever we're inside an independent sub-expression:
+   bool m_independent;
+   // the current repeat being examined:
+   repeater_count<BidiIterator>* next_count;
+   // the first repeat being examined (top of linked list):
+   repeater_count<BidiIterator> rep_obj;
+   // the mask to pass when matching word boundaries:
+   typename traits::char_class_type m_word_mask;
+   // the bitmask to use when determining whether a match_any matches a newline or not:
+   unsigned char match_any_mask;
+   // recursion information:
+   std::vector<recursion_info<results_type> > recursion_stack;
+
+#ifdef NDNBOOST_REGEX_NON_RECURSIVE
+   //
+   // additional members for non-recursive version:
+   //
+   typedef bool (self_type::*unwind_proc_type)(bool);
+
+   void extend_stack();
+   bool unwind(bool);
+   bool unwind_end(bool);
+   bool unwind_paren(bool);
+   bool unwind_recursion_stopper(bool);
+   bool unwind_assertion(bool);
+   bool unwind_alt(bool);
+   bool unwind_repeater_counter(bool);
+   bool unwind_extra_block(bool);
+   bool unwind_greedy_single_repeat(bool);
+   bool unwind_slow_dot_repeat(bool);
+   bool unwind_fast_dot_repeat(bool);
+   bool unwind_char_repeat(bool);
+   bool unwind_short_set_repeat(bool);
+   bool unwind_long_set_repeat(bool);
+   bool unwind_non_greedy_repeat(bool);
+   bool unwind_recursion(bool);
+   bool unwind_recursion_pop(bool);
+   void destroy_single_repeat();
+   void push_matched_paren(int index, const sub_match<BidiIterator>& sub);
+   void push_recursion_stopper();
+   void push_assertion(const re_syntax_base* ps, bool positive);
+   void push_alt(const re_syntax_base* ps);
+   void push_repeater_count(int i, repeater_count<BidiIterator>** s);
+   void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);
+   void push_non_greedy_repeat(const re_syntax_base* ps);
+   void push_recursion(int idx, const re_syntax_base* p, results_type* presults);
+   void push_recursion_pop();
+
+   // pointer to base of stack:
+   saved_state* m_stack_base;
+   // pointer to current stack position:
+   saved_state* m_backup_state;
+   // determines what value to return when unwinding from recursion,
+   // allows for mixed recursive/non-recursive algorithm:
+   bool m_recursive_result;
+   // how many memory blocks have we used up?:
+   unsigned used_block_count;
+#endif
+
+   // these operations aren't allowed, so are declared private,
+   // bodies are provided to keep explicit-instantiation requests happy:
+   perl_matcher& operator=(const perl_matcher&)
+   {
+      return *this;
+   }
+   perl_matcher(const perl_matcher& that)
+      : m_result(that.m_result), re(that.re), traits_inst(that.traits_inst), rep_obj(0) {}
+};
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace re_detail
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+//
+// include the implementation of perl_matcher:
+//
+#ifdef NDNBOOST_REGEX_RECURSIVE
+#include <ndnboost/regex/v4/perl_matcher_recursive.hpp>
+#else
+#include <ndnboost/regex/v4/perl_matcher_non_recursive.hpp>
+#endif
+// this one has to be last:
+#include <ndnboost/regex/v4/perl_matcher_common.hpp>
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/perl_matcher_common.hpp b/include/ndnboost/regex/v4/perl_matcher_common.hpp
new file mode 100644
index 0000000..5d5fed0
--- /dev/null
+++ b/include/ndnboost/regex/v4/perl_matcher_common.hpp
@@ -0,0 +1,996 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         perl_matcher_common.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Definitions of perl_matcher member functions that are 
+  *                common to both the recursive and non-recursive versions.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
+#define NDNBOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef __BORLANDC__
+#  pragma option push -w-8008 -w-8066
+#endif
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable: 4800)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)
+{ 
+   typedef typename regex_iterator_traits<BidiIterator>::iterator_category category;
+   typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;
+   
+   if(e.empty())
+   {
+      // precondition failure: e is not a valid regex.
+      std::invalid_argument ex("Invalid regular expression object");
+      ndnboost::throw_exception(ex);
+   }
+   pstate = 0;
+   m_match_flags = f;
+   estimate_max_state_count(static_cast<category*>(0));
+   expression_flag_type re_f = re.flags();
+   icase = re_f & regex_constants::icase;
+   if(!(m_match_flags & (match_perl|match_posix)))
+   {
+      if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
+         m_match_flags |= match_perl;
+      else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
+         m_match_flags |= match_perl;
+      else if((re_f & (regbase::main_option_type|regbase::literal)) == (regbase::literal))
+         m_match_flags |= match_perl;
+      else
+         m_match_flags |= match_posix;
+   }
+   if(m_match_flags & match_posix)
+   {
+      m_temp_match.reset(new match_results<BidiIterator, Allocator>());
+      m_presult = m_temp_match.get();
+   }
+   else
+      m_presult = &m_result;
+#ifdef NDNBOOST_REGEX_NON_RECURSIVE
+   m_stack_base = 0;
+   m_backup_state = 0;
+#endif
+   // find the value to use for matching word boundaries:
+   m_word_mask = re.get_data().m_word_mask; 
+   // find bitmask to use for matching '.':
+   match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? re_detail::test_not_newline : re_detail::test_newline);
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
+{
+   //
+   // How many states should we allow our machine to visit before giving up?
+   // This is a heuristic: it takes the greater of O(N^2) and O(NS^2)
+   // where N is the length of the string, and S is the number of states
+   // in the machine.  It's tempting to up this to O(N^2S) or even O(N^2S^2)
+   // but these take unreasonably amounts of time to bale out in pathological
+   // cases.
+   //
+   // Calculate NS^2 first:
+   //
+   static const std::ptrdiff_t k = 100000;
+   std::ptrdiff_t dist = ndnboost::re_detail::distance(base, last);
+   if(dist == 0)
+      dist = 1;
+   std::ptrdiff_t states = re.size();
+   if(states == 0)
+      states = 1;
+   states *= states;
+   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
+   {
+      max_state_count = (std::min)((std::ptrdiff_t)NDNBOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
+      return;
+   }
+   states *= dist;
+   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
+   {
+      max_state_count = (std::min)((std::ptrdiff_t)NDNBOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
+      return;
+   }
+   states += k;
+
+   max_state_count = states;
+
+   //
+   // Now calculate N^2:
+   //
+   states = dist;
+   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
+   {
+      max_state_count = (std::min)((std::ptrdiff_t)NDNBOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
+      return;
+   }
+   states *= dist;
+   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
+   {
+      max_state_count = (std::min)((std::ptrdiff_t)NDNBOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
+      return;
+   }
+   states += k;
+   //
+   // N^2 can be a very large number indeed, to prevent things getting out
+   // of control, cap the max states:
+   //
+   if(states > NDNBOOST_REGEX_MAX_STATE_COUNT)
+      states = NDNBOOST_REGEX_MAX_STATE_COUNT;
+   //
+   // If (the possibly capped) N^2 is larger than our first estimate,
+   // use this instead:
+   //
+   if(states > max_state_count)
+      max_state_count = states;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
+{
+   // we don't know how long the sequence is:
+   max_state_count = NDNBOOST_REGEX_MAX_STATE_COUNT;
+}
+
+#ifdef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
+   protected_proc_type proc)
+{
+   ::ndnboost::re_detail::concrete_protected_call
+      <perl_matcher<BidiIterator, Allocator, traits> >
+      obj(this, proc);
+   return obj.execute();
+
+}
+#endif
+
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::match()
+{
+#ifdef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+   return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::match_imp);
+#else
+   return match_imp();
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
+{
+   // initialise our stack if we are non-recursive:
+#ifdef NDNBOOST_REGEX_NON_RECURSIVE
+   save_state_init init(&m_stack_base, &m_backup_state);
+   used_block_count = NDNBOOST_REGEX_MAX_BLOCKS;
+#if !defined(NDNBOOST_NO_EXCEPTIONS)
+   try{
+#endif
+#endif
+
+   // reset our state machine:
+   position = base;
+   search_base = base;
+   state_count = 0;
+   m_match_flags |= regex_constants::match_all;
+   m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
+   m_presult->set_base(base);
+   m_presult->set_named_subs(this->re.get_named_subs());
+   if(m_match_flags & match_posix)
+      m_result = *m_presult;
+   verify_options(re.flags(), m_match_flags);
+   if(0 == match_prefix())
+      return false;
+   return (m_result[0].second == last) && (m_result[0].first == base);
+
+#if defined(NDNBOOST_REGEX_NON_RECURSIVE) && !defined(NDNBOOST_NO_EXCEPTIONS)
+   }
+   catch(...)
+   {
+      // unwind all pushed states, apart from anything else this
+      // ensures that all the states are correctly destructed
+      // not just the memory freed.
+      while(unwind(true)){}
+      throw;
+   }
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::find()
+{
+#ifdef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+   return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::find_imp);
+#else
+   return find_imp();
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
+{
+   static matcher_proc_type const s_find_vtable[7] = 
+   {
+      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
+      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
+      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
+      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
+      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
+      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
+   };
+
+   // initialise our stack if we are non-recursive:
+#ifdef NDNBOOST_REGEX_NON_RECURSIVE
+   save_state_init init(&m_stack_base, &m_backup_state);
+   used_block_count = NDNBOOST_REGEX_MAX_BLOCKS;
+#if !defined(NDNBOOST_NO_EXCEPTIONS)
+   try{
+#endif
+#endif
+
+   state_count = 0;
+   if((m_match_flags & regex_constants::match_init) == 0)
+   {
+      // reset our state machine:
+      search_base = position = base;
+      pstate = re.get_first_state();
+      m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last);
+      m_presult->set_base(base);
+      m_presult->set_named_subs(this->re.get_named_subs());
+      m_match_flags |= regex_constants::match_init;
+   }
+   else
+   {
+      // start again:
+      search_base = position = m_result[0].second;
+      // If last match was null and match_not_null was not set then increment
+      // our start position, otherwise we go into an infinite loop:
+      if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))
+      {
+         if(position == last)
+            return false;
+         else 
+            ++position;
+      }
+      // reset $` start:
+      m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
+      //if((base != search_base) && (base == backstop))
+      //   m_match_flags |= match_prev_avail;
+   }
+   if(m_match_flags & match_posix)
+   {
+      m_result.set_size(re.mark_count(), base, last);
+      m_result.set_base(base);
+   }
+
+   verify_options(re.flags(), m_match_flags);
+   // find out what kind of expression we have:
+   unsigned type = (m_match_flags & match_continuous) ? 
+      static_cast<unsigned int>(regbase::restart_continue) 
+         : static_cast<unsigned int>(re.get_restart_type());
+
+   // call the appropriate search routine:
+   matcher_proc_type proc = s_find_vtable[type];
+   return (this->*proc)();
+
+#if defined(NDNBOOST_REGEX_NON_RECURSIVE) && !defined(NDNBOOST_NO_EXCEPTIONS)
+   }
+   catch(...)
+   {
+      // unwind all pushed states, apart from anything else this
+      // ensures that all the states are correctly destructed
+      // not just the memory freed.
+      while(unwind(true)){}
+      throw;
+   }
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()
+{
+   m_has_partial_match = false;
+   m_has_found_match = false;
+   pstate = re.get_first_state();
+   m_presult->set_first(position);
+   restart = position;
+   match_all_states();
+   if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))
+   {
+      m_has_found_match = true;
+      m_presult->set_second(last, 0, false);
+      position = last;
+      if((m_match_flags & match_posix) == match_posix)
+      {
+         m_result.maybe_assign(*m_presult);
+      }
+   }
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+   if(m_has_found_match && (match_extra & m_match_flags))
+   {
+      //
+      // we have a match, reverse the capture information:
+      //
+      for(unsigned i = 0; i < m_presult->size(); ++i)
+      {
+         typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();
+         std::reverse(seq.begin(), seq.end());
+      }
+   }
+#endif
+   if(!m_has_found_match)
+      position = restart; // reset search postion
+   return m_has_found_match;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
+{
+   unsigned int len = static_cast<const re_literal*>(pstate)->length;
+   const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
+   //
+   // compare string with what we stored in
+   // our records:
+   for(unsigned int i = 0; i < len; ++i, ++position)
+   {
+      if((position == last) || (traits_inst.translate(*position, icase) != what[i]))
+         return false;
+   }
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
+{
+   if(position == backstop)
+   {
+      if((m_match_flags & match_prev_avail) == 0)
+      {
+         if((m_match_flags & match_not_bol) == 0)
+         {
+            pstate = pstate->next.p;
+            return true;
+         }
+         return false;
+      }
+   }
+   else if(m_match_flags & match_single_line)
+      return false;
+
+   // check the previous value character:
+   BidiIterator t(position);
+   --t;
+   if(position != last)
+   {
+      if(is_separator(*t) && !((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n'))) )
+      {
+         pstate = pstate->next.p;
+         return true;
+      }
+   }
+   else if(is_separator(*t))
+   {
+      pstate = pstate->next.p;
+      return true;
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
+{
+   if(position != last)
+   {
+      if(m_match_flags & match_single_line)
+         return false;
+      // we're not yet at the end so *first is always valid:
+      if(is_separator(*position))
+      {
+         if((position != backstop) || (m_match_flags & match_prev_avail))
+         {
+            // check that we're not in the middle of \r\n sequence
+            BidiIterator t(position);
+            --t;
+            if((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n')))
+            {
+               return false;
+            }
+         }
+         pstate = pstate->next.p;
+         return true;
+      }
+   }
+   else if((m_match_flags & match_not_eol) == 0)
+   {
+      pstate = pstate->next.p;
+      return true;
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
+{
+   if(position == last) 
+      return false;
+   if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))
+      return false;
+   if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
+      return false;
+   pstate = pstate->next.p;
+   ++position;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
+{
+   bool b; // indcates whether next character is a word character
+   if(position != last)
+   {
+      // prev and this character must be opposites:
+   #if defined(NDNBOOST_REGEX_USE_C_LOCALE) && defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
+      b = traits::isctype(*position, m_word_mask);
+   #else
+      b = traits_inst.isctype(*position, m_word_mask);
+   #endif
+   }
+   else
+   {
+      b = (m_match_flags & match_not_eow) ? true : false;
+   }
+   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+   {
+      if(m_match_flags & match_not_bow)
+         b ^= true;
+      else
+         b ^= false;
+   }
+   else
+   {
+      --position;
+      b ^= traits_inst.isctype(*position, m_word_mask);
+      ++position;
+   }
+   if(b)
+   {
+      pstate = pstate->next.p;
+      return true;
+   }
+   return false; // no match if we get to here...
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
+{
+   if(position == last)
+      return false;
+   // both prev and this character must be m_word_mask:
+   bool prev = traits_inst.isctype(*position, m_word_mask);
+   {
+      bool b;
+      if((position == backstop) && ((m_match_flags & match_prev_avail) == 0)) 
+         return false;
+      else
+      {
+         --position;
+         b = traits_inst.isctype(*position, m_word_mask);
+         ++position;
+      }
+      if(b == prev)
+      {
+         pstate = pstate->next.p;
+         return true;
+      }
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
+{
+   if(position == last)
+      return false; // can't be starting a word if we're already at the end of input
+   if(!traits_inst.isctype(*position, m_word_mask))
+      return false; // next character isn't a word character
+   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+   {
+      if(m_match_flags & match_not_bow)
+         return false; // no previous input
+   }
+   else
+   {
+      // otherwise inside buffer:
+      BidiIterator t(position);
+      --t;
+      if(traits_inst.isctype(*t, m_word_mask))
+         return false; // previous character not non-word
+   }
+   // OK we have a match:
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
+{
+   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+      return false;  // start of buffer can't be end of word
+   BidiIterator t(position);
+   --t;
+   if(traits_inst.isctype(*t, m_word_mask) == false)
+      return false;  // previous character wasn't a word character
+
+   if(position == last)
+   {
+      if(m_match_flags & match_not_eow)
+         return false; // end of buffer but not end of word
+   }
+   else
+   {
+      // otherwise inside buffer:
+      if(traits_inst.isctype(*position, m_word_mask))
+         return false; // next character is a word character
+   }
+   pstate = pstate->next.p;
+   return true;      // if we fall through to here then we've succeeded
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
+{
+   if((position != backstop) || (m_match_flags & match_not_bob))
+      return false;
+   // OK match:
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()
+{
+   if((position != last) || (m_match_flags & match_not_eob))
+      return false;
+   // OK match:
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_backref()
+{
+   //
+   // Compare with what we previously matched.
+   // Note that this succeeds if the backref did not partisipate
+   // in the match, this is in line with ECMAScript, but not Perl
+   // or PCRE.
+   //
+   int index = static_cast<const re_brace*>(pstate)->index;
+   if(index >= 10000)
+   {
+      named_subexpressions::range_type r = re.get_data().equal_range(index);
+      NDNBOOST_ASSERT(r.first != r.second);
+      do
+      {
+         index = r.first->index;
+         ++r.first;
+      }while((r.first != r.second) && ((*m_presult)[index].matched != true));
+   }
+
+   if((m_match_flags & match_perl) && !(*m_presult)[index].matched)
+      return false;
+
+   BidiIterator i = (*m_presult)[index].first;
+   BidiIterator j = (*m_presult)[index].second;
+   while(i != j)
+   {
+      if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))
+         return false;
+      ++i;
+      ++position;
+   }
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
+{
+   typedef typename traits::char_class_type char_class_type;
+   // let the traits class do the work:
+   if(position == last)
+      return false;
+   BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);
+   if(t != position)
+   {
+      pstate = pstate->next.p;
+      position = t;
+      return true;
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_set()
+{
+   if(position == last)
+      return false;
+   if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+   {
+      pstate = pstate->next.p;
+      ++position;
+      return true;
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_jump()
+{
+   pstate = static_cast<const re_jump*>(pstate)->alt.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_combining()
+{
+   if(position == last)
+      return false;
+   if(is_combining(traits_inst.translate(*position, icase)))
+      return false;
+   ++position;
+   while((position != last) && is_combining(traits_inst.translate(*position, icase)))
+      ++position;
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()
+{
+   if(m_match_flags & match_not_eob)
+      return false;
+   BidiIterator p(position);
+   while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;
+   if(p != last)
+      return false;
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
+{
+   if(position == search_base)
+   {
+      pstate = pstate->next.p;
+      return true;
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   if( ::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      std::ptrdiff_t maxlen = ::ndnboost::re_detail::distance(backstop, position);
+      if(maxlen < static_cast<const re_brace*>(pstate)->index)
+         return false;
+      std::advance(position, -static_cast<const re_brace*>(pstate)->index);
+   }
+   else
+   {
+      int c = static_cast<const re_brace*>(pstate)->index;
+      while(c--)
+      {
+         if(position == backstop)
+            return false;
+         --position;
+      }
+   }
+   pstate = pstate->next.p;
+   return true;
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()
+{
+   // return true if marked sub-expression N has been matched:
+   int index = static_cast<const re_brace*>(pstate)->index;
+   bool result = false;
+   if(index == 9999)
+   {
+      // Magic value for a (DEFINE) block:
+      return false;
+   }
+   else if(index > 0)
+   {
+      // Have we matched subexpression "index"?
+      // Check if index is a hash value:
+      if(index >= 10000)
+      {
+         named_subexpressions::range_type r = re.get_data().equal_range(index);
+         while(r.first != r.second)
+         {
+            if((*m_presult)[r.first->index].matched)
+            {
+               result = true;
+               break;
+            }
+            ++r.first;
+         }
+      }
+      else
+      {
+         result = (*m_presult)[index].matched;
+      }
+      pstate = pstate->next.p;
+   }
+   else
+   {
+      // Have we recursed into subexpression "index"?
+      // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.
+      int idx = -index-1;
+      if(idx >= 10000)
+      {
+         named_subexpressions::range_type r = re.get_data().equal_range(idx);
+         int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx;
+         while(r.first != r.second)
+         {
+            result |= (stack_index == r.first->index);
+            if(result)break;
+            ++r.first;
+         }
+      }
+      else
+      {
+         result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0));
+      }
+      pstate = pstate->next.p;
+   }
+   return result;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()
+{
+   // change our case sensitivity:
+   this->icase = static_cast<const re_case*>(pstate)->icase;
+   pstate = pstate->next.p;
+   return true;
+}
+
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   const unsigned char* _map = re.get_map();
+   while(true)
+   {
+      // skip everything we can't match:
+      while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )
+         ++position;
+      if(position == last)
+      {
+         // run out of characters, try a null match if possible:
+         if(re.can_be_null())
+            return match_prefix();
+         break;
+      }
+      // now try and obtain a match:
+      if(match_prefix())
+         return true;
+      if(position == last)
+         return false;
+      ++position;
+   }
+   return false;
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   // do search optimised for word starts:
+   const unsigned char* _map = re.get_map();
+   if((m_match_flags & match_prev_avail) || (position != base))
+      --position;
+   else if(match_prefix())
+      return true;
+   do
+   {
+      while((position != last) && traits_inst.isctype(*position, m_word_mask))
+         ++position;
+      while((position != last) && !traits_inst.isctype(*position, m_word_mask))
+         ++position;
+      if(position == last)
+         break;
+
+      if(can_start(*position, _map, (unsigned char)mask_any) )
+      {
+         if(match_prefix())
+            return true;
+      }
+      if(position == last)
+         break;
+   } while(true);
+   return false;
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()
+{
+   // do search optimised for line starts:
+   const unsigned char* _map = re.get_map();
+   if(match_prefix())
+      return true;
+   while(position != last)
+   {
+      while((position != last) && !is_separator(*position))
+         ++position;
+      if(position == last)
+         return false;
+      ++position;
+      if(position == last)
+      {
+         if(re.can_be_null() && match_prefix())
+            return true;
+         return false;
+      }
+
+      if( can_start(*position, _map, (unsigned char)mask_any) )
+      {
+         if(match_prefix())
+            return true;
+      }
+      if(position == last)
+         return false;
+      //++position;
+   }
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()
+{
+   if((position == base) && ((m_match_flags & match_not_bob) == 0))
+      return match_prefix();
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()
+{
+#if 0
+   if(position == last)
+      return false; // can't possibly match if we're at the end already
+
+   unsigned type = (m_match_flags & match_continuous) ? 
+      static_cast<unsigned int>(regbase::restart_continue) 
+         : static_cast<unsigned int>(re.get_restart_type());
+
+   const kmp_info<char_type>* info = access::get_kmp(re);
+   int len = info->len;
+   const char_type* x = info->pstr;
+   int j = 0; 
+   while (position != last) 
+   {
+      while((j > -1) && (x[j] != traits_inst.translate(*position, icase))) 
+         j = info->kmp_next[j];
+      ++position;
+      ++j;
+      if(j >= len) 
+      {
+         if(type == regbase::restart_fixed_lit)
+         {
+            std::advance(position, -j);
+            restart = position;
+            std::advance(restart, len);
+            m_result.set_first(position);
+            m_result.set_second(restart);
+            position = restart;
+            return true;
+         }
+         else
+         {
+            restart = position;
+            std::advance(position, -j);
+            if(match_prefix())
+               return true;
+            else
+            {
+               for(int k = 0; (restart != position) && (k < j); ++k, --restart)
+                     {} // dwa 10/20/2000 - warning suppression for MWCW
+               if(restart != last)
+                  ++restart;
+               position = restart;
+               j = 0;  //we could do better than this...
+            }
+         }
+      }
+   }
+   if((m_match_flags & match_partial) && (position == last) && j)
+   {
+      // we need to check for a partial match:
+      restart = position;
+      std::advance(position, -j);
+      return match_prefix();
+   }
+#endif
+   return false;
+}
+
+} // namespace re_detail
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+#ifdef __BORLANDC__
+#  pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/perl_matcher_non_recursive.hpp b/include/ndnboost/regex/v4/perl_matcher_non_recursive.hpp
new file mode 100644
index 0000000..c28856c
--- /dev/null
+++ b/include/ndnboost/regex/v4/perl_matcher_non_recursive.hpp
@@ -0,0 +1,1642 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         perl_matcher_common.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Definitions of perl_matcher member functions that are 
+  *                specific to the non-recursive implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP
+#define NDNBOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP
+
+#include <new>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable: 4800)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+template <class T>
+inline void inplace_destroy(T* p)
+{
+   (void)p;  // warning suppression
+   p->~T();
+}
+
+struct saved_state
+{
+   union{
+      unsigned int state_id;
+      // this padding ensures correct alignment on 64-bit platforms:
+      std::size_t padding1;
+      std::ptrdiff_t padding2;
+      void* padding3;
+   };
+   saved_state(unsigned i) : state_id(i) {}
+};
+
+template <class BidiIterator>
+struct saved_matched_paren : public saved_state
+{
+   int index;
+   sub_match<BidiIterator> sub;
+   saved_matched_paren(int i, const sub_match<BidiIterator>& s) : saved_state(1), index(i), sub(s){};
+};
+
+template <class BidiIterator>
+struct saved_position : public saved_state
+{
+   const re_syntax_base* pstate;
+   BidiIterator position;
+   saved_position(const re_syntax_base* ps, BidiIterator pos, int i) : saved_state(i), pstate(ps), position(pos){};
+};
+
+template <class BidiIterator>
+struct saved_assertion : public saved_position<BidiIterator>
+{
+   bool positive;
+   saved_assertion(bool p, const re_syntax_base* ps, BidiIterator pos) 
+      : saved_position<BidiIterator>(ps, pos, saved_type_assertion), positive(p){};
+};
+
+template <class BidiIterator>
+struct saved_repeater : public saved_state
+{
+   repeater_count<BidiIterator> count;
+   saved_repeater(int i, repeater_count<BidiIterator>** s, BidiIterator start) 
+      : saved_state(saved_state_repeater_count), count(i,s,start){}
+};
+
+struct saved_extra_block : public saved_state
+{
+   saved_state *base, *end;
+   saved_extra_block(saved_state* b, saved_state* e) 
+      : saved_state(saved_state_extra_block), base(b), end(e) {}
+};
+
+struct save_state_init
+{
+   saved_state** stack;
+   save_state_init(saved_state** base, saved_state** end)
+      : stack(base)
+   {
+      *base = static_cast<saved_state*>(get_mem_block());
+      *end = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(*base)+NDNBOOST_REGEX_BLOCKSIZE);
+      --(*end);
+      (void) new (*end)saved_state(0);
+      NDNBOOST_ASSERT(*end > *base);
+   }
+   ~save_state_init()
+   {
+      put_mem_block(*stack);
+      *stack = 0;
+   }
+};
+
+template <class BidiIterator>
+struct saved_single_repeat : public saved_state
+{
+   std::size_t count;
+   const re_repeat* rep;
+   BidiIterator last_position;
+   saved_single_repeat(std::size_t c, const re_repeat* r, BidiIterator lp, int arg_id) 
+      : saved_state(arg_id), count(c), rep(r), last_position(lp){}
+};
+
+template <class Results>
+struct saved_recursion : public saved_state
+{
+   saved_recursion(int idx, const re_syntax_base* p, Results* pr) 
+      : saved_state(14), recursion_id(idx), preturn_address(p), results(*pr)
+   {}
+   int recursion_id;
+   const re_syntax_base* preturn_address;
+   Results results;
+};
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
+{
+   static matcher_proc_type const s_match_vtable[30] = 
+   {
+      (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
+      &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_literal,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_wild,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_match,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_backref,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_set,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_jump,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_alt,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_rep,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_combining,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
+      // Although this next line *should* be evaluated at compile time, in practice
+      // some compilers (VC++) emit run-time initialisation which breaks thread
+      // safety, so use a dispatch function instead:
+      //(::ndnboost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
+      &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
+   };
+
+   push_recursion_stopper();
+   do{
+      while(pstate)
+      {
+         matcher_proc_type proc = s_match_vtable[pstate->type];
+         ++state_count;
+         if(!(this->*proc)())
+         {
+            if(state_count > max_state_count)
+               raise_error(traits_inst, regex_constants::error_complexity);
+            if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+               m_has_partial_match = true;
+            bool successful_unwind = unwind(false);
+            if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+               m_has_partial_match = true;
+            if(false == successful_unwind)
+               return m_recursive_result;
+         }
+      }
+   }while(unwind(true));
+   return m_recursive_result;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
+{
+   if(used_block_count)
+   {
+      --used_block_count;
+      saved_state* stack_base;
+      saved_state* backup_state;
+      stack_base = static_cast<saved_state*>(get_mem_block());
+      backup_state = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(stack_base)+NDNBOOST_REGEX_BLOCKSIZE);
+      saved_extra_block* block = static_cast<saved_extra_block*>(backup_state);
+      --block;
+      (void) new (block) saved_extra_block(m_stack_base, m_backup_state);
+      m_stack_base = stack_base;
+      m_backup_state = block;
+   }
+   else
+      raise_error(traits_inst, regex_constants::error_stack);
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
+{
+   //NDNBOOST_ASSERT(index);
+   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_matched_paren<BidiIterator>(index, sub);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()
+{
+   saved_state* pmp = m_backup_state;
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = m_backup_state;
+      --pmp;
+   }
+   (void) new (pmp)saved_state(saved_type_recurse);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)
+{
+   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_assertion<BidiIterator>(positive, ps, position);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)
+{
+   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_alt);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)
+{
+   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
+{
+   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_repeater<BidiIterator>(i, s, position);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id)
+{
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_single_repeat<BidiIterator>(c, r, last_position, state_id);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults)
+{
+   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_recursion<results_type>(idx, p, presults);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
+{
+   int index = static_cast<const re_brace*>(pstate)->index;
+   icase = static_cast<const re_brace*>(pstate)->icase;
+   switch(index)
+   {
+   case 0:
+      pstate = pstate->next.p;
+      break;
+   case -1:
+   case -2:
+      {
+         // forward lookahead assert:
+         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+         pstate = pstate->next.p->next.p;
+         push_assertion(next_pstate, index == -1);
+         break;
+      }
+   case -3:
+      {
+         // independent sub-expression, currently this is always recursive:
+         bool old_independent = m_independent;
+         m_independent = true;
+         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+         pstate = pstate->next.p->next.p;
+         bool r = match_all_states();
+         pstate = next_pstate;
+         m_independent = old_independent;
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+         if(r && (m_match_flags & match_extra))
+         {
+            //
+            // our captures have been stored in *m_presult
+            // we need to unpack them, and insert them
+            // back in the right order when we unwind the stack:
+            //
+            match_results<BidiIterator, Allocator> temp_match(*m_presult);
+            unsigned i;
+            for(i = 0; i < temp_match.size(); ++i)
+               (*m_presult)[i].get_captures().clear();
+            // match everything else:
+            r = match_all_states();
+            // now place the stored captures back:
+            for(i = 0; i < temp_match.size(); ++i)
+            {
+               typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
+               seq& s1 = (*m_presult)[i].get_captures();
+               const seq& s2 = temp_match[i].captures();
+               s1.insert(
+                  s1.end(), 
+                  s2.begin(), 
+                  s2.end());
+            }
+         }
+#endif
+         return r;
+      }
+   case -4:
+      {
+      // conditional expression:
+      const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
+      NDNBOOST_ASSERT(alt->type == syntax_element_alt);
+      pstate = alt->next.p;
+      if(pstate->type == syntax_element_assert_backref)
+      {
+         if(!match_assert_backref())
+            pstate = alt->alt.p;
+         break;
+      }
+      else
+      {
+         // zero width assertion, have to match this recursively:
+         NDNBOOST_ASSERT(pstate->type == syntax_element_startmark);
+         bool negated = static_cast<const re_brace*>(pstate)->index == -2;
+         BidiIterator saved_position = position;
+         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+         pstate = pstate->next.p->next.p;
+         bool r = match_all_states();
+         position = saved_position;
+         if(negated)
+            r = !r;
+         if(r)
+            pstate = next_pstate;
+         else
+            pstate = alt->alt.p;
+         break;
+      }
+      }
+   case -5:
+      {
+         push_matched_paren(0, (*m_presult)[0]);
+         m_presult->set_first(position, 0, true);
+         pstate = pstate->next.p;
+         break;
+      }
+   default:
+   {
+      NDNBOOST_ASSERT(index > 0);
+      if((m_match_flags & match_nosubs) == 0)
+      {
+         push_matched_paren(index, (*m_presult)[index]);
+         m_presult->set_first(position, index);
+      }
+      pstate = pstate->next.p;
+      break;
+   }
+   }
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
+{
+   bool take_first, take_second;
+   const re_alt* jmp = static_cast<const re_alt*>(pstate);
+
+   // find out which of these two alternatives we need to take:
+   if(position == last)
+   {
+      take_first = jmp->can_be_null & mask_take;
+      take_second = jmp->can_be_null & mask_skip;
+   }
+   else
+   {
+      take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
+      take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
+  }
+
+   if(take_first)
+   {
+      // we can take the first alternative,
+      // see if we need to push next alternative:
+      if(take_second)
+      {
+         push_alt(jmp->alt.p);
+      }
+      pstate = pstate->next.p;
+      return true;
+   }
+   if(take_second)
+   {
+      pstate = jmp->alt.p;
+      return true;
+   }
+   return false;  // neither option is possible
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127 4244)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+
+   // find out which of these two alternatives we need to take:
+   bool take_first, take_second;
+   if(position == last)
+   {
+      take_first = rep->can_be_null & mask_take;
+      take_second = rep->can_be_null & mask_skip;
+   }
+   else
+   {
+      take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
+      take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
+   }
+
+   if((m_backup_state->state_id != saved_state_repeater_count) 
+      || (static_cast<saved_repeater<BidiIterator>*>(m_backup_state)->count.get_id() != rep->state_id)
+      || (next_count->get_id() != rep->state_id))
+   {
+      // we're moving to a different repeat from the last
+      // one, so set up a counter object:
+      push_repeater_count(rep->state_id, &next_count);
+   }
+   //
+   // If we've had at least one repeat already, and the last one 
+   // matched the NULL string then set the repeat count to
+   // maximum:
+   //
+   next_count->check_null_repeat(position, rep->max);
+
+   if(next_count->get_count() < rep->min)
+   {
+      // we must take the repeat:
+      if(take_first)
+      {
+         // increase the counter:
+         ++(*next_count);
+         pstate = rep->next.p;
+         return true;
+      }
+      return false;
+   }
+
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   if(greedy)
+   {
+      // try and take the repeat if we can:
+      if((next_count->get_count() < rep->max) && take_first)
+      {
+         if(take_second)
+         {
+            // store position in case we fail:
+            push_alt(rep->alt.p);
+         }
+         // increase the counter:
+         ++(*next_count);
+         pstate = rep->next.p;
+         return true;
+      }
+      else if(take_second)
+      {
+         pstate = rep->alt.p;
+         return true;
+      }
+      return false; // can't take anything, fail...
+   }
+   else // non-greedy
+   {
+      // try and skip the repeat if we can:
+      if(take_second)
+      {
+         if((next_count->get_count() < rep->max) && take_first)
+         {
+            // store position in case we fail:
+            push_non_greedy_repeat(rep->next.p);
+         }
+         pstate = rep->alt.p;
+         return true;
+      }
+      if((next_count->get_count() < rep->max) && take_first)
+      {
+         // increase the counter:
+         ++(*next_count);
+         pstate = rep->next.p;
+         return true;
+      }
+   }
+   return false;
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
+{
+   unsigned count = 0;
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   re_syntax_base* psingle = rep->next.p;
+   // match compulsary repeats first:
+   while(count < rep->min)
+   {
+      pstate = psingle;
+      if(!match_wild())
+         return false;
+      ++count;
+   }
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   if(greedy)
+   {
+      // repeat for as long as we can:
+      while(count < rep->max)
+      {
+         pstate = psingle;
+         if(!match_wild())
+            break;
+         ++count;
+      }
+      // remember where we got to if this is a leading repeat:
+      if((rep->leading) && (count < rep->max))
+         restart = position;
+      // push backtrack info if available:
+      if(count - rep->min)
+         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+      // jump to next state:
+      pstate = rep->alt.p;
+      return true;
+   }
+   else
+   {
+      // non-greedy, push state and return true if we can skip:
+      if(count < rep->max)
+         push_single_repeat(count, rep, position, saved_state_rep_slow_dot);
+      pstate = rep->alt.p;
+      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+   }
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
+{
+   if(m_match_flags & match_not_dot_null)
+      return match_dot_repeat_slow();
+   if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
+      return match_dot_repeat_slow();
+
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   unsigned count = static_cast<unsigned>((std::min)(static_cast<unsigned>(::ndnboost::re_detail::distance(position, last)), static_cast<unsigned>(greedy ? rep->max : rep->min)));
+   if(rep->min > count)
+   {
+      position = last;
+      return false;  // not enough text left to match
+   }
+   std::advance(position, count);
+
+   if(greedy)
+   {
+      if((rep->leading) && (count < rep->max))
+         restart = position;
+      // push backtrack info if available:
+      if(count - rep->min)
+         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+      // jump to next state:
+      pstate = rep->alt.p;
+      return true;
+   }
+   else
+   {
+      // non-greedy, push state and return true if we can skip:
+      if(count < rep->max)
+         push_single_repeat(count, rep, position, saved_state_rep_fast_dot);
+      pstate = rep->alt.p;
+      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+   }
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   NDNBOOST_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
+   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
+   std::size_t count = 0;
+   //
+   // start by working out how much we can skip:
+   //
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t desired = greedy ? rep->max : rep->min;
+   if(::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      BidiIterator end = position;
+      std::advance(end, (std::min)((std::size_t)::ndnboost::re_detail::distance(position, last), desired));
+      BidiIterator origin(position);
+      while((position != end) && (traits_inst.translate(*position, icase) == what))
+      {
+         ++position;
+      }
+      count = (unsigned)::ndnboost::re_detail::distance(origin, position);
+   }
+   else
+   {
+      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
+      {
+         ++position;
+         ++count;
+      }
+   }
+
+   if(count < rep->min)
+      return false;
+
+   if(greedy)
+   {
+      if((rep->leading) && (count < rep->max))
+         restart = position;
+      // push backtrack info if available:
+      if(count - rep->min)
+         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+      // jump to next state:
+      pstate = rep->alt.p;
+      return true;
+   }
+   else
+   {
+      // non-greedy, push state and return true if we can skip:
+      if(count < rep->max)
+         push_single_repeat(count, rep, position, saved_state_rep_char);
+      pstate = rep->alt.p;
+      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+   }
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
+   std::size_t count = 0;
+   //
+   // start by working out how much we can skip:
+   //
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t desired = greedy ? rep->max : rep->min;
+   if(::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      BidiIterator end = position;
+      std::advance(end, (std::min)((std::size_t)::ndnboost::re_detail::distance(position, last), desired));
+      BidiIterator origin(position);
+      while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+      {
+         ++position;
+      }
+      count = (unsigned)::ndnboost::re_detail::distance(origin, position);
+   }
+   else
+   {
+      while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+      {
+         ++position;
+         ++count;
+      }
+   }
+
+   if(count < rep->min)
+      return false;
+
+   if(greedy)
+   {
+      if((rep->leading) && (count < rep->max))
+         restart = position;
+      // push backtrack info if available:
+      if(count - rep->min)
+         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+      // jump to next state:
+      pstate = rep->alt.p;
+      return true;
+   }
+   else
+   {
+      // non-greedy, push state and return true if we can skip:
+      if(count < rep->max)
+         push_single_repeat(count, rep, position, saved_state_rep_short_set);
+      pstate = rep->alt.p;
+      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+   }
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   typedef typename traits::char_class_type m_type;
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate->next.p);
+   std::size_t count = 0;
+   //
+   // start by working out how much we can skip:
+   //
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t desired = greedy ? rep->max : rep->min;
+   if(::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      BidiIterator end = position;
+      std::advance(end, (std::min)((std::size_t)::ndnboost::re_detail::distance(position, last), desired));
+      BidiIterator origin(position);
+      while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+      {
+         ++position;
+      }
+      count = (unsigned)::ndnboost::re_detail::distance(origin, position);
+   }
+   else
+   {
+      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+      {
+         ++position;
+         ++count;
+      }
+   }
+
+   if(count < rep->min)
+      return false;
+
+   if(greedy)
+   {
+      if((rep->leading) && (count < rep->max))
+         restart = position;
+      // push backtrack info if available:
+      if(count - rep->min)
+         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+      // jump to next state:
+      pstate = rep->alt.p;
+      return true;
+   }
+   else
+   {
+      // non-greedy, push state and return true if we can skip:
+      if(count < rep->max)
+         push_single_repeat(count, rep, position, saved_state_rep_long_set);
+      pstate = rep->alt.p;
+      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+   }
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
+{
+   NDNBOOST_ASSERT(pstate->type == syntax_element_recurse);
+   //
+   // Backup call stack:
+   //
+   push_recursion_pop();
+   //
+   // Set new call stack:
+   //
+   if(recursion_stack.capacity() == 0)
+   {
+      recursion_stack.reserve(50);
+   }
+   recursion_stack.push_back(recursion_info<results_type>());
+   recursion_stack.back().preturn_address = pstate->next.p;
+   recursion_stack.back().results = *m_presult;
+   if(static_cast<const re_recurse*>(pstate)->state_id > 0)
+   {
+      push_repeater_count(static_cast<const re_recurse*>(pstate)->state_id, &next_count);
+   }
+   pstate = static_cast<const re_jump*>(pstate)->alt.p;
+   recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
+
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
+{
+   int index = static_cast<const re_brace*>(pstate)->index;
+   icase = static_cast<const re_brace*>(pstate)->icase;
+   if(index > 0)
+   {
+      if((m_match_flags & match_nosubs) == 0)
+      {
+         m_presult->set_second(position, index);
+      }
+      if(!recursion_stack.empty())
+      {
+         if(index == recursion_stack.back().idx)
+         {
+            pstate = recursion_stack.back().preturn_address;
+            *m_presult = recursion_stack.back().results;
+            push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results);
+            recursion_stack.pop_back();
+         }
+      }
+   }
+   else if((index < 0) && (index != -4))
+   {
+      // matched forward lookahead:
+      pstate = 0;
+      return true;
+   }
+   pstate = pstate->next.p;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
+{
+   if(!recursion_stack.empty())
+   {
+      NDNBOOST_ASSERT(0 == recursion_stack.back().idx);
+      pstate = recursion_stack.back().preturn_address;
+      *m_presult = recursion_stack.back().results;
+      push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results);
+      recursion_stack.pop_back();
+      return true;
+   }
+   if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
+      return false;
+   if((m_match_flags & match_all) && (position != last))
+      return false;
+   if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
+      return false;
+   m_presult->set_second(position);
+   pstate = 0;
+   m_has_found_match = true;
+   if((m_match_flags & match_posix) == match_posix)
+   {
+      m_result.maybe_assign(*m_presult);
+      if((m_match_flags & match_any) == 0)
+         return false;
+   }
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+   if(match_extra & m_match_flags)
+   {
+      for(unsigned i = 0; i < m_presult->size(); ++i)
+         if((*m_presult)[i].matched)
+            ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
+   }
+#endif
+   return true;
+}
+
+/****************************************************************************
+
+Unwind and associated proceedures follow, these perform what normal stack
+unwinding does in the recursive implementation.
+
+****************************************************************************/
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
+{
+   static unwind_proc_type const s_unwind_table[18] = 
+   {
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,
+      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,
+   };
+
+   m_recursive_result = have_match;
+   unwind_proc_type unwinder;
+   bool cont;
+   //
+   // keep unwinding our stack until we have something to do:
+   //
+   do
+   {
+      unwinder = s_unwind_table[m_backup_state->state_id];
+      cont = (this->*unwinder)(m_recursive_result);
+   }while(cont);
+   //
+   // return true if we have more states to try:
+   //
+   return pstate ? true : false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)
+{
+   pstate = 0;   // nothing left to search
+   return false; // end of stack nothing more to search
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)
+{
+   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
+   // restore previous values if no match was found:
+   if(have_match == false)
+   {
+      m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);
+      m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);
+   }
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+   //
+   // we have a match, push the capture information onto the stack:
+   //
+   else if(pmp->sub.matched && (match_extra & m_match_flags))
+      ((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);
+#endif
+   // unwind stack:
+   m_backup_state = pmp+1;
+   ndnboost::re_detail::inplace_destroy(pmp);
+   return true; // keep looking
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)
+{
+   ndnboost::re_detail::inplace_destroy(m_backup_state++);
+   pstate = 0;   // nothing left to search
+   return false; // end of stack nothing more to search
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)
+{
+   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
+   pstate = pmp->pstate;
+   position = pmp->position;
+   bool result = (r == pmp->positive);
+   m_recursive_result = pmp->positive ? r : !r;
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return !result; // return false if the assertion was matched to stop search.
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)
+{
+   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+   if(!r)
+   {
+      pstate = pmp->pstate;
+      position = pmp->position;
+   }
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return r; 
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)
+{
+   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return true; // keep looking
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)
+{
+   saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);
+   void* condemmed = m_stack_base;
+   m_stack_base = pmp->base;
+   m_backup_state = pmp->end;
+   ndnboost::re_detail::inplace_destroy(pmp);
+   put_mem_block(condemmed);
+   return true; // keep looking
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()
+{
+   saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+   ndnboost::re_detail::inplace_destroy(p++);
+   m_backup_state = p;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)
+{
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+   // if we have a match, just discard this state:
+   if(r) 
+   {
+      destroy_single_repeat();
+      return true;
+   }
+
+   const re_repeat* rep = pmp->rep;
+   std::size_t count = pmp->count;
+   NDNBOOST_ASSERT(rep->next.p != 0);
+   NDNBOOST_ASSERT(rep->alt.p != 0);
+
+   count -= rep->min;
+   
+   if((m_match_flags & match_partial) && (position == last))
+      m_has_partial_match = true;
+
+   NDNBOOST_ASSERT(count);
+   position = pmp->last_position;
+
+   // backtrack till we can skip out:
+   do
+   {
+      --position;
+      --count;
+      ++state_count;
+   }while(count && !can_start(*position, rep->_map, mask_skip));
+
+   // if we've hit base, destroy this state:
+   if(count == 0)
+   {
+         destroy_single_repeat();
+         if(!can_start(*position, rep->_map, mask_skip))
+            return true;
+   }
+   else
+   {
+      pmp->count = count + rep->min;
+      pmp->last_position = position;
+   }
+   pstate = rep->alt.p;
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)
+{
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+   // if we have a match, just discard this state:
+   if(r) 
+   {
+      destroy_single_repeat();
+      return true;
+   }
+
+   const re_repeat* rep = pmp->rep;
+   std::size_t count = pmp->count;
+   NDNBOOST_ASSERT(rep->type == syntax_element_dot_rep);
+   NDNBOOST_ASSERT(rep->next.p != 0);
+   NDNBOOST_ASSERT(rep->alt.p != 0);
+   NDNBOOST_ASSERT(rep->next.p->type == syntax_element_wild);
+
+   NDNBOOST_ASSERT(count < rep->max);
+   pstate = rep->next.p;
+   position = pmp->last_position;
+
+   if(position != last)
+   {
+      // wind forward until we can skip out of the repeat:
+      do
+      {
+         if(!match_wild())
+         {
+            // failed repeat match, discard this state and look for another:
+            destroy_single_repeat();
+            return true;
+         }
+         ++count;
+         ++state_count;
+         pstate = rep->next.p;
+      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+   }   
+   if(position == last)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+         m_has_partial_match = true;
+      if(0 == (rep->can_be_null & mask_skip))
+         return true;
+   }
+   else if(count == rep->max)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if(!can_start(*position, rep->_map, mask_skip))
+         return true;
+   }
+   else
+   {
+      pmp->count = count;
+      pmp->last_position = position;
+   }
+   pstate = rep->alt.p;
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)
+{
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+   // if we have a match, just discard this state:
+   if(r) 
+   {
+      destroy_single_repeat();
+      return true;
+   }
+
+   const re_repeat* rep = pmp->rep;
+   std::size_t count = pmp->count;
+
+   NDNBOOST_ASSERT(count < rep->max);
+   position = pmp->last_position;
+   if(position != last)
+   {
+
+      // wind forward until we can skip out of the repeat:
+      do
+      {
+         ++position;
+         ++count;
+         ++state_count;
+      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+   }
+
+   // remember where we got to if this is a leading repeat:
+   if((rep->leading) && (count < rep->max))
+      restart = position;
+   if(position == last)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+         m_has_partial_match = true;
+      if(0 == (rep->can_be_null & mask_skip))
+         return true;
+   }
+   else if(count == rep->max)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if(!can_start(*position, rep->_map, mask_skip))
+         return true;
+   }
+   else
+   {
+      pmp->count = count;
+      pmp->last_position = position;
+   }
+   pstate = rep->alt.p;
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)
+{
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+   // if we have a match, just discard this state:
+   if(r) 
+   {
+      destroy_single_repeat();
+      return true;
+   }
+
+   const re_repeat* rep = pmp->rep;
+   std::size_t count = pmp->count;
+   pstate = rep->next.p;
+   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
+   position = pmp->last_position;
+
+   NDNBOOST_ASSERT(rep->type == syntax_element_char_rep);
+   NDNBOOST_ASSERT(rep->next.p != 0);
+   NDNBOOST_ASSERT(rep->alt.p != 0);
+   NDNBOOST_ASSERT(rep->next.p->type == syntax_element_literal);
+   NDNBOOST_ASSERT(count < rep->max);
+
+   if(position != last)
+   {
+      // wind forward until we can skip out of the repeat:
+      do
+      {
+         if(traits_inst.translate(*position, icase) != what)
+         {
+            // failed repeat match, discard this state and look for another:
+            destroy_single_repeat();
+            return true;
+         }
+         ++count;
+         ++ position;
+         ++state_count;
+         pstate = rep->next.p;
+      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+   }   
+   // remember where we got to if this is a leading repeat:
+   if((rep->leading) && (count < rep->max))
+      restart = position;
+   if(position == last)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+         m_has_partial_match = true;
+      if(0 == (rep->can_be_null & mask_skip))
+         return true;
+   }
+   else if(count == rep->max)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if(!can_start(*position, rep->_map, mask_skip))
+         return true;
+   }
+   else
+   {
+      pmp->count = count;
+      pmp->last_position = position;
+   }
+   pstate = rep->alt.p;
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)
+{
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+   // if we have a match, just discard this state:
+   if(r) 
+   {
+      destroy_single_repeat();
+      return true;
+   }
+
+   const re_repeat* rep = pmp->rep;
+   std::size_t count = pmp->count;
+   pstate = rep->next.p;
+   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
+   position = pmp->last_position;
+
+   NDNBOOST_ASSERT(rep->type == syntax_element_short_set_rep);
+   NDNBOOST_ASSERT(rep->next.p != 0);
+   NDNBOOST_ASSERT(rep->alt.p != 0);
+   NDNBOOST_ASSERT(rep->next.p->type == syntax_element_set);
+   NDNBOOST_ASSERT(count < rep->max);
+   
+   if(position != last)
+   {
+      // wind forward until we can skip out of the repeat:
+      do
+      {
+         if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+         {
+            // failed repeat match, discard this state and look for another:
+            destroy_single_repeat();
+            return true;
+         }
+         ++count;
+         ++ position;
+         ++state_count;
+         pstate = rep->next.p;
+      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+   }   
+   // remember where we got to if this is a leading repeat:
+   if((rep->leading) && (count < rep->max))
+      restart = position;
+   if(position == last)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+         m_has_partial_match = true;
+      if(0 == (rep->can_be_null & mask_skip))
+         return true;
+   }
+   else if(count == rep->max)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if(!can_start(*position, rep->_map, mask_skip))
+         return true;
+   }
+   else
+   {
+      pmp->count = count;
+      pmp->last_position = position;
+   }
+   pstate = rep->alt.p;
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)
+{
+   typedef typename traits::char_class_type m_type;
+   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+   // if we have a match, just discard this state:
+   if(r)
+   {
+      destroy_single_repeat();
+      return true;
+   }
+
+   const re_repeat* rep = pmp->rep;
+   std::size_t count = pmp->count;
+   pstate = rep->next.p;
+   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate);
+   position = pmp->last_position;
+
+   NDNBOOST_ASSERT(rep->type == syntax_element_long_set_rep);
+   NDNBOOST_ASSERT(rep->next.p != 0);
+   NDNBOOST_ASSERT(rep->alt.p != 0);
+   NDNBOOST_ASSERT(rep->next.p->type == syntax_element_long_set);
+   NDNBOOST_ASSERT(count < rep->max);
+
+   if(position != last)
+   {
+      // wind forward until we can skip out of the repeat:
+      do
+      {
+         if(position == re_is_set_member(position, last, set, re.get_data(), icase))
+         {
+            // failed repeat match, discard this state and look for another:
+            destroy_single_repeat();
+            return true;
+         }
+         ++position;
+         ++count;
+         ++state_count;
+         pstate = rep->next.p;
+      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+   }   
+   // remember where we got to if this is a leading repeat:
+   if((rep->leading) && (count < rep->max))
+      restart = position;
+   if(position == last)
+   {
+      // can't repeat any more, remove the pushed state:
+      destroy_single_repeat();
+      if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+         m_has_partial_match = true;
+      if(0 == (rep->can_be_null & mask_skip))
+         return true;
+   }
+   else if(count == rep->max)
+   {
+      // can't repeat any more, remove the pushed state: 
+      destroy_single_repeat();
+      if(!can_start(*position, rep->_map, mask_skip))
+         return true;
+   }
+   else
+   {
+      pmp->count = count;
+      pmp->last_position = position;
+   }
+   pstate = rep->alt.p;
+   return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)
+{
+   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+   if(!r)
+   {
+      position = pmp->position;
+      pstate = pmp->pstate;
+      ++(*next_count);
+   }
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return r;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)
+{
+   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+   if(!r)
+   {
+      recursion_stack.push_back(recursion_info<results_type>());
+      recursion_stack.back().idx = pmp->recursion_id;
+      recursion_stack.back().preturn_address = pmp->preturn_address;
+      recursion_stack.back().results = pmp->results;
+   }
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)
+{
+   saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+   if(!r)
+   {
+      recursion_stack.pop_back();
+   }
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()
+{
+   saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_state*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_state(15);
+   m_backup_state = pmp;
+}
+/*
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_pop(bool r)
+{
+   saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+   if(!r)
+   {
+      --parenthesis_stack_position;
+   }
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_pop()
+{
+   saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_state*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_state(16);
+   m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_push(bool r)
+{
+   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+   if(!r)
+   {
+      parenthesis_stack[parenthesis_stack_position++] = pmp->position;
+   }
+   ndnboost::re_detail::inplace_destroy(pmp++);
+   m_backup_state = pmp;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_push(BidiIterator p)
+{
+   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+   --pmp;
+   if(pmp < m_stack_base)
+   {
+      extend_stack();
+      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+      --pmp;
+   }
+   (void) new (pmp)saved_position<BidiIterator>(0, p, 17);
+   m_backup_state = pmp;
+}
+*/
+} // namespace re_detail
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
diff --git a/include/ndnboost/regex/v4/perl_matcher_recursive.hpp b/include/ndnboost/regex/v4/perl_matcher_recursive.hpp
new file mode 100644
index 0000000..d5ee6bb
--- /dev/null
+++ b/include/ndnboost/regex/v4/perl_matcher_recursive.hpp
@@ -0,0 +1,991 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         perl_matcher_common.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Definitions of perl_matcher member functions that are 
+  *                specific to the recursive implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP
+#define NDNBOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4800)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+template <class BidiIterator>
+class backup_subex
+{
+   int index;
+   sub_match<BidiIterator> sub;
+public:
+   template <class A>
+   backup_subex(const match_results<BidiIterator, A>& w, int i)
+      : index(i), sub(w[i], false) {}
+   template <class A>
+   void restore(match_results<BidiIterator, A>& w)
+   {
+      w.set_first(sub.first, index, index == 0);
+      w.set_second(sub.second, index, sub.matched, index == 0);
+   }
+   const sub_match<BidiIterator>& get() { return sub; }
+};
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
+{
+   static matcher_proc_type const s_match_vtable[30] = 
+   {
+      (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
+      &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_literal,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_wild,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_match,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_backref,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_set,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_jump,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_alt,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_rep,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_combining,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
+      // Although this next line *should* be evaluated at compile time, in practice
+      // some compilers (VC++) emit run-time initialisation which breaks thread
+      // safety, so use a dispatch function instead:
+      //(::ndnboost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
+      &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
+      &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
+   };
+
+   if(state_count > max_state_count)
+      raise_error(traits_inst, regex_constants::error_complexity);
+   while(pstate)
+   {
+      matcher_proc_type proc = s_match_vtable[pstate->type];
+      ++state_count;
+      if(!(this->*proc)())
+      {
+         if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+            m_has_partial_match = true;
+         return 0;
+      }
+   }
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
+{
+   int index = static_cast<const re_brace*>(pstate)->index;
+   icase = static_cast<const re_brace*>(pstate)->icase;
+   bool r = true;
+   switch(index)
+   {
+   case 0:
+      pstate = pstate->next.p;
+      break;
+   case -1:
+   case -2:
+      {
+         // forward lookahead assert:
+         BidiIterator old_position(position);
+         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+         pstate = pstate->next.p->next.p;
+         r = match_all_states();
+         pstate = next_pstate;
+         position = old_position;
+         if((r && (index != -1)) || (!r && (index != -2)))
+            r = false;
+         else
+            r = true;
+         break;
+      }
+   case -3:
+      {
+         // independent sub-expression:
+         bool old_independent = m_independent;
+         m_independent = true;
+         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+         pstate = pstate->next.p->next.p;
+         r = match_all_states();
+         pstate = next_pstate;
+         m_independent = old_independent;
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+         if(r && (m_match_flags & match_extra))
+         {
+            //
+            // our captures have been stored in *m_presult
+            // we need to unpack them, and insert them
+            // back in the right order when we unwind the stack:
+            //
+            unsigned i;
+            match_results<BidiIterator, Allocator> tm(*m_presult);
+            for(i = 0; i < tm.size(); ++i)
+               (*m_presult)[i].get_captures().clear();
+            // match everything else:
+            r = match_all_states();
+            // now place the stored captures back:
+            for(i = 0; i < tm.size(); ++i)
+            {
+               typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
+               seq& s1 = (*m_presult)[i].get_captures();
+               const seq& s2 = tm[i].captures();
+               s1.insert(
+                  s1.end(), 
+                  s2.begin(), 
+                  s2.end());
+            }
+         }
+#endif
+         break;
+      }
+   case -4:
+      {
+      // conditional expression:
+      const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
+      NDNBOOST_ASSERT(alt->type == syntax_element_alt);
+      pstate = alt->next.p;
+      if(pstate->type == syntax_element_assert_backref)
+      {
+         if(!match_assert_backref())
+            pstate = alt->alt.p;
+         break;
+      }
+      else
+      {
+         // zero width assertion, have to match this recursively:
+         NDNBOOST_ASSERT(pstate->type == syntax_element_startmark);
+         bool negated = static_cast<const re_brace*>(pstate)->index == -2;
+         BidiIterator saved_position = position;
+         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+         pstate = pstate->next.p->next.p;
+         bool res = match_all_states();
+         position = saved_position;
+         if(negated)
+            res = !res;
+         if(res)
+            pstate = next_pstate;
+         else
+            pstate = alt->alt.p;
+         break;
+      }
+      }
+   case -5:
+      {
+         // Reset start of $0, since we have a \K escape
+         backup_subex<BidiIterator> sub(*m_presult, 0);
+         m_presult->set_first(position, 0, true);
+         pstate = pstate->next.p;
+         r = match_all_states();
+         if(r == false)
+            sub.restore(*m_presult);
+         break;
+      }
+   default:
+   {
+      NDNBOOST_ASSERT(index > 0);
+      if((m_match_flags & match_nosubs) == 0)
+      {
+         backup_subex<BidiIterator> sub(*m_presult, index);
+         m_presult->set_first(position, index);
+         pstate = pstate->next.p;
+         r = match_all_states();
+         if(r == false)
+            sub.restore(*m_presult);
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+         //
+         // we have a match, push the capture information onto the stack:
+         //
+         else if(sub.get().matched && (match_extra & m_match_flags))
+            ((*m_presult)[index]).get_captures().push_back(sub.get());
+#endif
+      }
+      else
+      {
+         pstate = pstate->next.p;
+      }
+      break;
+   }
+   }
+   return r;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
+{
+   bool take_first, take_second;
+   const re_alt* jmp = static_cast<const re_alt*>(pstate);
+
+   // find out which of these two alternatives we need to take:
+   if(position == last)
+   {
+      take_first = jmp->can_be_null & mask_take;
+      take_second = jmp->can_be_null & mask_skip;
+   }
+   else
+   {
+      take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
+      take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
+  }
+
+   if(take_first)
+   {
+      // we can take the first alternative,
+      // see if we need to push next alternative:
+      if(take_second)
+      {
+         BidiIterator oldposition(position);
+         const re_syntax_base* old_pstate = jmp->alt.p;
+         pstate = pstate->next.p;
+         if(!match_all_states())
+         {
+            pstate = old_pstate;
+            position = oldposition;
+         }
+         return true;
+      }
+      pstate = pstate->next.p;
+      return true;
+   }
+   if(take_second)
+   {
+      pstate = jmp->alt.p;
+      return true;
+   }
+   return false;  // neither option is possible
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127 4244)
+#endif
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   //
+   // Always copy the repeat count, so that the state is restored
+   // when we exit this scope:
+   //
+   repeater_count<BidiIterator> r(rep->state_id, &next_count, position);
+   //
+   // If we've had at least one repeat already, and the last one 
+   // matched the NULL string then set the repeat count to
+   // maximum:
+   //
+   next_count->check_null_repeat(position, rep->max);
+
+   // find out which of these two alternatives we need to take:
+   bool take_first, take_second;
+   if(position == last)
+   {
+      take_first = rep->can_be_null & mask_take;
+      take_second = rep->can_be_null & mask_skip;
+   }
+   else
+   {
+      take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
+      take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
+   }
+
+   if(next_count->get_count() < rep->min)
+   {
+      // we must take the repeat:
+      if(take_first)
+      {
+         // increase the counter:
+         ++(*next_count);
+         pstate = rep->next.p;
+         return match_all_states();
+      }
+      return false;
+   }
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   if(greedy)
+   {
+      // try and take the repeat if we can:
+      if((next_count->get_count() < rep->max) && take_first)
+      {
+         // store position in case we fail:
+         BidiIterator pos = position;
+         // increase the counter:
+         ++(*next_count);
+         pstate = rep->next.p;
+         if(match_all_states())
+            return true;
+         // failed repeat, reset posistion and fall through for alternative:
+         position = pos;
+      }
+      if(take_second)
+      {
+         pstate = rep->alt.p;
+         return true;
+      }
+      return false; // can't take anything, fail...
+   }
+   else // non-greedy
+   {
+      // try and skip the repeat if we can:
+      if(take_second)
+      {
+         // store position in case we fail:
+         BidiIterator pos = position;
+         pstate = rep->alt.p;
+         if(match_all_states())
+            return true;
+         // failed alternative, reset posistion and fall through for repeat:
+         position = pos;
+      }
+      if((next_count->get_count() < rep->max) && take_first)
+      {
+         // increase the counter:
+         ++(*next_count);
+         pstate = rep->next.p;
+         return match_all_states();
+      }
+   }
+   return false;
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   unsigned count = 0;
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   re_syntax_base* psingle = rep->next.p;
+   // match compulsary repeats first:
+   while(count < rep->min)
+   {
+      pstate = psingle;
+      if(!match_wild())
+         return false;
+      ++count;
+   }
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   if(greedy)
+   {
+      // normal repeat:
+      while(count < rep->max)
+      {
+         pstate = psingle;
+         if(!match_wild())
+            break;
+         ++count;
+      }
+      if((rep->leading) && (count < rep->max))
+         restart = position;
+      pstate = rep;
+      return backtrack_till_match(count - rep->min);
+   }
+   else
+   {
+      // non-greedy, keep trying till we get a match:
+      BidiIterator save_pos;
+      do
+      {
+         if((rep->leading) && (rep->max == UINT_MAX))
+            restart = position;
+         pstate = rep->alt.p;
+         save_pos = position;
+         ++state_count;
+         if(match_all_states())
+            return true;
+         if(count >= rep->max)
+            return false;
+         ++count;
+         pstate = psingle;
+         position = save_pos;
+         if(!match_wild())
+            return false;
+      }while(true);
+   }
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   if(m_match_flags & match_not_dot_null)
+      return match_dot_repeat_slow();
+   if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
+      return match_dot_repeat_slow();
+   //
+   // start by working out how much we can skip:
+   //
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4267)
+#endif
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t count = (std::min)(static_cast<std::size_t>(::ndnboost::re_detail::distance(position, last)), static_cast<std::size_t>(greedy ? rep->max : rep->min));
+   if(rep->min > count)
+   {
+      position = last;
+      return false;  // not enough text left to match
+   }
+   std::advance(position, count);
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+   if((rep->leading) && (count < rep->max) && greedy)
+      restart = position;
+   if(greedy)
+      return backtrack_till_match(count - rep->min);
+
+   // non-greedy, keep trying till we get a match:
+   BidiIterator save_pos;
+   do
+   {
+      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+      {
+         ++position;
+         ++count;
+      }
+      if((rep->leading) && (rep->max == UINT_MAX))
+         restart = position;
+      pstate = rep->alt.p;
+      save_pos = position;
+      ++state_count;
+      if(match_all_states())
+         return true;
+      if(count >= rep->max)
+         return false;
+      if(save_pos == last)
+         return false;
+      position = ++save_pos;
+      ++count;
+   }while(true);
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#pragma warning(disable:4267)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   NDNBOOST_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
+   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
+   //
+   // start by working out how much we can skip:
+   //
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t count, desired;
+   if(::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      desired = 
+         (std::min)(
+            (std::size_t)(greedy ? rep->max : rep->min),
+            (std::size_t)::ndnboost::re_detail::distance(position, last));
+      count = desired;
+      ++desired;
+      if(icase)
+      {
+         while(--desired && (traits_inst.translate_nocase(*position) == what))
+         {
+            ++position;
+         }
+      }
+      else
+      {
+         while(--desired && (traits_inst.translate(*position) == what))
+         {
+            ++position;
+         }
+      }
+      count = count - desired;
+   }
+   else
+   {
+      count = 0;
+      desired = greedy ? rep->max : rep->min;
+      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
+      {
+         ++position;
+         ++count;
+      }
+   }
+   if((rep->leading) && (count < rep->max) && greedy)
+      restart = position;
+   if(count < rep->min)
+      return false;
+
+   if(greedy)
+      return backtrack_till_match(count - rep->min);
+
+   // non-greedy, keep trying till we get a match:
+   BidiIterator save_pos;
+   do
+   {
+      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+      {
+         if((traits_inst.translate(*position, icase) == what))
+         {
+            ++position;
+            ++count;
+         }
+         else
+            return false;  // counldn't repeat even though it was the only option
+      }
+      if((rep->leading) && (rep->max == UINT_MAX))
+         restart = position;
+      pstate = rep->alt.p;
+      save_pos = position;
+      ++state_count;
+      if(match_all_states())
+         return true;
+      if(count >= rep->max)
+         return false;
+      position = save_pos;
+      if(position == last)
+         return false;
+      if(traits_inst.translate(*position, icase) == what)
+      {
+         ++position;
+         ++count;
+      }
+      else
+      {
+         return false;
+      }
+   }while(true);
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
+   unsigned count = 0;
+   //
+   // start by working out how much we can skip:
+   //
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t desired = greedy ? rep->max : rep->min;
+   if(::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      BidiIterator end = position;
+      std::advance(end, (std::min)((std::size_t)::ndnboost::re_detail::distance(position, last), desired));
+      BidiIterator origin(position);
+      while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+      {
+         ++position;
+      }
+      count = (unsigned)::ndnboost::re_detail::distance(origin, position);
+   }
+   else
+   {
+      while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+      {
+         ++position;
+         ++count;
+      }
+   }
+   if((rep->leading) && (count < rep->max) && greedy)
+      restart = position;
+   if(count < rep->min)
+      return false;
+
+   if(greedy)
+      return backtrack_till_match(count - rep->min);
+
+   // non-greedy, keep trying till we get a match:
+   BidiIterator save_pos;
+   do
+   {
+      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+      {
+         if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+         {
+            ++position;
+            ++count;
+         }
+         else
+            return false;  // counldn't repeat even though it was the only option
+      }
+      if((rep->leading) && (rep->max == UINT_MAX))
+         restart = position;
+      pstate = rep->alt.p;
+      save_pos = position;
+      ++state_count;
+      if(match_all_states())
+         return true;
+      if(count >= rep->max)
+         return false;
+      position = save_pos;
+      if(position == last)
+         return false;
+      if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+      {
+         ++position;
+         ++count;
+      }
+      else
+      {
+         return false;
+      }
+   }while(true);
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+   typedef typename traits::char_class_type char_class_type;
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   const re_set_long<char_class_type>* set = static_cast<const re_set_long<char_class_type>*>(pstate->next.p);
+   unsigned count = 0;
+   //
+   // start by working out how much we can skip:
+   //
+   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   
+   std::size_t desired = greedy ? rep->max : rep->min;
+   if(::ndnboost::is_random_access_iterator<BidiIterator>::value)
+   {
+      BidiIterator end = position;
+      std::advance(end, (std::min)((std::size_t)::ndnboost::re_detail::distance(position, last), desired));
+      BidiIterator origin(position);
+      while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+      {
+         ++position;
+      }
+      count = (unsigned)::ndnboost::re_detail::distance(origin, position);
+   }
+   else
+   {
+      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+      {
+         ++position;
+         ++count;
+      }
+   }
+   if((rep->leading) && (count < rep->max) && greedy)
+      restart = position;
+   if(count < rep->min)
+      return false;
+
+   if(greedy)
+      return backtrack_till_match(count - rep->min);
+
+   // non-greedy, keep trying till we get a match:
+   BidiIterator save_pos;
+   do
+   {
+      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+      {
+         if(position != re_is_set_member(position, last, set, re.get_data(), icase))
+         {
+            ++position;
+            ++count;
+         }
+         else
+            return false;  // counldn't repeat even though it was the only option
+      }
+      if((rep->leading) && (rep->max == UINT_MAX))
+         restart = position;
+      pstate = rep->alt.p;
+      save_pos = position;
+      ++state_count;
+      if(match_all_states())
+         return true;
+      if(count >= rep->max)
+         return false;
+      position = save_pos;
+      if(position == last)
+         return false;
+      if(position != re_is_set_member(position, last, set, re.get_data(), icase))
+      {
+         ++position;
+         ++count;
+      }
+      else
+      {
+         return false;
+      }
+   }while(true);
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::backtrack_till_match(std::size_t count)
+{
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+   if((m_match_flags & match_partial) && (position == last))
+      m_has_partial_match = true;
+
+   const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+   BidiIterator backtrack = position;
+   if(position == last)
+   {
+      if(rep->can_be_null & mask_skip) 
+      {
+         pstate = rep->alt.p;
+         if(match_all_states())
+            return true;
+      }
+      if(count)
+      {
+         position = --backtrack;
+         --count;
+      }
+      else
+         return false;
+   }
+   do
+   {
+      while(count && !can_start(*position, rep->_map, mask_skip))
+      {
+         --position;
+         --count;
+         ++state_count;
+      }
+      pstate = rep->alt.p;
+      backtrack = position;
+      if(match_all_states())
+         return true;
+      if(count == 0)
+         return false;
+      position = --backtrack;
+      ++state_count;
+      --count;
+   }while(true);
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
+{
+   NDNBOOST_ASSERT(pstate->type == syntax_element_recurse);
+   //
+   // Set new call stack:
+   //
+   if(recursion_stack.capacity() == 0)
+   {
+      recursion_stack.reserve(50);
+   }
+   recursion_stack.push_back(recursion_info<results_type>());
+   recursion_stack.back().preturn_address = pstate->next.p;
+   recursion_stack.back().results = *m_presult;
+   recursion_stack.back().repeater_stack = next_count;
+   pstate = static_cast<const re_jump*>(pstate)->alt.p;
+   recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
+
+   repeater_count<BidiIterator>* saved = next_count;
+   repeater_count<BidiIterator> r(&next_count); // resets all repeat counts since we're recursing and starting fresh on those
+   next_count = &r;
+   bool result = match_all_states();
+   next_count = saved;
+
+   if(!result)
+   {
+      next_count = recursion_stack.back().repeater_stack;
+      *m_presult = recursion_stack.back().results;
+      recursion_stack.pop_back();
+      return false;
+   }
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
+{
+   int index = static_cast<const re_brace*>(pstate)->index;
+   icase = static_cast<const re_brace*>(pstate)->icase;
+   if(index > 0)
+   {
+      if((m_match_flags & match_nosubs) == 0)
+      {
+         m_presult->set_second(position, index);
+      }
+      if(!recursion_stack.empty())
+      {
+         if(index == recursion_stack.back().idx)
+         {
+            recursion_info<results_type> saved = recursion_stack.back();
+            recursion_stack.pop_back();
+            pstate = saved.preturn_address;
+            repeater_count<BidiIterator>* saved_count = next_count;
+            next_count = saved.repeater_stack;
+            *m_presult = saved.results;
+            if(!match_all_states())
+            {
+               recursion_stack.push_back(saved);
+               next_count = saved_count;
+               return false;
+            }
+         }
+      }
+   }
+   else if((index < 0) && (index != -4))
+   {
+      // matched forward lookahead:
+      pstate = 0;
+      return true;
+   }
+   pstate = pstate ? pstate->next.p : 0;
+   return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
+{
+   if(!recursion_stack.empty())
+   {
+      NDNBOOST_ASSERT(0 == recursion_stack.back().idx);
+      const re_syntax_base* saved_state = pstate = recursion_stack.back().preturn_address;
+      *m_presult = recursion_stack.back().results;
+      recursion_stack.pop_back();
+      if(!match_all_states())
+      {
+         recursion_stack.push_back(recursion_info<results_type>());
+         recursion_stack.back().preturn_address = saved_state;
+         recursion_stack.back().results = *m_presult;
+         return false;
+      }
+      return true;
+   }
+   if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
+      return false;
+   if((m_match_flags & match_all) && (position != last))
+      return false;
+   if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
+      return false;
+   m_presult->set_second(position);
+   pstate = 0;
+   m_has_found_match = true;
+   if((m_match_flags & match_posix) == match_posix)
+   {
+      m_result.maybe_assign(*m_presult);
+      if((m_match_flags & match_any) == 0)
+         return false;
+   }
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+   if(match_extra & m_match_flags)
+   {
+      for(unsigned i = 0; i < m_presult->size(); ++i)
+         if((*m_presult)[i].matched)
+            ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
+   }
+#endif
+   return true;
+}
+
+
+
+} // namespace re_detail
+} // namespace ndnboost
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/primary_transform.hpp b/include/ndnboost/regex/v4/primary_transform.hpp
new file mode 100644
index 0000000..0c9bc68
--- /dev/null
+++ b/include/ndnboost/regex/v4/primary_transform.hpp
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE:        primary_transform.hpp
+  *   VERSION:     see <ndnboost/version.hpp>
+  *   DESCRIPTION: Heuristically determines the sort string format in use
+  *                by the current locale.
+  */
+
+#ifndef NDNBOOST_REGEX_PRIMARY_TRANSFORM
+#define NDNBOOST_REGEX_PRIMARY_TRANSFORM
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+   namespace re_detail{
+
+
+enum{
+   sort_C,
+   sort_fixed,
+   sort_delim,
+   sort_unknown
+};
+
+template <class S, class charT>
+unsigned count_chars(const S& s, charT c)
+{
+   //
+   // Count how many occurances of character c occur
+   // in string s: if c is a delimeter between collation
+   // fields, then this should be the same value for all
+   // sort keys:
+   //
+   unsigned int count = 0;
+   for(unsigned pos = 0; pos < s.size(); ++pos)
+   {
+      if(s[pos] == c) ++count;
+   }
+   return count;
+}
+
+
+template <class traits, class charT>
+unsigned find_sort_syntax(const traits* pt, charT* delim)
+{
+   //
+   // compare 'a' with 'A' to see how similar they are,
+   // should really use a-accute but we can't portably do that,
+   //
+   typedef typename traits::string_type string_type;
+   typedef typename traits::char_type char_type;
+
+   // Suppress incorrect warning for MSVC
+   (void)pt;
+
+   char_type a[2] = {'a', '\0', };
+   string_type sa(pt->transform(a, a+1));
+   if(sa == a)
+   {
+      *delim = 0;
+      return sort_C;
+   }
+   char_type A[2] = { 'A', '\0', };
+   string_type sA(pt->transform(A, A+1));
+   char_type c[2] = { ';', '\0', };
+   string_type sc(pt->transform(c, c+1));
+
+   int pos = 0;
+   while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;
+   --pos;
+   if(pos < 0)
+   {
+      *delim = 0;
+      return sort_unknown;
+   }
+   //
+   // at this point sa[pos] is either the end of a fixed width field
+   // or the character that acts as a delimiter:
+   //
+   charT maybe_delim = sa[pos];
+   if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))
+   {
+      *delim = maybe_delim;
+      return sort_delim;
+   }
+   //
+   // OK doen't look like a delimiter, try for fixed width field:
+   //
+   if((sa.size() == sA.size()) && (sa.size() == sc.size()))
+   {
+      // note assumes that the fixed width field is less than
+      // (numeric_limits<charT>::max)(), should be true for all types
+      // I can't imagine 127 character fields...
+      *delim = static_cast<charT>(++pos);
+      return sort_fixed;
+   }
+   //
+   // don't know what it is:
+   //
+   *delim = 0;
+   return sort_unknown;
+}
+
+
+   } // namespace re_detail
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/protected_call.hpp b/include/ndnboost/regex/v4/protected_call.hpp
new file mode 100644
index 0000000..88615de
--- /dev/null
+++ b/include/ndnboost/regex/v4/protected_call.hpp
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         basic_regex_creator.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares template class basic_regex_creator which fills in
+  *                the data members of a regex_data object.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_PROTECTED_CALL_HPP
+#define NDNBOOST_REGEX_V4_PROTECTED_CALL_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+class NDNBOOST_REGEX_DECL abstract_protected_call
+{
+public:
+   bool NDNBOOST_REGEX_CALL execute()const;
+   // this stops gcc-4 from complaining:
+   virtual ~abstract_protected_call(){}
+private:
+   virtual bool call()const = 0;
+};
+
+template <class T>
+class concrete_protected_call
+   : public abstract_protected_call
+{
+public:
+   typedef bool (T::*proc_type)();
+   concrete_protected_call(T* o, proc_type p)
+      : obj(o), proc(p) {}
+private:
+   virtual bool call()const;
+   T* obj;
+   proc_type proc;
+};
+
+template <class T>
+bool concrete_protected_call<T>::call()const
+{
+   return (obj->*proc)();
+}
+
+}
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/ndnboost/regex/v4/regbase.hpp b/include/ndnboost/regex/v4/regbase.hpp
new file mode 100644
index 0000000..7c52468
--- /dev/null
+++ b/include/ndnboost/regex/v4/regbase.hpp
@@ -0,0 +1,180 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regbase.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares class regbase.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGBASE_HPP
+#define NDNBOOST_REGEX_V4_REGBASE_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+//
+// class regbase
+// handles error codes and flags
+//
+class NDNBOOST_REGEX_DECL regbase
+{
+public:
+   enum flag_type_
+   {
+      //
+      // Divide the flags up into logical groups:
+      // bits 0-7 indicate main synatx type.
+      // bits 8-15 indicate syntax subtype.
+      // bits 16-31 indicate options that are common to all
+      // regex syntaxes.
+      // In all cases the default is 0.
+      //
+      // Main synatx group:
+      //
+      perl_syntax_group = 0,                      // default
+      basic_syntax_group = 1,                     // POSIX basic
+      literal = 2,                                // all characters are literals
+      main_option_type = literal | basic_syntax_group | perl_syntax_group, // everything!
+      //
+      // options specific to perl group:
+      //
+      no_bk_refs = 1 << 8,                        // \d not allowed
+      no_perl_ex = 1 << 9,                        // disable perl extensions
+      no_mod_m = 1 << 10,                         // disable Perl m modifier
+      mod_x = 1 << 11,                            // Perl x modifier
+      mod_s = 1 << 12,                            // force s modifier on (overrides match_not_dot_newline)
+      no_mod_s = 1 << 13,                         // force s modifier off (overrides match_not_dot_newline)
+
+      //
+      // options specific to basic group:
+      //
+      no_char_classes = 1 << 8,                   // [[:CLASS:]] not allowed
+      no_intervals = 1 << 9,                      // {x,y} not allowed
+      bk_plus_qm = 1 << 10,                       // uses \+ and \?
+      bk_vbar = 1 << 11,                          // use \| for alternatives
+      emacs_ex = 1 << 12,                         // enables emacs extensions
+
+      //
+      // options common to all groups:
+      //
+      no_escape_in_lists = 1 << 16,                     // '\' not special inside [...]
+      newline_alt = 1 << 17,                            // \n is the same as |
+      no_except = 1 << 18,                              // no exception on error
+      failbit = 1 << 19,                                // error flag
+      icase = 1 << 20,                                  // characters are matched regardless of case
+      nocollate = 0,                                    // don't use locale specific collation (deprecated)
+      collate = 1 << 21,                                // use locale specific collation
+      nosubs = 1 << 22,                                 // don't mark sub-expressions
+      save_subexpression_location = 1 << 23,            // save subexpression locations
+      no_empty_expressions = 1 << 24,                   // no empty expressions allowed
+      optimize = 0,                                     // not really supported
+      
+
+
+      basic = basic_syntax_group | collate | no_escape_in_lists,
+      extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,
+      normal = 0,
+      emacs = basic_syntax_group | collate | emacs_ex | bk_vbar,
+      awk = no_bk_refs | collate | no_perl_ex,
+      grep = basic | newline_alt,
+      egrep = extended | newline_alt,
+      sed = basic,
+      perl = normal,
+      ECMAScript = normal,
+      JavaScript = normal,
+      JScript = normal
+   };
+   typedef unsigned int flag_type;
+
+   enum restart_info
+   {
+      restart_any = 0,
+      restart_word = 1,
+      restart_line = 2,
+      restart_buf = 3,
+      restart_continue = 4,
+      restart_lit = 5,
+      restart_fixed_lit = 6, 
+      restart_count = 7
+   };
+};
+
+//
+// provide std lib proposal compatible constants:
+//
+namespace regex_constants{
+
+   enum flag_type_
+   {
+
+      no_except = ::ndnboost::regbase::no_except,
+      failbit = ::ndnboost::regbase::failbit,
+      literal = ::ndnboost::regbase::literal,
+      icase = ::ndnboost::regbase::icase,
+      nocollate = ::ndnboost::regbase::nocollate,
+      collate = ::ndnboost::regbase::collate,
+      nosubs = ::ndnboost::regbase::nosubs,
+      optimize = ::ndnboost::regbase::optimize,
+      bk_plus_qm = ::ndnboost::regbase::bk_plus_qm,
+      bk_vbar = ::ndnboost::regbase::bk_vbar,
+      no_intervals = ::ndnboost::regbase::no_intervals,
+      no_char_classes = ::ndnboost::regbase::no_char_classes,
+      no_escape_in_lists = ::ndnboost::regbase::no_escape_in_lists,
+      no_mod_m = ::ndnboost::regbase::no_mod_m,
+      mod_x = ::ndnboost::regbase::mod_x,
+      mod_s = ::ndnboost::regbase::mod_s,
+      no_mod_s = ::ndnboost::regbase::no_mod_s,
+      save_subexpression_location = ::ndnboost::regbase::save_subexpression_location,
+      no_empty_expressions = ::ndnboost::regbase::no_empty_expressions,
+
+      basic = ::ndnboost::regbase::basic,
+      extended = ::ndnboost::regbase::extended,
+      normal = ::ndnboost::regbase::normal,
+      emacs = ::ndnboost::regbase::emacs,
+      awk = ::ndnboost::regbase::awk,
+      grep = ::ndnboost::regbase::grep,
+      egrep = ::ndnboost::regbase::egrep,
+      sed = basic,
+      perl = normal,
+      ECMAScript = normal,
+      JavaScript = normal,
+      JScript = normal
+   };
+   typedef ::ndnboost::regbase::flag_type syntax_option_type;
+
+} // namespace regex_constants
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/regex.hpp b/include/ndnboost/regex/v4/regex.hpp
new file mode 100644
index 0000000..e6d3111
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex.hpp
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares ndnboost::basic_regex<> and associated
+  *                functions and classes. This header is the main
+  *                entry point for the template regex code.
+  */
+
+#ifndef NDNBOOST_RE_REGEX_HPP_INCLUDED
+#define NDNBOOST_RE_REGEX_HPP_INCLUDED
+
+#ifdef __cplusplus
+
+// what follows is all C++ don't include in C builds!!
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_WORKAROUND_HPP
+#include <ndnboost/regex/v4/regex_workaround.hpp>
+#endif
+
+#ifndef NDNBOOST_REGEX_FWD_HPP
+#include <ndnboost/regex_fwd.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_TRAITS_HPP
+#include <ndnboost/regex/regex_traits.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_RAW_BUFFER_HPP
+#include <ndnboost/regex/v4/error_type.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_MATCH_FLAGS
+#include <ndnboost/regex/v4/match_flags.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_RAW_BUFFER_HPP
+#include <ndnboost/regex/v4/regex_raw_buffer.hpp>
+#endif
+#ifndef NDNBOOST_RE_PAT_EXCEPT_HPP
+#include <ndnboost/regex/pattern_except.hpp>
+#endif
+
+#ifndef NDNBOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
+#include <ndnboost/regex/v4/char_regex_traits.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_STATES_HPP
+#include <ndnboost/regex/v4/states.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_REGBASE_HPP
+#include <ndnboost/regex/v4/regbase.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_ITERATOR_TRAITS_HPP
+#include <ndnboost/regex/v4/iterator_traits.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_BASIC_REGEX_HPP
+#include <ndnboost/regex/v4/basic_regex.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
+#include <ndnboost/regex/v4/basic_regex_creator.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
+#include <ndnboost/regex/v4/basic_regex_parser.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_SUB_MATCH_HPP
+#include <ndnboost/regex/v4/sub_match.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_FORMAT_HPP
+#include <ndnboost/regex/v4/regex_format.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_MATCH_RESULTS_HPP
+#include <ndnboost/regex/v4/match_results.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_PROTECTED_CALL_HPP
+#include <ndnboost/regex/v4/protected_call.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_MATCHER_HPP
+#include <ndnboost/regex/v4/perl_matcher.hpp>
+#endif
+//
+// template instances:
+//
+#define NDNBOOST_REGEX_CHAR_T char
+#ifdef NDNBOOST_REGEX_NARROW_INSTANTIATE
+#  define NDNBOOST_REGEX_INSTANTIATE
+#endif
+#include <ndnboost/regex/v4/instances.hpp>
+#undef NDNBOOST_REGEX_CHAR_T
+#ifdef NDNBOOST_REGEX_INSTANTIATE
+#  undef NDNBOOST_REGEX_INSTANTIATE
+#endif
+
+#ifndef NDNBOOST_NO_WREGEX
+#define NDNBOOST_REGEX_CHAR_T wchar_t
+#ifdef NDNBOOST_REGEX_WIDE_INSTANTIATE
+#  define NDNBOOST_REGEX_INSTANTIATE
+#endif
+#include <ndnboost/regex/v4/instances.hpp>
+#undef NDNBOOST_REGEX_CHAR_T
+#ifdef NDNBOOST_REGEX_INSTANTIATE
+#  undef NDNBOOST_REGEX_INSTANTIATE
+#endif
+#endif
+
+#if !defined(NDNBOOST_NO_WREGEX) && defined(NDNBOOST_REGEX_HAS_OTHER_WCHAR_T)
+#define NDNBOOST_REGEX_CHAR_T unsigned short
+#ifdef NDNBOOST_REGEX_US_INSTANTIATE
+#  define NDNBOOST_REGEX_INSTANTIATE
+#endif
+#include <ndnboost/regex/v4/instances.hpp>
+#undef NDNBOOST_REGEX_CHAR_T
+#ifdef NDNBOOST_REGEX_INSTANTIATE
+#  undef NDNBOOST_REGEX_INSTANTIATE
+#endif
+#endif
+
+
+namespace ndnboost{
+#ifdef NDNBOOST_REGEX_NO_FWD
+typedef basic_regex<char, regex_traits<char> > regex;
+#ifndef NDNBOOST_NO_WREGEX
+typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
+#endif
+#endif
+
+typedef match_results<const char*> cmatch;
+typedef match_results<std::string::const_iterator> smatch;
+#ifndef NDNBOOST_NO_WREGEX
+typedef match_results<const wchar_t*> wcmatch;
+typedef match_results<std::wstring::const_iterator> wsmatch;
+#endif
+
+} // namespace ndnboost
+#ifndef NDNBOOST_REGEX_MATCH_HPP
+#include <ndnboost/regex/v4/regex_match.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_REGEX_SEARCH_HPP
+#include <ndnboost/regex/v4/regex_search.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_ITERATOR_HPP
+#include <ndnboost/regex/v4/regex_iterator.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_TOKEN_ITERATOR_HPP
+#include <ndnboost/regex/v4/regex_token_iterator.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_REGEX_GREP_HPP
+#include <ndnboost/regex/v4/regex_grep.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_REGEX_REPLACE_HPP
+#include <ndnboost/regex/v4/regex_replace.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_V4_REGEX_MERGE_HPP
+#include <ndnboost/regex/v4/regex_merge.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_SPLIT_HPP
+#include <ndnboost/regex/v4/regex_split.hpp>
+#endif
+
+#endif  // __cplusplus
+
+#endif  // include
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/regex_format.hpp b/include/ndnboost/regex/v4/regex_format.hpp
new file mode 100644
index 0000000..01397a2
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_format.hpp
@@ -0,0 +1,1156 @@
+/*
+ *
+ * Copyright (c) 1998-2009 John Maddock
+ * Copyright 2008 Eric Niebler. 
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_format.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides formatting output routines for search and replace
+  *                operations.  Note this is an internal header file included
+  *                by regex.hpp, do not include on its own.
+  */
+
+#ifndef NDNBOOST_REGEX_FORMAT_HPP
+#define NDNBOOST_REGEX_FORMAT_HPP
+
+#include <ndnboost/type_traits/is_pointer.hpp>
+#include <ndnboost/type_traits/is_function.hpp>
+#include <ndnboost/type_traits/is_class.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/remove_pointer.hpp>
+#include <ndnboost/type_traits/remove_cv.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/mpl/and.hpp>
+#include <ndnboost/mpl/not.hpp>
+#ifndef NDNBOOST_NO_SFINAE
+#include <ndnboost/mpl/has_xxx.hpp>
+#endif
+#include <ndnboost/ref.hpp>
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+//
+// Forward declaration:
+//
+   template <class BidiIterator, class Allocator = NDNBOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >
+class match_results;
+
+namespace re_detail{
+
+//
+// struct trivial_format_traits:
+// defines minimum localisation support for formatting
+// in the case that the actual regex traits is unavailable.
+//
+template <class charT>
+struct trivial_format_traits
+{
+   typedef charT char_type;
+
+   static std::ptrdiff_t length(const charT* p)
+   {
+      return global_length(p);
+   }
+   static charT tolower(charT c)
+   {
+      return ::ndnboost::re_detail::global_lower(c);
+   }
+   static charT toupper(charT c)
+   {
+      return ::ndnboost::re_detail::global_upper(c);
+   }
+   static int value(const charT c, int radix)
+   {
+      int result = global_value(c);
+      return result >= radix ? -1 : result;
+   }
+   int toi(const charT*& p1, const charT* p2, int radix)const
+   {
+      return global_toi(p1, p2, radix, *this);
+   }
+};
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+class basic_regex_formatter
+{
+public:
+   typedef typename traits::char_type char_type;
+   basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
+      : m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}
+   OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f);
+   OutputIterator format(ForwardIter p1, match_flag_type f)
+   {
+      return format(p1, p1 + m_traits.length(p1), f);
+   }
+private:
+   typedef typename Results::value_type sub_match_type;
+   enum output_state
+   {
+      output_copy,
+      output_next_lower,
+      output_next_upper,
+      output_lower,
+      output_upper,
+      output_none
+   };
+
+   void put(char_type c);
+   void put(const sub_match_type& sub);
+   void format_all();
+   void format_perl();
+   void format_escape();
+   void format_conditional();
+   void format_until_scope_end();
+   bool handle_perl_verb(bool have_brace);
+
+   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::false_&)
+   {
+      std::vector<char_type> v(i, j);
+      return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size())
+         : this->m_results.named_subexpression(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
+   }
+   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::true_&)
+   {
+      return this->m_results.named_subexpression(i, j);
+   }
+   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j)
+   {
+      typedef typename ndnboost::is_convertible<ForwardIter, const char_type*>::type tag_type;
+      return get_named_sub(i, j, tag_type());
+   }
+   inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::false_&)
+   {
+      std::vector<char_type> v(i, j);
+      return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size())
+         : this->m_results.named_subexpression_index(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
+   }
+   inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::true_&)
+   {
+      return this->m_results.named_subexpression_index(i, j);
+   }
+   inline int get_named_sub_index(ForwardIter i, ForwardIter j)
+   {
+      typedef typename ndnboost::is_convertible<ForwardIter, const char_type*>::type tag_type;
+      return get_named_sub_index(i, j, tag_type());
+   }
+#ifdef NDNBOOST_MSVC
+   // msvc-8.0 issues a spurious warning on the call to std::advance here:
+#pragma warning(push)
+#pragma warning(disable:4244)
+#endif
+   inline int toi(ForwardIter& i, ForwardIter j, int base, const ndnboost::mpl::false_&)
+   {
+      if(i != j)
+      {
+         std::vector<char_type> v(i, j);
+         const char_type* start = &v[0];
+         const char_type* pos = start;
+         int r = m_traits.toi(pos, &v[0] + v.size(), base);
+         std::advance(i, pos - start);
+         return r;
+      }
+      return -1;
+   }
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+   inline int toi(ForwardIter& i, ForwardIter j, int base, const ndnboost::mpl::true_&)
+   {
+      return m_traits.toi(i, j, base);
+   }
+   inline int toi(ForwardIter& i, ForwardIter j, int base)
+   {
+#if defined(_MSC_VER) && defined(__INTEL_COMPILER) && ((__INTEL_COMPILER == 9999) || (__INTEL_COMPILER == 1210))
+      // Workaround for Intel support issue #656654.
+      // See also https://svn.boost.org/trac/boost/ticket/6359
+      return toi(i, j, base, mpl::false_());
+#else
+      typedef typename ndnboost::is_convertible<ForwardIter, const char_type*&>::type tag_type;
+      return toi(i, j, base, tag_type());
+#endif
+   }
+
+   const traits&    m_traits;       // the traits class for localised formatting operations
+   const Results&   m_results;     // the match_results being used.
+   OutputIterator   m_out;         // where to send output.
+   ForwardIter      m_position;  // format string, current position
+   ForwardIter      m_end;       // format string end
+   match_flag_type  m_flags;      // format flags to use
+   output_state     m_state;      // what to do with the next character
+   output_state     m_restore_state;  // what state to restore to.
+   bool             m_have_conditional; // we are parsing a conditional
+private:
+   basic_regex_formatter(const basic_regex_formatter&);
+   basic_regex_formatter& operator=(const basic_regex_formatter&);
+};
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+OutputIterator basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format(ForwardIter p1, ForwardIter p2, match_flag_type f)
+{
+   m_position = p1;
+   m_end = p2;
+   m_flags = f;
+   format_all();
+   return m_out;
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_all()
+{
+   // over and over:
+   while(m_position != m_end)
+   {
+      switch(*m_position)
+      {
+      case '&':
+         if(m_flags & ::ndnboost::regex_constants::format_sed)
+         {
+            ++m_position;
+            put(m_results[0]);
+            break;
+         }
+         put(*m_position++);
+         break;
+      case '\\':
+         format_escape();
+         break;
+      case '(':
+         if(m_flags & ndnboost::regex_constants::format_all)
+         {
+            ++m_position;
+            bool have_conditional = m_have_conditional;
+            m_have_conditional = false;
+            format_until_scope_end();
+            m_have_conditional = have_conditional;
+            if(m_position == m_end)
+               return;
+            NDNBOOST_ASSERT(*m_position == static_cast<char_type>(')'));
+            ++m_position;  // skip the closing ')'
+            break;
+         }
+         put(*m_position);
+         ++m_position;
+         break;
+      case ')':
+         if(m_flags & ndnboost::regex_constants::format_all)
+         {
+            return;
+         }
+         put(*m_position);
+         ++m_position;
+         break;
+      case ':':
+         if((m_flags & ndnboost::regex_constants::format_all) && m_have_conditional)
+         {
+            return;
+         }
+         put(*m_position);
+         ++m_position;
+         break;
+      case '?':
+         if(m_flags & ndnboost::regex_constants::format_all)
+         {
+            ++m_position;
+            format_conditional();
+            break;
+         }
+         put(*m_position);
+         ++m_position;
+         break;
+      case '$':
+         if((m_flags & format_sed) == 0)
+         {
+            format_perl();
+            break;
+         }
+         // not a special character:
+         NDNBOOST_FALLTHROUGH;
+      default:
+         put(*m_position);
+         ++m_position;
+         break;
+      }
+   }
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_perl()
+{
+   //
+   // On entry *m_position points to a '$' character
+   // output the information that goes with it:
+   //
+   NDNBOOST_ASSERT(*m_position == '$');
+   //
+   // see if this is a trailing '$':
+   //
+   if(++m_position == m_end)
+   {
+      --m_position;
+      put(*m_position);
+      ++m_position;
+      return;
+   }
+   //
+   // OK find out what kind it is:
+   //
+   bool have_brace = false;
+   ForwardIter save_position = m_position;
+   switch(*m_position)
+   {
+   case '&':
+      ++m_position;
+      put(this->m_results[0]);
+      break;
+   case '`':
+      ++m_position;
+      put(this->m_results.prefix());
+      break;
+   case '\'':
+      ++m_position;
+      put(this->m_results.suffix());
+      break;
+   case '$':
+      put(*m_position++);
+      break;
+   case '+':
+      if((++m_position != m_end) && (*m_position == '{'))
+      {
+         ForwardIter base = ++m_position;
+         while((m_position != m_end) && (*m_position != '}')) ++m_position;
+         if(m_position != m_end)
+         {
+            // Named sub-expression:
+            put(get_named_sub(base, m_position));
+            ++m_position;
+            break;
+         }
+         else
+         {
+            m_position = --base;
+         }
+      }
+      put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
+      break;
+   case '{':
+      have_brace = true;
+      ++m_position;
+      NDNBOOST_FALLTHROUGH;
+   default:
+      // see if we have a number:
+      {
+         std::ptrdiff_t len = ::ndnboost::re_detail::distance(m_position, m_end);
+         //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
+         int v = this->toi(m_position, m_position + len, 10);
+         if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))
+         {
+            // Look for a Perl-5.10 verb:
+            if(!handle_perl_verb(have_brace))
+            {
+               // leave the $ as is, and carry on:
+               m_position = --save_position;
+               put(*m_position);
+               ++m_position;
+            }
+            break;
+         }
+         // otherwise output sub v:
+         put(this->m_results[v]);
+         if(have_brace)
+            ++m_position;
+      }
+   }
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+bool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle_perl_verb(bool have_brace)
+{
+   // 
+   // We may have a capitalised string containing a Perl action:
+   //
+   static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };
+   static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };
+   static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };
+   static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };
+   static const char_type LAST_SUBMATCH_RESULT[] = { 'L', 'A', 'S', 'T', '_', 'S', 'U', 'B', 'M', 'A', 'T', 'C', 'H', '_', 'R', 'E', 'S', 'U', 'L', 'T' };
+   static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };
+
+   if(m_position == m_end)
+      return false;
+   if(have_brace && (*m_position == '^'))
+      ++m_position;
+
+   std::ptrdiff_t max_len = m_end - m_position;
+
+   if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))
+   {
+      m_position += 5;
+      if(have_brace)
+      {
+         if((m_position != m_end) && (*m_position == '}'))
+            ++m_position;
+         else
+         {
+            m_position -= 5;
+            return false;
+         }
+      }
+      put(this->m_results[0]);
+      return true;
+   }
+   if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))
+   {
+      m_position += 8;
+      if(have_brace)
+      {
+         if((m_position != m_end) && (*m_position == '}'))
+            ++m_position;
+         else
+         {
+            m_position -= 8;
+            return false;
+         }
+      }
+      put(this->m_results.prefix());
+      return true;
+   }
+   if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))
+   {
+      m_position += 9;
+      if(have_brace)
+      {
+         if((m_position != m_end) && (*m_position == '}'))
+            ++m_position;
+         else
+         {
+            m_position -= 9;
+            return false;
+         }
+      }
+      put(this->m_results.suffix());
+      return true;
+   }
+   if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))
+   {
+      m_position += 16;
+      if(have_brace)
+      {
+         if((m_position != m_end) && (*m_position == '}'))
+            ++m_position;
+         else
+         {
+            m_position -= 16;
+            return false;
+         }
+      }
+      put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
+      return true;
+   }
+   if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))
+   {
+      m_position += 20;
+      if(have_brace)
+      {
+         if((m_position != m_end) && (*m_position == '}'))
+            ++m_position;
+         else
+         {
+            m_position -= 20;
+            return false;
+         }
+      }
+      put(this->m_results.get_last_closed_paren());
+      return true;
+   }
+   if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))
+   {
+      m_position += 2;
+      if(have_brace)
+      {
+         if((m_position != m_end) && (*m_position == '}'))
+            ++m_position;
+         else
+         {
+            m_position -= 2;
+            return false;
+         }
+      }
+      put(this->m_results.get_last_closed_paren());
+      return true;
+   }
+   return false;
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_escape()
+{
+   // skip the escape and check for trailing escape:
+   if(++m_position == m_end)
+   {
+      put(static_cast<char_type>('\\'));
+      return;
+   }
+   // now switch on the escape type:
+   switch(*m_position)
+   {
+   case 'a':
+      put(static_cast<char_type>('\a'));
+      ++m_position;
+      break;
+   case 'f':
+      put(static_cast<char_type>('\f'));
+      ++m_position;
+      break;
+   case 'n':
+      put(static_cast<char_type>('\n'));
+      ++m_position;
+      break;
+   case 'r':
+      put(static_cast<char_type>('\r'));
+      ++m_position;
+      break;
+   case 't':
+      put(static_cast<char_type>('\t'));
+      ++m_position;
+      break;
+   case 'v':
+      put(static_cast<char_type>('\v'));
+      ++m_position;
+      break;
+   case 'x':
+      if(++m_position == m_end)
+      {
+         put(static_cast<char_type>('x'));
+         return;
+      }
+      // maybe have \x{ddd}
+      if(*m_position == static_cast<char_type>('{'))
+      {
+         ++m_position;
+         int val = this->toi(m_position, m_end, 16);
+         if(val < 0)
+         {
+            // invalid value treat everything as literals:
+            put(static_cast<char_type>('x'));
+            put(static_cast<char_type>('{'));
+            return;
+         }
+         if((m_position == m_end) || (*m_position != static_cast<char_type>('}')))
+         {
+            --m_position;
+            while(*m_position != static_cast<char_type>('\\'))
+               --m_position;
+            ++m_position;
+            put(*m_position++);
+            return;
+         }
+         ++m_position;
+         put(static_cast<char_type>(val));
+         return;
+      }
+      else
+      {
+         std::ptrdiff_t len = ::ndnboost::re_detail::distance(m_position, m_end);
+         len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
+         int val = this->toi(m_position, m_position + len, 16);
+         if(val < 0)
+         {
+            --m_position;
+            put(*m_position++);
+            return;
+         }
+         put(static_cast<char_type>(val));
+      }
+      break;
+   case 'c':
+      if(++m_position == m_end)
+      {
+         --m_position;
+         put(*m_position++);
+         return;
+      }
+      put(static_cast<char_type>(*m_position++ % 32));
+      break;
+   case 'e':
+      put(static_cast<char_type>(27));
+      ++m_position;
+      break;
+   default:
+      // see if we have a perl specific escape:
+      if((m_flags & ndnboost::regex_constants::format_sed) == 0)
+      {
+         bool breakout = false;
+         switch(*m_position)
+         {
+         case 'l':
+            ++m_position;
+            m_restore_state = m_state;
+            m_state = output_next_lower;
+            breakout = true;
+            break;
+         case 'L':
+            ++m_position;
+            m_state = output_lower;
+            breakout = true;
+            break;
+         case 'u':
+            ++m_position;
+            m_restore_state = m_state;
+            m_state = output_next_upper;
+            breakout = true;
+            break;
+         case 'U':
+            ++m_position;
+            m_state = output_upper;
+            breakout = true;
+            break;
+         case 'E':
+            ++m_position;
+            m_state = output_copy;
+            breakout = true;
+            break;
+         }
+         if(breakout)
+            break;
+      }
+      // see if we have a \n sed style backreference:
+      std::ptrdiff_t len = ::ndnboost::re_detail::distance(m_position, m_end);
+      len = (std::min)(static_cast<std::ptrdiff_t>(1), len);
+      int v = this->toi(m_position, m_position+len, 10);
+      if((v > 0) || ((v == 0) && (m_flags & ::ndnboost::regex_constants::format_sed)))
+      {
+         put(m_results[v]);
+         break;
+      }
+      else if(v == 0)
+      {
+         // octal ecape sequence:
+         --m_position;
+         len = ::ndnboost::re_detail::distance(m_position, m_end);
+         len = (std::min)(static_cast<std::ptrdiff_t>(4), len);
+         v = this->toi(m_position, m_position + len, 8);
+         NDNBOOST_ASSERT(v >= 0);
+         put(static_cast<char_type>(v));
+         break;
+      }
+      // Otherwise output the character "as is":
+      put(*m_position++);
+      break;
+   }
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_conditional()
+{
+   if(m_position == m_end)
+   {
+      // oops trailing '?':
+      put(static_cast<char_type>('?'));
+      return;
+   }
+   int v;
+   if(*m_position == '{')
+   {
+      ForwardIter base = m_position;
+      ++m_position;
+      v = this->toi(m_position, m_end, 10);
+      if(v < 0)
+      {
+         // Try a named subexpression:
+         while((m_position != m_end) && (*m_position != '}'))
+            ++m_position;
+         v = this->get_named_sub_index(base + 1, m_position);
+      }
+      if((v < 0) || (*m_position != '}'))
+      {
+         m_position = base;
+         // oops trailing '?':
+         put(static_cast<char_type>('?'));
+         return;
+      }
+      // Skip trailing '}':
+      ++m_position;
+   }
+   else
+   {
+      std::ptrdiff_t len = ::ndnboost::re_detail::distance(m_position, m_end);
+      len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
+      v = this->toi(m_position, m_position + len, 10);
+   }
+   if(v < 0)
+   {
+      // oops not a number:
+      put(static_cast<char_type>('?'));
+      return;
+   }
+
+   // output varies depending upon whether sub-expression v matched or not:
+   if(m_results[v].matched)
+   {
+      m_have_conditional = true;
+      format_all();
+      m_have_conditional = false;
+      if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
+      {
+         // skip the ':':
+         ++m_position;
+         // save output state, then turn it off:
+         output_state saved_state = m_state;
+         m_state = output_none;
+         // format the rest of this scope:
+         format_until_scope_end();
+         // restore output state:
+         m_state = saved_state;
+      }
+   }
+   else
+   {
+      // save output state, then turn it off:
+      output_state saved_state = m_state;
+      m_state = output_none;
+      // format until ':' or ')':
+      m_have_conditional = true;
+      format_all();
+      m_have_conditional = false;
+      // restore state:
+      m_state = saved_state;
+      if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
+      {
+         // skip the ':':
+         ++m_position;
+         // format the rest of this scope:
+         format_until_scope_end();
+      }
+   }
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_until_scope_end()
+{
+   do
+   {
+      format_all();
+      if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
+         return;
+      put(*m_position++);
+   }while(m_position != m_end);
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(char_type c)
+{
+   // write a single character to output
+   // according to which case translation mode we are in:
+   switch(this->m_state)
+   {
+   case output_none:
+      return;
+   case output_next_lower:
+      c = m_traits.tolower(c);
+      this->m_state = m_restore_state;
+      break;
+   case output_next_upper:
+      c = m_traits.toupper(c);
+      this->m_state = m_restore_state;
+      break;
+   case output_lower:
+      c = m_traits.tolower(c);
+      break;
+   case output_upper:
+      c = m_traits.toupper(c);
+      break;
+   default:
+      break;
+   }
+   *m_out = c;
+   ++m_out;
+}
+
+template <class OutputIterator, class Results, class traits, class ForwardIter>
+void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(const sub_match_type& sub)
+{
+   typedef typename sub_match_type::iterator iterator_type;
+   iterator_type i = sub.first;
+   while(i != sub.second)
+   {
+      put(*i);
+      ++i;
+   }
+}
+
+template <class S>
+class string_out_iterator
+#ifndef NDNBOOST_NO_STD_ITERATOR
+   : public std::iterator<std::output_iterator_tag, typename S::value_type>
+#endif
+{
+   S* out;
+public:
+   string_out_iterator(S& s) : out(&s) {}
+   string_out_iterator& operator++() { return *this; }
+   string_out_iterator& operator++(int) { return *this; }
+   string_out_iterator& operator*() { return *this; }
+   string_out_iterator& operator=(typename S::value_type v) 
+   { 
+      out->append(1, v); 
+      return *this; 
+   }
+
+#ifdef NDNBOOST_NO_STD_ITERATOR
+   typedef std::ptrdiff_t difference_type;
+   typedef typename S::value_type value_type;
+   typedef value_type* pointer;
+   typedef value_type& reference;
+   typedef std::output_iterator_tag iterator_category;
+#endif
+};
+
+template <class OutputIterator, class Iterator, class Alloc, class ForwardIter, class traits>
+OutputIterator regex_format_imp(OutputIterator out,
+                          const match_results<Iterator, Alloc>& m,
+                          ForwardIter p1, ForwardIter p2,
+                          match_flag_type flags,
+                          const traits& t
+                         )
+{
+   if(flags & regex_constants::format_literal)
+   {
+      return re_detail::copy(p1, p2, out);
+   }
+
+   re_detail::basic_regex_formatter<
+      OutputIterator, 
+      match_results<Iterator, Alloc>, 
+      traits, ForwardIter> f(out, m, t);
+   return f.format(p1, p2, flags);
+}
+
+#ifndef NDNBOOST_NO_SFINAE
+
+NDNBOOST_MPL_HAS_XXX_TRAIT_DEF(const_iterator)
+
+struct any_type 
+{
+   template <class T>
+   any_type(const T&); 
+   template <class T, class U>
+   any_type(const T&, const U&); 
+   template <class T, class U, class V>
+   any_type(const T&, const U&, const V&); 
+};
+typedef char no_type;
+typedef char (&unary_type)[2];
+typedef char (&binary_type)[3];
+typedef char (&ternary_type)[4];
+
+no_type check_is_formatter(unary_type, binary_type, ternary_type);
+template<typename T>
+unary_type check_is_formatter(T const &, binary_type, ternary_type);
+template<typename T>
+binary_type check_is_formatter(unary_type, T const &, ternary_type);
+template<typename T, typename U>
+binary_type check_is_formatter(T const &, U const &, ternary_type);
+template<typename T>
+ternary_type check_is_formatter(unary_type, binary_type, T const &);
+template<typename T, typename U>
+ternary_type check_is_formatter(T const &, binary_type, U const &);
+template<typename T, typename U>
+ternary_type check_is_formatter(unary_type, T const &, U const &);
+template<typename T, typename U, typename V>
+ternary_type check_is_formatter(T const &, U const &, V const &);
+
+struct unary_binary_ternary
+{
+    typedef unary_type (*unary_fun)(any_type);
+    typedef binary_type (*binary_fun)(any_type, any_type);
+    typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);
+    operator unary_fun();
+    operator binary_fun();
+    operator ternary_fun();
+};
+
+template<typename Formatter, bool IsFunction = ndnboost::is_function<Formatter>::value>
+struct formatter_wrapper
+  : Formatter
+  , unary_binary_ternary
+{
+   formatter_wrapper(){}
+};
+
+template<typename Formatter>
+struct formatter_wrapper<Formatter, true>
+  : unary_binary_ternary
+{
+    operator Formatter *();
+};
+
+template<typename Formatter>
+struct formatter_wrapper<Formatter *, false>
+  : unary_binary_ternary
+{
+    operator Formatter *();
+};
+
+template <class F, class M, class O>
+struct format_traits_imp
+{
+private:
+   //
+   // F must be a pointer, a function, or a class with a function call operator:
+   //
+   NDNBOOST_STATIC_ASSERT((::ndnboost::is_pointer<F>::value || ::ndnboost::is_function<F>::value || ::ndnboost::is_class<F>::value));
+   static formatter_wrapper<typename unwrap_reference<F>::type> f;
+   static M m;
+   static O out;
+   static ndnboost::regex_constants::match_flag_type flags;
+public:
+   NDNBOOST_STATIC_CONSTANT(int, value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags))));
+};
+
+template <class F, class M, class O>
+struct format_traits
+{
+public:
+   // 
+   // Type is mpl::int_<N> where N is one of:
+   //
+   // 0 : F is a pointer to a presumably null-terminated string.
+   // 1 : F is a character-container such as a std::string.
+   // 2 : F is a Unary Functor.
+   // 3 : F is a Binary Functor.
+   // 4 : F is a Ternary Functor.
+   //
+   typedef typename ndnboost::mpl::if_<
+      ndnboost::mpl::and_<ndnboost::is_pointer<F>, ndnboost::mpl::not_<ndnboost::is_function<typename ndnboost::remove_pointer<F>::type> > >,
+      ndnboost::mpl::int_<0>,
+      typename ndnboost::mpl::if_<
+         has_const_iterator<F>,
+         ndnboost::mpl::int_<1>,
+         ndnboost::mpl::int_<format_traits_imp<F, M, O>::value>
+      >::type
+   >::type type;
+   //
+   // This static assertion will fail if the functor passed does not accept
+   // the same type of arguments passed.
+   //
+   NDNBOOST_STATIC_ASSERT( ndnboost::is_class<F>::value && !has_const_iterator<F>::value ? (type::value > 1) : true);
+};
+
+#else // NDNBOOST_NO_SFINAE
+
+template <class F, class M, class O>
+struct format_traits
+{
+public:
+   // 
+   // Type is mpl::int_<N> where N is one of:
+   //
+   // 0 : F is a pointer to a presumably null-terminated string.
+   // 1 : F is a character-container such as a std::string.
+   //
+   // Other options such as F being a Functor are not supported without
+   // SFINAE support.
+   //
+   typedef typename ndnboost::mpl::if_<
+      ndnboost::is_pointer<F>,
+      ndnboost::mpl::int_<0>,
+      ndnboost::mpl::int_<1>
+   >::type type;
+};
+
+#endif // NDNBOOST_NO_SFINAE
+
+template <class Base, class Match>
+struct format_functor3
+{
+   format_functor3(Base b) : func(b) {}
+   template <class OutputIter>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type f)
+   {
+      return ndnboost::unwrap_ref(func)(m, i, f);
+   }
+   template <class OutputIter, class Traits>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type f, const Traits&)
+   {
+      return (*this)(m, i, f);
+   }
+private:
+   Base func;
+   format_functor3(const format_functor3&);
+   format_functor3& operator=(const format_functor3&);
+};
+
+template <class Base, class Match>
+struct format_functor2
+{
+   format_functor2(Base b) : func(b) {}
+   template <class OutputIter>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type /*f*/)
+   {
+      return ndnboost::unwrap_ref(func)(m, i);
+   }
+   template <class OutputIter, class Traits>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type f, const Traits&)
+   {
+      return (*this)(m, i, f);
+   }
+private:
+   Base func;
+   format_functor2(const format_functor2&);
+   format_functor2& operator=(const format_functor2&);
+};
+
+template <class Base, class Match>
+struct format_functor1
+{
+   format_functor1(Base b) : func(b) {}
+
+   template <class S, class OutputIter>
+   OutputIter do_format_string(const S& s, OutputIter i)
+   {
+      return re_detail::copy(s.begin(), s.end(), i);
+   }
+   template <class S, class OutputIter>
+   inline OutputIter do_format_string(const S* s, OutputIter i)
+   {
+      while(s && *s)
+      {
+         *i = *s;
+         ++i;
+         ++s;
+      }
+      return i;
+   }
+   template <class OutputIter>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type /*f*/)
+   {
+      return do_format_string(ndnboost::unwrap_ref(func)(m), i);
+   }
+   template <class OutputIter, class Traits>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type f, const Traits&)
+   {
+      return (*this)(m, i, f);
+   }
+private:
+   Base func;
+   format_functor1(const format_functor1&);
+   format_functor1& operator=(const format_functor1&);
+};
+
+template <class charT, class Match, class Traits>
+struct format_functor_c_string
+{
+   format_functor_c_string(const charT* ps) : func(ps) {}
+
+   template <class OutputIter>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type f, const Traits& t = Traits())
+   {
+      //typedef typename Match::char_type char_type;
+      const charT* end = func;
+      while(*end) ++end;
+      return regex_format_imp(i, m, func, end, f, t);
+   }
+private:
+   const charT* func;
+   format_functor_c_string(const format_functor_c_string&);
+   format_functor_c_string& operator=(const format_functor_c_string&);
+};
+
+template <class Container, class Match, class Traits>
+struct format_functor_container
+{
+   format_functor_container(const Container& c) : func(c) {}
+
+   template <class OutputIter>
+   OutputIter operator()(const Match& m, OutputIter i, ndnboost::regex_constants::match_flag_type f, const Traits& t = Traits())
+   {
+      //typedef typename Match::char_type char_type;
+      return re_detail::regex_format_imp(i, m, func.begin(), func.end(), f, t);
+   }
+private:
+   const Container& func;
+   format_functor_container(const format_functor_container&);
+   format_functor_container& operator=(const format_functor_container&);
+};
+
+template <class Func, class Match, class OutputIterator, class Traits = re_detail::trivial_format_traits<typename Match::char_type> >
+struct compute_functor_type
+{
+   typedef typename format_traits<Func, Match, OutputIterator>::type tag;
+   typedef typename ndnboost::remove_cv< typename ndnboost::remove_pointer<Func>::type>::type maybe_char_type;
+
+   typedef typename mpl::if_<
+      ::ndnboost::is_same<tag, mpl::int_<0> >, format_functor_c_string<maybe_char_type, Match, Traits>,
+      typename mpl::if_<
+         ::ndnboost::is_same<tag, mpl::int_<1> >, format_functor_container<Func, Match, Traits>,
+         typename mpl::if_<
+            ::ndnboost::is_same<tag, mpl::int_<2> >, format_functor1<Func, Match>,
+            typename mpl::if_<
+               ::ndnboost::is_same<tag, mpl::int_<3> >, format_functor2<Func, Match>, 
+               format_functor3<Func, Match>
+            >::type
+         >::type
+      >::type
+   >::type type;
+};
+
+} // namespace re_detail
+
+template <class OutputIterator, class Iterator, class Allocator, class Functor>
+inline OutputIterator regex_format(OutputIterator out,
+                          const match_results<Iterator, Allocator>& m,
+                          Functor fmt,
+                          match_flag_type flags = format_all
+                         )
+{
+   return m.format(out, fmt, flags);
+}
+
+template <class Iterator, class Allocator, class Functor>
+inline std::basic_string<typename match_results<Iterator, Allocator>::char_type> regex_format(const match_results<Iterator, Allocator>& m, 
+                                      Functor fmt, 
+                                      match_flag_type flags = format_all)
+{
+   return m.format(fmt, flags);
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif  // NDNBOOST_REGEX_FORMAT_HPP
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/regex_fwd.hpp b/include/ndnboost/regex/v4/regex_fwd.hpp
new file mode 100644
index 0000000..e98050f
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_fwd.hpp
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_fwd.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Forward declares ndnboost::basic_regex<> and
+  *                associated typedefs.
+  */
+
+#ifndef NDNBOOST_REGEX_FWD_HPP_INCLUDED
+#define NDNBOOST_REGEX_FWD_HPP_INCLUDED
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+
+//
+// define NDNBOOST_REGEX_NO_FWD if this
+// header doesn't work!
+//
+#ifdef NDNBOOST_REGEX_NO_FWD
+#  ifndef NDNBOOST_RE_REGEX_HPP
+#     include <ndnboost/regex.hpp>
+#  endif
+#else
+
+namespace ndnboost{
+
+template <class charT>
+class cpp_regex_traits;
+template <class charT>
+struct c_regex_traits;
+template <class charT>
+class w32_regex_traits;
+
+#ifdef NDNBOOST_REGEX_USE_WIN32_LOCALE
+template <class charT, class implementationT = w32_regex_traits<charT> >
+struct regex_traits;
+#elif defined(NDNBOOST_REGEX_USE_CPP_LOCALE)
+template <class charT, class implementationT = cpp_regex_traits<charT> >
+struct regex_traits;
+#else
+template <class charT, class implementationT = c_regex_traits<charT> >
+struct regex_traits;
+#endif
+
+template <class charT, class traits = regex_traits<charT> >
+class basic_regex;
+
+typedef basic_regex<char, regex_traits<char> > regex;
+#ifndef NDNBOOST_NO_WREGEX
+typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
+#endif
+
+} // namespace ndnboost
+
+#endif  // NDNBOOST_REGEX_NO_FWD
+
+#endif
+
+
+
+
diff --git a/include/ndnboost/regex/v4/regex_grep.hpp b/include/ndnboost/regex/v4/regex_grep.hpp
new file mode 100644
index 0000000..ee789d2
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_grep.hpp
@@ -0,0 +1,155 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_grep.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides regex_grep implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGEX_GREP_HPP
+#define NDNBOOST_REGEX_V4_REGEX_GREP_HPP
+
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+//
+// regex_grep:
+// find all non-overlapping matches within the sequence first last:
+//
+template <class Predicate, class BidiIterator, class charT, class traits>
+inline unsigned int regex_grep(Predicate foo, 
+                               BidiIterator first, 
+                               BidiIterator last, 
+                               const basic_regex<charT, traits>& e, 
+                               match_flag_type flags = match_default)
+{
+   if(e.flags() & regex_constants::failbit)
+      return false;
+
+   typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;
+
+   match_results<BidiIterator> m;
+   re_detail::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);
+   unsigned int count = 0;
+   while(matcher.find())
+   {
+      ++count;
+      if(0 == foo(m))
+         return count; // caller doesn't want to go on
+      if(m[0].second == last)
+         return count; // we've reached the end, don't try and find an extra null match.
+      if(m.length() == 0)
+      {
+         if(m[0].second == last)
+            return count;
+         // we found a NULL-match, now try to find
+         // a non-NULL one at the same position:
+         match_results<BidiIterator, match_allocator_type> m2(m);
+         matcher.setf(match_not_null | match_continuous);
+         if(matcher.find())
+         {
+            ++count;
+            if(0 == foo(m))
+               return count;
+         }
+         else
+         {
+            // reset match back to where it was:
+            m = m2;
+         }
+         matcher.unsetf((match_not_null | match_continuous) & ~flags);
+      }
+   }
+   return count;
+}
+
+//
+// regex_grep convenience interfaces:
+#ifndef NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class Predicate, class charT, class traits>
+inline unsigned int regex_grep(Predicate foo, const charT* str, 
+                        const basic_regex<charT, traits>& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_grep(foo, str, str + traits::length(str), e, flags);
+}
+
+template <class Predicate, class ST, class SA, class charT, class traits>
+inline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   return regex_grep(foo, s.begin(), s.end(), e, flags);
+}
+#else  // partial specialisation
+inline unsigned int regex_grep(bool (*foo)(const cmatch&), const char* str, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_grep(foo, str, str + regex::traits_type::length(str), e, flags);
+}
+#ifndef NDNBOOST_NO_WREGEX
+inline unsigned int regex_grep(bool (*foo)(const wcmatch&), const wchar_t* str, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_grep(foo, str, str + wregex::traits_type::length(str), e, flags);
+}
+#endif
+inline unsigned int regex_grep(bool (*foo)(const match_results<std::string::const_iterator>&), const std::string& s,
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_grep(foo, s.begin(), s.end(), e, flags);
+}
+#if !defined(NDNBOOST_NO_WREGEX)
+inline unsigned int regex_grep(bool (*foo)(const match_results<std::basic_string<wchar_t>::const_iterator>&), 
+                     const std::basic_string<wchar_t>& s, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_grep(foo, s.begin(), s.end(), e, flags);
+}
+#endif
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif  // NDNBOOST_REGEX_V4_REGEX_GREP_HPP
+
diff --git a/include/ndnboost/regex/v4/regex_iterator.hpp b/include/ndnboost/regex/v4/regex_iterator.hpp
new file mode 100644
index 0000000..0c0136e
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_iterator.hpp
@@ -0,0 +1,201 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_iterator.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides regex_iterator implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGEX_ITERATOR_HPP
+#define NDNBOOST_REGEX_V4_REGEX_ITERATOR_HPP
+
+#include <ndnboost/shared_ptr.hpp>
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class BidirectionalIterator, 
+          class charT,
+          class traits>
+class regex_iterator_implementation 
+{
+   typedef basic_regex<charT, traits> regex_type;
+
+   match_results<BidirectionalIterator> what;  // current match
+   BidirectionalIterator                base;  // start of sequence
+   BidirectionalIterator                end;   // end of sequence
+   const regex_type                     re;   // the expression
+   match_flag_type                      flags; // flags for matching
+
+public:
+   regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
+      : base(), end(last), re(*p), flags(f){}
+   bool init(BidirectionalIterator first)
+   {
+      base = first;
+      return regex_search(first, end, what, re, flags);
+   }
+   bool compare(const regex_iterator_implementation& that)
+   {
+      if(this == &that) return true;
+      return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
+   }
+   const match_results<BidirectionalIterator>& get()
+   { return what; }
+   bool next()
+   {
+      //if(what.prefix().first != what[0].second)
+      //   flags |= match_prev_avail;
+      BidirectionalIterator next_start = what[0].second;
+      match_flag_type f(flags);
+      if(!what.length() || (f & regex_constants::match_posix))
+         f |= regex_constants::match_not_initial_null;
+      //if(base != next_start)
+      //   f |= regex_constants::match_not_bob;
+      bool result = regex_search(next_start, end, what, re, f, base);
+      if(result)
+         what.set_base(base);
+      return result;
+   }
+private:
+   regex_iterator_implementation& operator=(const regex_iterator_implementation&);
+};
+
+template <class BidirectionalIterator, 
+          class charT = NDNBOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
+          class traits = regex_traits<charT> >
+class regex_iterator 
+#ifndef NDNBOOST_NO_STD_ITERATOR
+   : public std::iterator<
+         std::forward_iterator_tag, 
+         match_results<BidirectionalIterator>,
+         typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+         const match_results<BidirectionalIterator>*,
+         const match_results<BidirectionalIterator>& >         
+#endif
+{
+private:
+   typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;
+   typedef shared_ptr<impl> pimpl;
+public:
+   typedef          basic_regex<charT, traits>                   regex_type;
+   typedef          match_results<BidirectionalIterator>                    value_type;
+   typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type 
+                                                                            difference_type;
+   typedef          const value_type*                                       pointer;
+   typedef          const value_type&                                       reference; 
+   typedef          std::forward_iterator_tag                               iterator_category;
+   
+   regex_iterator(){}
+   regex_iterator(BidirectionalIterator a, BidirectionalIterator b, 
+                  const regex_type& re, 
+                  match_flag_type m = match_default)
+                  : pdata(new impl(&re, b, m))
+   {
+      if(!pdata->init(a))
+      {
+         pdata.reset();
+      }
+   }
+   regex_iterator(const regex_iterator& that)
+      : pdata(that.pdata) {}
+   regex_iterator& operator=(const regex_iterator& that)
+   {
+      pdata = that.pdata;
+      return *this;
+   }
+   bool operator==(const regex_iterator& that)const
+   { 
+      if((pdata.get() == 0) || (that.pdata.get() == 0))
+         return pdata.get() == that.pdata.get();
+      return pdata->compare(*(that.pdata.get())); 
+   }
+   bool operator!=(const regex_iterator& that)const
+   { return !(*this == that); }
+   const value_type& operator*()const
+   { return pdata->get(); }
+   const value_type* operator->()const
+   { return &(pdata->get()); }
+   regex_iterator& operator++()
+   {
+      cow();
+      if(0 == pdata->next())
+      {
+         pdata.reset();
+      }
+      return *this;
+   }
+   regex_iterator operator++(int)
+   {
+      regex_iterator result(*this);
+      ++(*this);
+      return result;
+   }
+private:
+
+   pimpl pdata;
+
+   void cow()
+   {
+      // copy-on-write
+      if(pdata.get() && !pdata.unique())
+      {
+         pdata.reset(new impl(*(pdata.get())));
+      }
+   }
+};
+
+typedef regex_iterator<const char*> cregex_iterator;
+typedef regex_iterator<std::string::const_iterator> sregex_iterator;
+#ifndef NDNBOOST_NO_WREGEX
+typedef regex_iterator<const wchar_t*> wcregex_iterator;
+typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;
+#endif
+
+// make_regex_iterator:
+template <class charT, class traits>
+inline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);
+}
+template <class charT, class traits, class ST, class SA>
+inline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_REGEX_V4_REGEX_ITERATOR_HPP
+
diff --git a/include/ndnboost/regex/v4/regex_match.hpp b/include/ndnboost/regex/v4/regex_match.hpp
new file mode 100644
index 0000000..81f9b9b
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_match.hpp
@@ -0,0 +1,382 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_match.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Regular expression matching algorithms.
+  *                Note this is an internal header file included
+  *                by regex.hpp, do not include on its own.
+  */
+
+
+#ifndef NDNBOOST_REGEX_MATCH_HPP
+#define NDNBOOST_REGEX_MATCH_HPP
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+//
+// proc regex_match
+// returns true if the specified regular expression matches
+// the whole of the input.  Fills in what matched in m.
+//
+template <class BidiIterator, class Allocator, class charT, class traits>
+bool regex_match(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);
+   return matcher.match();
+}
+template <class iterator, class charT, class traits>
+bool regex_match(iterator first, iterator last, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<iterator> m;
+   return regex_match(first, last, m, e, flags | regex_constants::match_any);
+}
+//
+// query_match convenience interfaces:
+#ifndef NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class charT, class Allocator, class traits>
+inline bool regex_match(const charT* str, 
+                        match_results<const charT*, Allocator>& m, 
+                        const basic_regex<charT, traits>& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + traits::length(str), m, e, flags);
+}
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+inline bool regex_match(const std::basic_string<charT, ST, SA>& s, 
+                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+template <class charT, class traits>
+inline bool regex_match(const charT* str, 
+                        const basic_regex<charT, traits>& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const charT*> m;
+   return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any);
+}
+
+template <class ST, class SA, class charT, class traits>
+inline bool regex_match(const std::basic_string<charT, ST, SA>& s, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;
+   match_results<iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#else  // partial ordering
+inline bool regex_match(const char* str, 
+                        cmatch& m, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const char*> m;
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#ifndef NDNBOOST_NO_STD_LOCALE
+inline bool regex_match(const char* str, 
+                        cmatch& m, 
+                        const basic_regex<char, cpp_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str, 
+                        const basic_regex<char, cpp_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const char*> m;
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const char* str, 
+                        cmatch& m, 
+                        const basic_regex<char, c_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str, 
+                        const basic_regex<char, c_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const char*> m;
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(NDNBOOST_REGEX_NO_W32)
+inline bool regex_match(const char* str, 
+                        cmatch& m, 
+                        const basic_regex<char, w32_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str, 
+                        const basic_regex<char, w32_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const char*> m;
+   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+#ifndef NDNBOOST_NO_WREGEX
+inline bool regex_match(const wchar_t* str, 
+                        wcmatch& m, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const wchar_t*> m;
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#ifndef NDNBOOST_NO_STD_LOCALE
+inline bool regex_match(const wchar_t* str, 
+                        wcmatch& m, 
+                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str, 
+                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const wchar_t*> m;
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const wchar_t* str, 
+                        wcmatch& m, 
+                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str, 
+                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const wchar_t*> m;
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(NDNBOOST_REGEX_NO_W32)
+inline bool regex_match(const wchar_t* str, 
+                        wcmatch& m, 
+                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str, 
+                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const wchar_t*> m;
+   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+#endif
+inline bool regex_match(const std::string& s, 
+                        smatch& m,
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::string::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#ifndef NDNBOOST_NO_STD_LOCALE
+inline bool regex_match(const std::string& s, 
+                        smatch& m,
+                        const basic_regex<char, cpp_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s, 
+                        const basic_regex<char, cpp_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::string::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const std::string& s, 
+                        smatch& m,
+                        const basic_regex<char, c_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s, 
+                        const basic_regex<char, c_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::string::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(NDNBOOST_REGEX_NO_W32)
+inline bool regex_match(const std::string& s, 
+                        smatch& m,
+                        const basic_regex<char, w32_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s, 
+                        const basic_regex<char, w32_regex_traits<char> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::string::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+#if !defined(NDNBOOST_NO_WREGEX)
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        match_results<std::basic_string<wchar_t>::const_iterator>& m,
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::basic_string<wchar_t>::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#ifndef NDNBOOST_NO_STD_LOCALE
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        match_results<std::basic_string<wchar_t>::const_iterator>& m,
+                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::basic_string<wchar_t>::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        match_results<std::basic_string<wchar_t>::const_iterator>& m,
+                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::basic_string<wchar_t>::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(NDNBOOST_REGEX_NO_W32)
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        match_results<std::basic_string<wchar_t>::const_iterator>& m,
+                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s, 
+                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::basic_string<wchar_t>::const_iterator> m;
+   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+#endif
+
+#endif
+
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif   // NDNBOOST_REGEX_MATCH_HPP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/regex_merge.hpp b/include/ndnboost/regex/v4/regex_merge.hpp
new file mode 100644
index 0000000..21b914f
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_merge.hpp
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_format.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides formatting output routines for search and replace
+  *                operations.  Note this is an internal header file included
+  *                by regex.hpp, do not include on its own.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGEX_MERGE_HPP
+#define NDNBOOST_REGEX_V4_REGEX_MERGE_HPP
+
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class OutputIterator, class Iterator, class traits, class charT>
+inline OutputIterator regex_merge(OutputIterator out,
+                         Iterator first,
+                         Iterator last,
+                         const basic_regex<charT, traits>& e, 
+                         const charT* fmt, 
+                         match_flag_type flags = match_default)
+{
+   return regex_replace(out, first, last, e, fmt, flags);
+}
+
+template <class OutputIterator, class Iterator, class traits, class charT>
+inline OutputIterator regex_merge(OutputIterator out,
+                         Iterator first,
+                         Iterator last,
+                         const basic_regex<charT, traits>& e, 
+                         const std::basic_string<charT>& fmt,
+                         match_flag_type flags = match_default)
+{
+   return regex_merge(out, first, last, e, fmt.c_str(), flags);
+}
+
+template <class traits, class charT>
+inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
+                         const basic_regex<charT, traits>& e, 
+                         const charT* fmt,
+                         match_flag_type flags = match_default)
+{
+   return regex_replace(s, e, fmt, flags);
+}
+
+template <class traits, class charT>
+inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
+                         const basic_regex<charT, traits>& e, 
+                         const std::basic_string<charT>& fmt,
+                         match_flag_type flags = match_default)
+{
+   return regex_replace(s, e, fmt, flags);
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif  // NDNBOOST_REGEX_V4_REGEX_MERGE_HPP
+
+
diff --git a/include/ndnboost/regex/v4/regex_raw_buffer.hpp b/include/ndnboost/regex/v4/regex_raw_buffer.hpp
new file mode 100644
index 0000000..1990359
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_raw_buffer.hpp
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_raw_buffer.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Raw character buffer for regex code.
+  *                Note this is an internal header file included
+  *                by regex.hpp, do not include on its own.
+  */
+
+#ifndef NDNBOOST_REGEX_RAW_BUFFER_HPP
+#define NDNBOOST_REGEX_RAW_BUFFER_HPP
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+
+#include <algorithm>
+#include <cstddef>
+
+namespace ndnboost{
+   namespace re_detail{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+struct empty_padding{};
+
+union padding
+{
+   void* p;
+   unsigned int i;
+};
+
+template <int N>
+struct padding3
+{
+   enum{
+      padding_size = 8,
+      padding_mask = 7
+   };
+};
+
+template<>
+struct padding3<2>
+{
+   enum{
+      padding_size = 2,
+      padding_mask = 1
+   };
+};
+
+template<>
+struct padding3<4>
+{
+   enum{
+      padding_size = 4,
+      padding_mask = 3
+   };
+};
+
+template<>
+struct padding3<8>
+{
+   enum{
+      padding_size = 8,
+      padding_mask = 7
+   };
+};
+
+template<>
+struct padding3<16>
+{
+   enum{
+      padding_size = 16,
+      padding_mask = 15
+   };
+};
+
+enum{
+   padding_size = padding3<sizeof(padding)>::padding_size,
+   padding_mask = padding3<sizeof(padding)>::padding_mask
+};
+
+//
+// class raw_storage
+// basically this is a simplified vector<unsigned char>
+// this is used by basic_regex for expression storage
+//
+
+class NDNBOOST_REGEX_DECL raw_storage
+{
+public:
+   typedef std::size_t           size_type;
+   typedef unsigned char*        pointer;
+private:
+   pointer last, start, end;
+public:
+
+   raw_storage();
+   raw_storage(size_type n);
+
+   ~raw_storage()
+   {
+      ::operator delete(start);
+   }
+
+   void NDNBOOST_REGEX_CALL resize(size_type n);
+   
+   void* NDNBOOST_REGEX_CALL extend(size_type n)
+   {
+      if(size_type(last - end) < n)
+         resize(n + (end - start));
+      register pointer result = end;
+      end += n;
+      return result;
+   }
+
+   void* NDNBOOST_REGEX_CALL insert(size_type pos, size_type n);
+
+   size_type NDNBOOST_REGEX_CALL size()
+   {
+      return end - start;
+   }
+
+   size_type NDNBOOST_REGEX_CALL capacity()
+   {
+      return last - start;
+   }
+
+   void* NDNBOOST_REGEX_CALL data()const
+   {
+      return start;
+   }
+
+   size_type NDNBOOST_REGEX_CALL index(void* ptr)
+   {
+      return static_cast<pointer>(ptr) - static_cast<pointer>(data());
+   }
+
+   void NDNBOOST_REGEX_CALL clear()
+   {
+      end = start;
+   }
+
+   void NDNBOOST_REGEX_CALL align()
+   {
+      // move end up to a boundary:
+      end = start + (((end - start) + padding_mask) & ~padding_mask);
+   }
+   void swap(raw_storage& that)
+   {
+      std::swap(start, that.start);
+      std::swap(end, that.end);
+      std::swap(last, that.last);
+  }
+};
+
+inline raw_storage::raw_storage()
+{
+   last = start = end = 0;
+}
+
+inline raw_storage::raw_storage(size_type n)
+{
+   start = end = static_cast<pointer>(::operator new(n));
+   NDNBOOST_REGEX_NOEH_ASSERT(start)
+   last = start + n;
+}
+
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace re_detail
+} // namespace ndnboost
+
+#endif
+
+
+
+
+
+
diff --git a/include/ndnboost/regex/v4/regex_replace.hpp b/include/ndnboost/regex/v4/regex_replace.hpp
new file mode 100644
index 0000000..bb24fa8
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_replace.hpp
@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright (c) 1998-2009
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_format.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides formatting output routines for search and replace
+  *                operations.  Note this is an internal header file included
+  *                by regex.hpp, do not include on its own.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGEX_REPLACE_HPP
+#define NDNBOOST_REGEX_V4_REGEX_REPLACE_HPP
+
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class OutputIterator, class BidirectionalIterator, class traits, class charT, class Formatter>
+OutputIterator regex_replace(OutputIterator out,
+                         BidirectionalIterator first,
+                         BidirectionalIterator last,
+                         const basic_regex<charT, traits>& e, 
+                         Formatter fmt, 
+                         match_flag_type flags = match_default)
+{
+   regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags);
+   regex_iterator<BidirectionalIterator, charT, traits> j;
+   if(i == j)
+   {
+      if(!(flags & regex_constants::format_no_copy))
+         out = re_detail::copy(first, last, out);
+   }
+   else
+   {
+      BidirectionalIterator last_m(first);
+      while(i != j)
+      {
+         if(!(flags & regex_constants::format_no_copy))
+            out = re_detail::copy(i->prefix().first, i->prefix().second, out); 
+         out = i->format(out, fmt, flags, e);
+         last_m = (*i)[0].second;
+         if(flags & regex_constants::format_first_only)
+            break;
+         ++i;
+      }
+      if(!(flags & regex_constants::format_no_copy))
+         out = re_detail::copy(last_m, last, out);
+   }
+   return out;
+}
+
+template <class traits, class charT, class Formatter>
+std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
+                         const basic_regex<charT, traits>& e, 
+                         Formatter fmt,
+                         match_flag_type flags = match_default)
+{
+   std::basic_string<charT> result;
+   re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+   regex_replace(i, s.begin(), s.end(), e, fmt, flags);
+   return result;
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif  // NDNBOOST_REGEX_V4_REGEX_REPLACE_HPP
+
+
diff --git a/include/ndnboost/regex/v4/regex_search.hpp b/include/ndnboost/regex/v4/regex_search.hpp
new file mode 100644
index 0000000..2a480fd
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_search.hpp
@@ -0,0 +1,217 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_search.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides regex_search implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGEX_SEARCH_HPP
+#define NDNBOOST_REGEX_V4_REGEX_SEARCH_HPP
+
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class BidiIterator, class Allocator, class charT, class traits>
+bool regex_search(BidiIterator first, BidiIterator last, 
+                  match_results<BidiIterator, Allocator>& m, 
+                  const basic_regex<charT, traits>& e, 
+                  match_flag_type flags = match_default)
+{
+   return regex_search(first, last, m, e, flags, first);
+}
+
+template <class BidiIterator, class Allocator, class charT, class traits>
+bool regex_search(BidiIterator first, BidiIterator last, 
+                  match_results<BidiIterator, Allocator>& m, 
+                  const basic_regex<charT, traits>& e, 
+                  match_flag_type flags,
+                  BidiIterator base)
+{
+   if(e.flags() & regex_constants::failbit)
+      return false;
+
+   re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, base);
+   return matcher.find();
+}
+
+//
+// regex_search convenience interfaces:
+#ifndef NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class charT, class Allocator, class traits>
+inline bool regex_search(const charT* str, 
+                        match_results<const charT*, Allocator>& m, 
+                        const basic_regex<charT, traits>& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_search(str, str + traits::length(str), m, e, flags);
+}
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+inline bool regex_search(const std::basic_string<charT, ST, SA>& s, 
+                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   return regex_search(s.begin(), s.end(), m, e, flags);
+}
+#else  // partial overloads:
+inline bool regex_search(const char* str, 
+                        cmatch& m, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_search(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_search(const char* first, const char* last, 
+                  const regex& e, 
+                  match_flag_type flags = match_default)
+{
+   cmatch m;
+   return regex_search(first, last, m, e, flags | regex_constants::match_any);
+}
+
+#ifndef NDNBOOST_NO_WREGEX
+inline bool regex_search(const wchar_t* str, 
+                        wcmatch& m, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_search(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_search(const wchar_t* first, const wchar_t* last, 
+                  const wregex& e, 
+                  match_flag_type flags = match_default)
+{
+   wcmatch m;
+   return regex_search(first, last, m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_search(const std::string& s, 
+                        smatch& m,
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_search(s.begin(), s.end(), m, e, flags);
+}
+#if !defined(NDNBOOST_NO_WREGEX)
+inline bool regex_search(const std::basic_string<wchar_t>& s, 
+                        wsmatch& m,
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_search(s.begin(), s.end(), m, e, flags);
+}
+#endif
+
+#endif
+
+template <class BidiIterator, class charT, class traits>
+bool regex_search(BidiIterator first, BidiIterator last, 
+                  const basic_regex<charT, traits>& e, 
+                  match_flag_type flags = match_default)
+{
+   if(e.flags() & regex_constants::failbit)
+      return false;
+
+   match_results<BidiIterator> m;
+   typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;
+   re_detail::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any, first);
+   return matcher.find();
+}
+
+#ifndef NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template <class charT, class traits>
+inline bool regex_search(const charT* str, 
+                        const basic_regex<charT, traits>& e, 
+                        match_flag_type flags = match_default)
+{
+   return regex_search(str, str + traits::length(str), e, flags);
+}
+
+template <class ST, class SA, class charT, class traits>
+inline bool regex_search(const std::basic_string<charT, ST, SA>& s, 
+                 const basic_regex<charT, traits>& e, 
+                 match_flag_type flags = match_default)
+{
+   return regex_search(s.begin(), s.end(), e, flags);
+}
+#else  // non-template function overloads
+inline bool regex_search(const char* str, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   cmatch m;
+   return regex_search(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#ifndef NDNBOOST_NO_WREGEX
+inline bool regex_search(const wchar_t* str, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   wcmatch m;
+   return regex_search(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_search(const std::string& s, 
+                        const regex& e, 
+                        match_flag_type flags = match_default)
+{
+   smatch m;
+   return regex_search(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#if !defined(NDNBOOST_NO_WREGEX)
+inline bool regex_search(const std::basic_string<wchar_t>& s, 
+                        const wregex& e, 
+                        match_flag_type flags = match_default)
+{
+   wsmatch m;
+   return regex_search(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+
+#endif // NDNBOOST_NO_WREGEX
+
+#endif // partial overload
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif  // NDNBOOST_REGEX_V4_REGEX_SEARCH_HPP
+
+
diff --git a/include/ndnboost/regex/v4/regex_split.hpp b/include/ndnboost/regex/v4/regex_split.hpp
new file mode 100644
index 0000000..cdc67b3
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_split.hpp
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_split.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Implements regex_split and associated functions.
+  *                Note this is an internal header file included
+  *                by regex.hpp, do not include on its own.
+  */
+
+#ifndef NDNBOOST_REGEX_SPLIT_HPP
+#define NDNBOOST_REGEX_SPLIT_HPP
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable: 4800)
+#endif
+
+namespace re_detail{
+
+template <class charT>
+const basic_regex<charT>& get_default_expression(charT)
+{
+   static const charT expression_text[4] = { '\\', 's', '+', '\00', };
+   static const basic_regex<charT> e(expression_text);
+   return e;
+}
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1>
+class split_pred
+{
+   typedef std::basic_string<charT, Traits1, Alloc1> string_type;
+   typedef typename string_type::const_iterator iterator_type;
+   iterator_type* p_last;
+   OutputIterator* p_out;
+   std::size_t* p_max;
+   std::size_t initial_max;
+public:
+   split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
+      : p_last(a), p_out(b), p_max(c), initial_max(*c) {}
+
+   bool operator()(const match_results<iterator_type>& what);
+};
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1>
+bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
+   (const match_results<iterator_type>& what)
+{
+   *p_last = what[0].second;
+   if(what.size() > 1)
+   {
+      // output sub-expressions only:
+      for(unsigned i = 1; i < what.size(); ++i)
+      {
+         *(*p_out) = what.str(i);
+         ++(*p_out);
+         if(0 == --*p_max) return false;
+      }
+      return *p_max != 0;
+   }
+   else
+   {
+      // output $` only if it's not-null or not at the start of the input:
+      const sub_match<iterator_type>& sub = what[-1];
+      if((sub.first != sub.second) || (*p_max != initial_max))
+      {
+         *(*p_out) = sub.str();
+         ++(*p_out);
+         return --*p_max;
+      }
+   }
+   //
+   // initial null, do nothing:
+   return true;
+}
+
+} // namespace re_detail
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
+std::size_t regex_split(OutputIterator out,
+                   std::basic_string<charT, Traits1, Alloc1>& s, 
+                   const basic_regex<charT, Traits2>& e,
+                   match_flag_type flags,
+                   std::size_t max_split)
+{
+   typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator  ci_t;
+   //typedef typename match_results<ci_t>::allocator_type                        match_allocator;
+   ci_t last = s.begin();
+   std::size_t init_size = max_split;
+   re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);
+   ci_t i, j;
+   i = s.begin();
+   j = s.end();
+   regex_grep(pred, i, j, e, flags);
+   //
+   // if there is still input left, do a final push as long as max_split
+   // is not exhausted, and we're not splitting sub-expressions rather 
+   // than whitespace:
+   if(max_split && (last != s.end()) && (e.mark_count() == 1))
+   {
+      *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
+      ++out;
+      last = s.end();
+      --max_split;
+   }
+   //
+   // delete from the string everything that has been processed so far:
+   s.erase(0, last - s.begin());
+   //
+   // return the number of new records pushed:
+   return init_size - max_split;
+}
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
+inline std::size_t regex_split(OutputIterator out,
+                   std::basic_string<charT, Traits1, Alloc1>& s, 
+                   const basic_regex<charT, Traits2>& e,
+                   match_flag_type flags = match_default)
+{
+   return regex_split(out, s, e, flags, UINT_MAX);
+}
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1>
+inline std::size_t regex_split(OutputIterator out,
+                   std::basic_string<charT, Traits1, Alloc1>& s)
+{
+   return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
+}
+
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif
+
+
diff --git a/include/ndnboost/regex/v4/regex_token_iterator.hpp b/include/ndnboost/regex/v4/regex_token_iterator.hpp
new file mode 100644
index 0000000..7b61c9c
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_token_iterator.hpp
@@ -0,0 +1,342 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_token_iterator.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides regex_token_iterator implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+#define NDNBOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#if (NDNBOOST_WORKAROUND(__BORLANDC__, >= 0x560) && NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x570)))\
+      || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+      || NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3003))
+//
+// Borland C++ Builder 6, and Visual C++ 6,
+// can't cope with the array template constructor
+// so we have a template member that will accept any type as 
+// argument, and then assert that is really is an array:
+//
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_array.hpp>
+#endif
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, > 1300)
+#  pragma warning(push)
+#  pragma warning(disable:4700)
+#endif
+
+template <class BidirectionalIterator,
+          class charT,
+          class traits>
+class regex_token_iterator_implementation 
+{
+   typedef basic_regex<charT, traits> regex_type;
+   typedef sub_match<BidirectionalIterator>      value_type;
+
+   match_results<BidirectionalIterator> what;   // current match
+   BidirectionalIterator                base;    // start of search area
+   BidirectionalIterator                end;    // end of search area
+   const regex_type                     re;    // the expression
+   match_flag_type                      flags;  // match flags
+   value_type                           result; // the current string result
+   int                                  N;      // the current sub-expression being enumerated
+   std::vector<int>                     subs;   // the sub-expressions to enumerate
+
+public:
+   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
+      : end(last), re(*p), flags(f){ subs.push_back(sub); }
+   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
+      : end(last), re(*p), flags(f), subs(v){}
+#if !NDNBOOST_WORKAROUND(__HP_aCC, < 60700)
+#if (NDNBOOST_WORKAROUND(__BORLANDC__, >= 0x560) && NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x570)))\
+      || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+      || NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3003)) \
+      || NDNBOOST_WORKAROUND(__HP_aCC, < 60700)
+   template <class T>
+   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
+      : end(last), re(*p), flags(f)
+   {
+      // assert that T really is an array:
+      NDNBOOST_STATIC_ASSERT(::ndnboost::is_array<T>::value);
+      const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);
+      for(std::size_t i = 0; i < array_size; ++i)
+      {
+         subs.push_back(submatches[i]);
+      }
+   }
+#else
+   template <std::size_t CN>
+   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
+      : end(last), re(*p), flags(f)
+   {
+      for(std::size_t i = 0; i < CN; ++i)
+      {
+         subs.push_back(submatches[i]);
+      }
+   }
+#endif
+#endif
+   bool init(BidirectionalIterator first)
+   {
+      N = 0;
+      base = first;
+      if(regex_search(first, end, what, re, flags, base) == true)
+      {
+         N = 0;
+         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
+         return true;
+      }
+      else if((subs[N] == -1) && (first != end))
+      {
+         result.first = first;
+         result.second = end;
+         result.matched = (first != end);
+         N = -1;
+         return true;
+      }
+      return false;
+   }
+   bool compare(const regex_token_iterator_implementation& that)
+   {
+      if(this == &that) return true;
+      return (&re.get_data() == &that.re.get_data()) 
+         && (end == that.end) 
+         && (flags == that.flags) 
+         && (N == that.N) 
+         && (what[0].first == that.what[0].first) 
+         && (what[0].second == that.what[0].second);
+   }
+   const value_type& get()
+   { return result; }
+   bool next()
+   {
+      if(N == -1)
+         return false;
+      if(N+1 < (int)subs.size())
+      {
+         ++N;
+         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+         return true;
+      }
+      //if(what.prefix().first != what[0].second)
+      //   flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;
+      BidirectionalIterator last_end(what[0].second);
+      if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
+      {
+         N =0;
+         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+         return true;
+      }
+      else if((last_end != end) && (subs[0] == -1))
+      {
+         N =-1;
+         result.first = last_end;
+         result.second = end;
+         result.matched = (last_end != end);
+         return true;
+      }
+      return false;
+   }
+private:
+   regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&);
+};
+
+template <class BidirectionalIterator, 
+          class charT = NDNBOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
+          class traits = regex_traits<charT> >
+class regex_token_iterator 
+#ifndef NDNBOOST_NO_STD_ITERATOR
+   : public std::iterator<
+         std::forward_iterator_tag, 
+         sub_match<BidirectionalIterator>,
+         typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+         const sub_match<BidirectionalIterator>*,
+         const sub_match<BidirectionalIterator>& >         
+#endif
+{
+private:
+   typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;
+   typedef shared_ptr<impl> pimpl;
+public:
+   typedef          basic_regex<charT, traits>                   regex_type;
+   typedef          sub_match<BidirectionalIterator>                        value_type;
+   typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type 
+                                                                            difference_type;
+   typedef          const value_type*                                       pointer;
+   typedef          const value_type&                                       reference; 
+   typedef          std::forward_iterator_tag                               iterator_category;
+   
+   regex_token_iterator(){}
+   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, 
+                        int submatch = 0, match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatch, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, 
+                        const std::vector<int>& submatches, match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatches, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+#if !NDNBOOST_WORKAROUND(__HP_aCC, < 60700)
+#if (NDNBOOST_WORKAROUND(__BORLANDC__, >= 0x560) && NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x570)))\
+      || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+      || NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3003)) \
+      || NDNBOOST_WORKAROUND(__HP_aCC, < 60700)
+   template <class T>
+   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+                        const T& submatches, match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatches, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+#else
+   template <std::size_t N>
+   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+                        const int (&submatches)[N], match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatches, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+#endif
+#endif
+   regex_token_iterator(const regex_token_iterator& that)
+      : pdata(that.pdata) {}
+   regex_token_iterator& operator=(const regex_token_iterator& that)
+   {
+      pdata = that.pdata;
+      return *this;
+   }
+   bool operator==(const regex_token_iterator& that)const
+   { 
+      if((pdata.get() == 0) || (that.pdata.get() == 0))
+         return pdata.get() == that.pdata.get();
+      return pdata->compare(*(that.pdata.get())); 
+   }
+   bool operator!=(const regex_token_iterator& that)const
+   { return !(*this == that); }
+   const value_type& operator*()const
+   { return pdata->get(); }
+   const value_type* operator->()const
+   { return &(pdata->get()); }
+   regex_token_iterator& operator++()
+   {
+      cow();
+      if(0 == pdata->next())
+      {
+         pdata.reset();
+      }
+      return *this;
+   }
+   regex_token_iterator operator++(int)
+   {
+      regex_token_iterator result(*this);
+      ++(*this);
+      return result;
+   }
+private:
+
+   pimpl pdata;
+
+   void cow()
+   {
+      // copy-on-write
+      if(pdata.get() && !pdata.unique())
+      {
+         pdata.reset(new impl(*(pdata.get())));
+      }
+   }
+};
+
+typedef regex_token_iterator<const char*> cregex_token_iterator;
+typedef regex_token_iterator<std::string::const_iterator> sregex_token_iterator;
+#ifndef NDNBOOST_NO_WREGEX
+typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
+typedef regex_token_iterator<std::wstring::const_iterator> wsregex_token_iterator;
+#endif
+
+template <class charT, class traits>
+inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
+}
+template <class charT, class traits, class ST, class SA>
+inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
+}
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+template <class charT, class traits, std::size_t N>
+inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
+}
+template <class charT, class traits, class ST, class SA, std::size_t N>
+inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
+}
+#endif
+template <class charT, class traits>
+inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
+}
+template <class charT, class traits, class ST, class SA>
+inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
+}
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, > 1300)
+#  pragma warning(pop)
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+
+
+
+
diff --git a/include/ndnboost/regex/v4/regex_traits.hpp b/include/ndnboost/regex/v4/regex_traits.hpp
new file mode 100644
index 0000000..e991bb6
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_traits.hpp
@@ -0,0 +1,189 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_traits.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression traits classes.
+  */
+
+#ifndef NDNBOOST_REGEX_TRAITS_HPP_INCLUDED
+#define NDNBOOST_REGEX_TRAITS_HPP_INCLUDED
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_WORKAROUND_HPP
+#include <ndnboost/regex/v4/regex_workaround.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_SYNTAX_TYPE_HPP
+#include <ndnboost/regex/v4/syntax_type.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_ERROR_TYPE_HPP
+#include <ndnboost/regex/v4/error_type.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#include <ndnboost/regex/v4/regex_traits_defaults.hpp>
+#endif
+#ifndef NDNBOOST_NO_STD_LOCALE
+#  ifndef NDNBOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
+#     include <ndnboost/regex/v4/cpp_regex_traits.hpp>
+#  endif
+#endif
+#if !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x560)
+#  ifndef NDNBOOST_C_REGEX_TRAITS_HPP_INCLUDED
+#     include <ndnboost/regex/v4/c_regex_traits.hpp>
+#  endif
+#endif
+#if defined(_WIN32) && !defined(NDNBOOST_REGEX_NO_W32)
+#  ifndef NDNBOOST_W32_REGEX_TRAITS_HPP_INCLUDED
+#     include <ndnboost/regex/v4/w32_regex_traits.hpp>
+#  endif
+#endif
+#ifndef NDNBOOST_REGEX_FWD_HPP_INCLUDED
+#include <ndnboost/regex_fwd.hpp>
+#endif
+
+#include "ndnboost/mpl/has_xxx.hpp"
+#include <ndnboost/static_assert.hpp>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+
+template <class charT, class implementationT >
+struct regex_traits : public implementationT
+{
+   regex_traits() : implementationT() {}
+};
+
+//
+// class regex_traits_wrapper.
+// this is what our implementation will actually store;
+// it provides default implementations of the "optional"
+// interfaces that we support, in addition to the
+// required "standard" ones:
+//
+namespace re_detail{
+#if !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !NDNBOOST_WORKAROUND(__HP_aCC, < 60000)
+NDNBOOST_MPL_HAS_XXX_TRAIT_DEF(boost_extensions_tag)
+#else
+template<class T>
+struct has_boost_extensions_tag
+{
+   NDNBOOST_STATIC_CONSTANT(bool, value = false);
+};
+#endif
+
+template <class BaseT>
+struct default_wrapper : public BaseT
+{
+   typedef typename BaseT::char_type char_type;
+   std::string error_string(::ndnboost::regex_constants::error_type e)const
+   {
+      return ::ndnboost::re_detail::get_default_error_string(e);
+   }
+   ::ndnboost::regex_constants::syntax_type syntax_type(char_type c)const
+   {
+      return ((c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::ndnboost::regex_constants::syntax_char;
+   }
+   ::ndnboost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const
+   {
+      return ((c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::ndnboost::regex_constants::escape_type_identity;
+   }
+   int toi(const char_type*& p1, const char_type* p2, int radix)const
+   {
+      return ::ndnboost::re_detail::global_toi(p1, p2, radix, *this);
+   }
+   char_type translate(char_type c, bool icase)const
+   {
+      return (icase ? this->translate_nocase(c) : this->translate(c));
+   }
+   char_type translate(char_type c)const
+   {
+      return BaseT::translate(c);
+   }
+   char_type tolower(char_type c)const
+   {
+      return ::ndnboost::re_detail::global_lower(c);
+   }
+   char_type toupper(char_type c)const
+   {
+      return ::ndnboost::re_detail::global_upper(c);
+   }
+};
+
+template <class BaseT, bool has_extensions>
+struct compute_wrapper_base
+{
+   typedef BaseT type;
+};
+#if !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !NDNBOOST_WORKAROUND(__HP_aCC, < 60000)
+template <class BaseT>
+struct compute_wrapper_base<BaseT, false>
+{
+   typedef default_wrapper<BaseT> type;
+};
+#else
+template <>
+struct compute_wrapper_base<c_regex_traits<char>, false>
+{
+   typedef default_wrapper<c_regex_traits<char> > type;
+};
+#ifndef NDNBOOST_NO_WREGEX
+template <>
+struct compute_wrapper_base<c_regex_traits<wchar_t>, false>
+{
+   typedef default_wrapper<c_regex_traits<wchar_t> > type;
+};
+#endif
+#endif
+
+} // namespace re_detail
+
+template <class BaseT>
+struct regex_traits_wrapper 
+   : public ::ndnboost::re_detail::compute_wrapper_base<
+               BaseT, 
+               ::ndnboost::re_detail::has_boost_extensions_tag<BaseT>::value
+            >::type
+{
+   regex_traits_wrapper(){}
+private:
+   regex_traits_wrapper(const regex_traits_wrapper&);
+   regex_traits_wrapper& operator=(const regex_traits_wrapper&);
+};
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // include
+
diff --git a/include/ndnboost/regex/v4/regex_traits_defaults.hpp b/include/ndnboost/regex/v4/regex_traits_defaults.hpp
new file mode 100644
index 0000000..2b4fc28
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_traits_defaults.hpp
@@ -0,0 +1,371 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_traits_defaults.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares API's for access to regex_traits default properties.
+  */
+
+#ifndef NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#define NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifndef NDNBOOST_REGEX_SYNTAX_TYPE_HPP
+#include <ndnboost/regex/v4/syntax_type.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_ERROR_TYPE_HPP
+#include <ndnboost/regex/v4/error_type.hpp>
+#endif
+
+#ifdef NDNBOOST_NO_STDC_NAMESPACE
+namespace std{
+   using ::strlen;
+}
+#endif
+
+namespace ndnboost{ namespace re_detail{
+
+
+//
+// helpers to suppress warnings:
+//
+template <class charT>
+inline bool is_extended(charT c)
+{ return c > 256; }
+inline bool is_extended(char)
+{ return false; }
+
+
+NDNBOOST_REGEX_DECL const char* NDNBOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n);
+NDNBOOST_REGEX_DECL const char* NDNBOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n);
+NDNBOOST_REGEX_DECL regex_constants::syntax_type NDNBOOST_REGEX_CALL get_default_syntax_type(char c);
+NDNBOOST_REGEX_DECL regex_constants::escape_syntax_type NDNBOOST_REGEX_CALL get_default_escape_syntax_type(char c);
+
+// is charT c a combining character?
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL is_combining_implementation(uint_least16_t s);
+
+template <class charT>
+inline bool is_combining(charT c)
+{
+   return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
+}
+template <>
+inline bool is_combining<char>(char)
+{
+   return false;
+}
+template <>
+inline bool is_combining<signed char>(signed char)
+{
+   return false;
+}
+template <>
+inline bool is_combining<unsigned char>(unsigned char)
+{
+   return false;
+}
+#if !defined(__hpux) && !defined(__WINSCW__) // can't use WCHAR_MAX/MIN in pp-directives
+#ifdef _MSC_VER
+template<>
+inline bool is_combining<wchar_t>(wchar_t c)
+{
+   return is_combining_implementation(static_cast<unsigned short>(c));
+}
+#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
+#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
+template<>
+inline bool is_combining<wchar_t>(wchar_t c)
+{
+   return is_combining_implementation(static_cast<unsigned short>(c));
+}
+#else
+template<>
+inline bool is_combining<wchar_t>(wchar_t c)
+{
+   return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
+}
+#endif
+#endif
+#endif
+
+//
+// is a charT c a line separator?
+//
+template <class charT>
+inline bool is_separator(charT c)
+{
+   return NDNBOOST_REGEX_MAKE_BOOL(
+      (c == static_cast<charT>('\n'))
+      || (c == static_cast<charT>('\r'))
+      || (c == static_cast<charT>('\f'))
+      || (static_cast<ndnboost::uint16_t>(c) == 0x2028u)
+      || (static_cast<ndnboost::uint16_t>(c) == 0x2029u)
+      || (static_cast<ndnboost::uint16_t>(c) == 0x85u));
+}
+template <>
+inline bool is_separator<char>(char c)
+{
+   return NDNBOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (c == '\f'));
+}
+
+//
+// get a default collating element:
+//
+NDNBOOST_REGEX_DECL std::string NDNBOOST_REGEX_CALL lookup_default_collate_name(const std::string& name);
+
+//
+// get the state_id of a character clasification, the individual
+// traits classes then transform that state_id into a bitmask:
+//
+template <class charT>
+struct character_pointer_range
+{
+   const charT* p1;
+   const charT* p2;
+
+   bool operator < (const character_pointer_range& r)const
+   {
+      return std::lexicographical_compare(p1, p2, r.p1, r.p2);
+   }
+   bool operator == (const character_pointer_range& r)const
+   {
+      // Not only do we check that the ranges are of equal size before
+      // calling std::equal, but there is no other algorithm available:
+      // not even a non-standard MS one.  So forward to unchecked_equal
+      // in the MS case.
+      return ((p2 - p1) == (r.p2 - r.p1)) && re_detail::equal(p1, p2, r.p1);
+   }
+};
+template <class charT>
+int get_default_class_id(const charT* p1, const charT* p2)
+{
+   static const charT data[73] = {
+      'a', 'l', 'n', 'u', 'm',
+      'a', 'l', 'p', 'h', 'a',
+      'b', 'l', 'a', 'n', 'k',
+      'c', 'n', 't', 'r', 'l',
+      'd', 'i', 'g', 'i', 't',
+      'g', 'r', 'a', 'p', 'h',
+      'l', 'o', 'w', 'e', 'r',
+      'p', 'r', 'i', 'n', 't',
+      'p', 'u', 'n', 'c', 't',
+      's', 'p', 'a', 'c', 'e',
+      'u', 'n', 'i', 'c', 'o', 'd', 'e',
+      'u', 'p', 'p', 'e', 'r',
+      'v',
+      'w', 'o', 'r', 'd',
+      'x', 'd', 'i', 'g', 'i', 't',
+   };
+
+   static const character_pointer_range<charT> ranges[21] =
+   {
+      {data+0, data+5,}, // alnum
+      {data+5, data+10,}, // alpha
+      {data+10, data+15,}, // blank
+      {data+15, data+20,}, // cntrl
+      {data+20, data+21,}, // d
+      {data+20, data+25,}, // digit
+      {data+25, data+30,}, // graph
+      {data+29, data+30,}, // h
+      {data+30, data+31,}, // l
+      {data+30, data+35,}, // lower
+      {data+35, data+40,}, // print
+      {data+40, data+45,}, // punct
+      {data+45, data+46,}, // s
+      {data+45, data+50,}, // space
+      {data+57, data+58,}, // u
+      {data+50, data+57,}, // unicode
+      {data+57, data+62,}, // upper
+      {data+62, data+63,}, // v
+      {data+63, data+64,}, // w
+      {data+63, data+67,}, // word
+      {data+67, data+73,}, // xdigit
+   };
+   static const character_pointer_range<charT>* ranges_begin = ranges;
+   static const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
+
+   character_pointer_range<charT> t = { p1, p2, };
+   const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
+   if((p != ranges_end) && (t == *p))
+      return static_cast<int>(p - ranges);
+   return -1;
+}
+
+//
+// helper functions:
+//
+template <class charT>
+std::ptrdiff_t global_length(const charT* p)
+{
+   std::ptrdiff_t n = 0;
+   while(*p)
+   {
+      ++p;
+      ++n;
+   }
+   return n;
+}
+template<>
+inline std::ptrdiff_t global_length<char>(const char* p)
+{
+   return (std::strlen)(p);
+}
+#ifndef NDNBOOST_NO_WREGEX
+template<>
+inline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)
+{
+   return (std::wcslen)(p);
+}
+#endif
+template <class charT>
+inline charT NDNBOOST_REGEX_CALL global_lower(charT c)
+{
+   return c;
+}
+template <class charT>
+inline charT NDNBOOST_REGEX_CALL global_upper(charT c)
+{
+   return c;
+}
+
+NDNBOOST_REGEX_DECL char NDNBOOST_REGEX_CALL do_global_lower(char c);
+NDNBOOST_REGEX_DECL char NDNBOOST_REGEX_CALL do_global_upper(char c);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL wchar_t NDNBOOST_REGEX_CALL do_global_lower(wchar_t c);
+NDNBOOST_REGEX_DECL wchar_t NDNBOOST_REGEX_CALL do_global_upper(wchar_t c);
+#endif
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL unsigned short NDNBOOST_REGEX_CALL do_global_lower(unsigned short c);
+NDNBOOST_REGEX_DECL unsigned short NDNBOOST_REGEX_CALL do_global_upper(unsigned short c);
+#endif
+//
+// This sucks: declare template specialisations of global_lower/global_upper
+// that just forward to the non-template implementation functions.  We do
+// this because there is one compiler (Compaq Tru64 C++) that doesn't seem
+// to differentiate between templates and non-template overloads....
+// what's more, the primary template, plus all overloads have to be
+// defined in the same translation unit (if one is inline they all must be)
+// otherwise the "local template instantiation" compiler option can pick
+// the wrong instantiation when linking:
+//
+template<> inline char NDNBOOST_REGEX_CALL global_lower<char>(char c){ return do_global_lower(c); }
+template<> inline char NDNBOOST_REGEX_CALL global_upper<char>(char c){ return do_global_upper(c); }
+#ifndef NDNBOOST_NO_WREGEX
+template<> inline wchar_t NDNBOOST_REGEX_CALL global_lower<wchar_t>(wchar_t c){ return do_global_lower(c); }
+template<> inline wchar_t NDNBOOST_REGEX_CALL global_upper<wchar_t>(wchar_t c){ return do_global_upper(c); }
+#endif
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+template<> inline unsigned short NDNBOOST_REGEX_CALL global_lower<unsigned short>(unsigned short c){ return do_global_lower(c); }
+template<> inline unsigned short NDNBOOST_REGEX_CALL global_upper<unsigned short>(unsigned short c){ return do_global_upper(c); }
+#endif
+
+template <class charT>
+int global_value(charT c)
+{
+   static const charT zero = '0';
+   static const charT nine = '9';
+   static const charT a = 'a';
+   static const charT f = 'f';
+   static const charT A = 'A';
+   static const charT F = 'F';
+
+   if(c > f) return -1;
+   if(c >= a) return 10 + (c - a);
+   if(c > F) return -1;
+   if(c >= A) return 10 + (c - A);
+   if(c > nine) return -1;
+   if(c >= zero) return c - zero;
+   return -1;
+}
+template <class charT, class traits>
+int global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
+{
+   (void)t; // warning suppression
+   int next_value = t.value(*p1, radix);
+   if((p1 == p2) || (next_value < 0) || (next_value >= radix))
+      return -1;
+   int result = 0;
+   while(p1 != p2)
+   {
+      next_value = t.value(*p1, radix);
+      if((next_value < 0) || (next_value >= radix))
+         break;
+      result *= radix;
+      result += next_value;
+      ++p1;
+   }
+   return result;
+}
+
+template <class charT>
+inline const charT* get_escape_R_string()
+{
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable:4309 4245)
+#endif
+   static const charT e1[] = { '(', '?', '>', '\x0D', '\x0A', '?',
+      '|', '[', '\x0A', '\x0B', '\x0C', static_cast<unsigned char>('\x85'), '\\', 'x', '{', '2', '0', '2', '8', '}',
+                '\\', 'x', '{', '2', '0', '2', '9', '}', ']', ')', '\0' };
+   static const charT e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
+      '|', '[', '\x0A', '\x0B', '\x0C', static_cast<unsigned char>('\x85'), ']', ')', '\0' };
+
+   charT c = static_cast<charT>(0x2029u);
+   bool b = (static_cast<unsigned>(c) == 0x2029u);
+
+   return (b ? e1 : e2);
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+}
+
+template <>
+inline const char* get_escape_R_string<char>()
+{
+#ifdef NDNBOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable:4309)
+#endif
+   static const char e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
+      '|', '[', '\x0A', '\x0B', '\x0C', '\x85', ']', ')', '\0' };
+   return e2;
+#ifdef NDNBOOST_MSVC
+#  pragma warning(pop)
+#endif
+}
+
+} // re_detail
+} // boost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/ndnboost/regex/v4/regex_workaround.hpp b/include/ndnboost/regex/v4/regex_workaround.hpp
new file mode 100644
index 0000000..c9d4385
--- /dev/null
+++ b/include/ndnboost/regex/v4/regex_workaround.hpp
@@ -0,0 +1,232 @@
+/*
+ *
+ * Copyright (c) 1998-2005
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         regex_workarounds.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares Misc workarounds.
+  */
+
+#ifndef NDNBOOST_REGEX_WORKAROUND_HPP
+#define NDNBOOST_REGEX_WORKAROUND_HPP
+
+
+#include <new>
+#include <cstring>
+#include <cstdlib>
+#include <cstddef>
+#include <cassert>
+#include <cstdio>
+#include <climits>
+#include <string>
+#include <stdexcept>
+#include <iterator>
+#include <algorithm>
+#include <iosfwd>
+#include <vector>
+#include <map>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/scoped_ptr.hpp>
+#include <ndnboost/scoped_array.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/mpl/bool_fwd.hpp>
+#ifndef NDNBOOST_NO_STD_LOCALE
+#   include <locale>
+#endif
+
+#if defined(NDNBOOST_NO_STDC_NAMESPACE)
+namespace std{
+   using ::sprintf; using ::strcpy; using ::strcat; using ::strlen;
+}
+#endif
+
+namespace ndnboost{ namespace re_detail{
+#ifdef NDNBOOST_NO_STD_DISTANCE
+template <class T>
+std::ptrdiff_t distance(const T& x, const T& y)
+{ return y - x; }
+#else
+using std::distance;
+#endif
+}}
+
+
+#ifdef NDNBOOST_REGEX_NO_BOOL
+#  define NDNBOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)
+#else
+#  define NDNBOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)
+#endif
+
+/*****************************************************************************
+ *
+ *  Fix broken broken namespace support:
+ *
+ ****************************************************************************/
+
+#if defined(NDNBOOST_NO_STDC_NAMESPACE) && defined(__cplusplus)
+
+namespace std{
+   using ::ptrdiff_t;
+   using ::size_t;
+   using ::abs;
+   using ::memset;
+   using ::memcpy;
+}
+
+#endif
+
+/*****************************************************************************
+ *
+ *  helper functions pointer_construct/pointer_destroy:
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+namespace ndnboost{ namespace re_detail{
+
+#ifdef NDNBOOST_MSVC
+#pragma warning (push)
+#pragma warning (disable : 4100)
+#endif
+
+template <class T>
+inline void pointer_destroy(T* p)
+{ p->~T(); (void)p; }
+
+#ifdef NDNBOOST_MSVC
+#pragma warning (pop)
+#endif
+
+template <class T>
+inline void pointer_construct(T* p, const T& t)
+{ new (p) T(t); }
+
+}} // namespaces
+#endif
+
+/*****************************************************************************
+ *
+ *  helper function copy:
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+namespace ndnboost{ namespace re_detail{
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC,>=1400) && NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <1600) && defined(_CPPLIB_VER) && defined(NDNBOOST_DINKUMWARE_STDLIB) && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
+   //
+   // MSVC 8 will either emit warnings or else refuse to compile
+   // code that makes perfectly legitimate use of std::copy, when
+   // the OutputIterator type is a user-defined class (apparently all user 
+   // defined iterators are "unsafe").  This code works around that:
+   //
+   template<class InputIterator, class OutputIterator>
+   inline OutputIterator copy(
+      InputIterator first, 
+      InputIterator last, 
+      OutputIterator dest
+   )
+   {
+      return stdext::unchecked_copy(first, last, dest);
+   }
+   template<class InputIterator1, class InputIterator2>
+   inline bool equal(
+      InputIterator1 first, 
+      InputIterator1 last, 
+      InputIterator2 with
+   )
+   {
+      return stdext::unchecked_equal(first, last, with);
+   }
+#elif NDNBOOST_WORKAROUND(NDNBOOST_MSVC, > 1500)
+   //
+   // MSVC 10 will either emit warnings or else refuse to compile
+   // code that makes perfectly legitimate use of std::copy, when
+   // the OutputIterator type is a user-defined class (apparently all user 
+   // defined iterators are "unsafe").  What's more Microsoft have removed their
+   // non-standard "unchecked" versions, even though their still in the MS
+   // documentation!! Work around this as best we can: 
+   //
+   template<class InputIterator, class OutputIterator>
+   inline OutputIterator copy(
+      InputIterator first, 
+      InputIterator last, 
+      OutputIterator dest
+   )
+   {
+      while(first != last)
+         *dest++ = *first++;
+      return dest;
+   }
+   template<class InputIterator1, class InputIterator2>
+   inline bool equal(
+      InputIterator1 first, 
+      InputIterator1 last, 
+      InputIterator2 with
+   )
+   {
+      while(first != last)
+         if(*first++ != *with++) return false;
+      return true;
+   }
+#else 
+   using std::copy; 
+   using std::equal; 
+#endif 
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC,>=1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__ 
+
+   // use safe versions of strcpy etc:
+   using ::strcpy_s;
+   using ::strcat_s;
+#else
+   inline std::size_t strcpy_s(
+      char *strDestination,
+      std::size_t sizeInBytes,
+      const char *strSource 
+   )
+   {
+      if(std::strlen(strSource)+1 > sizeInBytes)
+         return 1;
+      std::strcpy(strDestination, strSource);
+      return 0;
+   }
+   inline std::size_t strcat_s(
+      char *strDestination,
+      std::size_t sizeInBytes,
+      const char *strSource 
+   )
+   {
+      if(std::strlen(strSource) + std::strlen(strDestination) + 1 > sizeInBytes)
+         return 1;
+      std::strcat(strDestination, strSource);
+      return 0;
+   }
+
+#endif
+
+   inline void overflow_error_if_not_zero(std::size_t i)
+   {
+      if(i)
+      {
+         std::overflow_error e("String buffer too small");
+         ndnboost::throw_exception(e);
+      }
+   }
+
+}} // namespaces
+
+#endif // __cplusplus
+
+#endif // include guard
+
diff --git a/include/ndnboost/regex/v4/states.hpp b/include/ndnboost/regex/v4/states.hpp
new file mode 100644
index 0000000..0698fa0
--- /dev/null
+++ b/include/ndnboost/regex/v4/states.hpp
@@ -0,0 +1,301 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         states.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares internal state machine structures.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_STATES_HPP
+#define NDNBOOST_REGEX_V4_STATES_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+namespace re_detail{
+
+/*** mask_type *******************************************************
+Whenever we have a choice of two alternatives, we use an array of bytes
+to indicate which of the two alternatives it is possible to take for any
+given input character.  If mask_take is set, then we can take the next 
+state, and if mask_skip is set then we can take the alternative.
+***********************************************************************/
+enum mask_type
+{
+   mask_take = 1,
+   mask_skip = 2,
+   mask_init = 4,
+   mask_any = mask_skip | mask_take,
+   mask_all = mask_any
+};
+
+/*** helpers **********************************************************
+These helpers let us use function overload resolution to detect whether
+we have narrow or wide character strings:
+***********************************************************************/
+struct _narrow_type{};
+struct _wide_type{};
+template <class charT> struct is_byte;
+template<>             struct is_byte<char>         { typedef _narrow_type width_type; };
+template<>             struct is_byte<unsigned char>{ typedef _narrow_type width_type; };
+template<>             struct is_byte<signed char>  { typedef _narrow_type width_type; };
+template <class charT> struct is_byte               { typedef _wide_type width_type; };
+
+/*** enum syntax_element_type ******************************************
+Every record in the state machine falls into one of the following types:
+***********************************************************************/
+enum syntax_element_type
+{
+   // start of a marked sub-expression, or perl-style (?...) extension
+   syntax_element_startmark = 0,
+   // end of a marked sub-expression, or perl-style (?...) extension
+   syntax_element_endmark = syntax_element_startmark + 1,
+   // any sequence of literal characters
+   syntax_element_literal = syntax_element_endmark + 1,
+   // start of line assertion: ^
+   syntax_element_start_line = syntax_element_literal + 1,
+   // end of line assertion $
+   syntax_element_end_line = syntax_element_start_line + 1,
+   // match any character: .
+   syntax_element_wild = syntax_element_end_line + 1,
+   // end of expression: we have a match when we get here
+   syntax_element_match = syntax_element_wild + 1,
+   // perl style word boundary: \b
+   syntax_element_word_boundary = syntax_element_match + 1,
+   // perl style within word boundary: \B
+   syntax_element_within_word = syntax_element_word_boundary + 1,
+   // start of word assertion: \<
+   syntax_element_word_start = syntax_element_within_word + 1,
+   // end of word assertion: \>
+   syntax_element_word_end = syntax_element_word_start + 1,
+   // start of buffer assertion: \`
+   syntax_element_buffer_start = syntax_element_word_end + 1,
+   // end of buffer assertion: \'
+   syntax_element_buffer_end = syntax_element_buffer_start + 1,
+   // backreference to previously matched sub-expression
+   syntax_element_backref = syntax_element_buffer_end + 1,
+   // either a wide character set [..] or one with multicharacter collating elements:
+   syntax_element_long_set = syntax_element_backref + 1,
+   // narrow character set: [...]
+   syntax_element_set = syntax_element_long_set + 1,
+   // jump to a new state in the machine:
+   syntax_element_jump = syntax_element_set + 1,
+   // choose between two production states:
+   syntax_element_alt = syntax_element_jump + 1,
+   // a repeat
+   syntax_element_rep = syntax_element_alt + 1,
+   // match a combining character sequence
+   syntax_element_combining = syntax_element_rep + 1,
+   // perl style soft buffer end: \z
+   syntax_element_soft_buffer_end = syntax_element_combining + 1,
+   // perl style continuation: \G
+   syntax_element_restart_continue = syntax_element_soft_buffer_end + 1,
+   // single character repeats:
+   syntax_element_dot_rep = syntax_element_restart_continue + 1,
+   syntax_element_char_rep = syntax_element_dot_rep + 1,
+   syntax_element_short_set_rep = syntax_element_char_rep + 1,
+   syntax_element_long_set_rep = syntax_element_short_set_rep + 1,
+   // a backstep for lookbehind repeats:
+   syntax_element_backstep = syntax_element_long_set_rep + 1,
+   // an assertion that a mark was matched:
+   syntax_element_assert_backref = syntax_element_backstep + 1,
+   syntax_element_toggle_case = syntax_element_assert_backref + 1,
+   // a recursive expression:
+   syntax_element_recurse = syntax_element_toggle_case + 1
+};
+
+#ifdef NDNBOOST_REGEX_DEBUG
+// dwa 09/26/00 - This is needed to suppress warnings about an ambiguous conversion
+std::ostream& operator<<(std::ostream&, syntax_element_type);
+#endif
+
+struct re_syntax_base;
+
+/*** union offset_type ************************************************
+Points to another state in the machine.  During machine construction
+we use integral offsets, but these are converted to pointers before
+execution of the machine.
+***********************************************************************/
+union offset_type
+{
+   re_syntax_base*   p;
+   std::ptrdiff_t    i;
+};
+
+/*** struct re_syntax_base ********************************************
+Base class for all states in the machine.
+***********************************************************************/
+struct re_syntax_base
+{
+   syntax_element_type   type;         // what kind of state this is
+   offset_type           next;         // next state in the machine
+};
+
+/*** struct re_brace **************************************************
+A marked parenthesis.
+***********************************************************************/
+struct re_brace : public re_syntax_base
+{
+   // The index to match, can be zero (don't mark the sub-expression)
+   // or negative (for perl style (?...) extentions):
+   int index;
+   bool icase;
+};
+
+/*** struct re_dot **************************************************
+Match anything.
+***********************************************************************/
+enum
+{
+   dont_care = 1,
+   force_not_newline = 0,
+   force_newline = 2,
+
+   test_not_newline = 2,
+   test_newline = 3
+};
+struct re_dot : public re_syntax_base
+{
+   unsigned char mask;
+};
+
+/*** struct re_literal ************************************************
+A string of literals, following this structure will be an 
+array of characters: charT[length]
+***********************************************************************/
+struct re_literal : public re_syntax_base
+{
+   unsigned int length;
+};
+
+/*** struct re_case ************************************************
+Indicates whether we are moving to a case insensive block or not
+***********************************************************************/
+struct re_case : public re_syntax_base
+{
+   bool icase;
+};
+
+/*** struct re_set_long ***********************************************
+A wide character set of characters, following this structure will be
+an array of type charT:
+First csingles null-terminated strings
+Then 2 * cranges NULL terminated strings
+Then cequivalents NULL terminated strings
+***********************************************************************/
+template <class mask_type>
+struct re_set_long : public re_syntax_base
+{
+   unsigned int            csingles, cranges, cequivalents;
+   mask_type               cclasses;
+   mask_type               cnclasses;
+   bool                    isnot;
+   bool                    singleton;
+};
+
+/*** struct re_set ****************************************************
+A set of narrow-characters, matches any of _map which is none-zero
+***********************************************************************/
+struct re_set : public re_syntax_base
+{
+   unsigned char _map[1 << CHAR_BIT];
+};
+
+/*** struct re_jump ***************************************************
+Jump to a new location in the machine (not next).
+***********************************************************************/
+struct re_jump : public re_syntax_base
+{
+   offset_type     alt;                 // location to jump to
+};
+
+/*** struct re_alt ***************************************************
+Jump to a new location in the machine (possibly next).
+***********************************************************************/
+struct re_alt : public re_jump
+{
+   unsigned char   _map[1 << CHAR_BIT]; // which characters can take the jump
+   unsigned int    can_be_null;         // true if we match a NULL string
+};
+
+/*** struct re_repeat *************************************************
+Repeat a section of the machine
+***********************************************************************/
+struct re_repeat : public re_alt
+{
+   std::size_t   min, max;  // min and max allowable repeats
+   int           state_id;        // Unique identifier for this repeat
+   bool          leading;   // True if this repeat is at the start of the machine (lets us optimize some searches)
+   bool          greedy;    // True if this is a greedy repeat
+};
+
+/*** struct re_recurse ************************************************
+Recurse to a particular subexpression.
+**********************************************************************/
+struct re_recurse : public re_jump
+{
+   int state_id;             // identifier of first nested repeat within the recursion.
+};
+
+/*** enum re_jump_size_type *******************************************
+Provides compiled size of re_jump structure (allowing for trailing alignment).
+We provide this so we know how manybytes to insert when constructing the machine
+(The value of padding_mask is defined in regex_raw_buffer.hpp).
+***********************************************************************/
+enum re_jump_size_type
+{
+   re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),
+   re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask),
+   re_alt_size = (sizeof(re_alt) + padding_mask) & ~(padding_mask)
+};
+
+/*** proc re_is_set_member *********************************************
+Forward declaration: we'll need this one later...
+***********************************************************************/
+
+template<class charT, class traits>
+struct regex_data;
+
+template <class iterator, class charT, class traits_type, class char_classT>
+iterator NDNBOOST_REGEX_CALL re_is_set_member(iterator next, 
+                          iterator last, 
+                          const re_set_long<char_classT>* set_, 
+                          const regex_data<charT, traits_type>& e, bool icase);
+
+} // namespace re_detail
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
diff --git a/include/ndnboost/regex/v4/sub_match.hpp b/include/ndnboost/regex/v4/sub_match.hpp
new file mode 100644
index 0000000..621cc83
--- /dev/null
+++ b/include/ndnboost/regex/v4/sub_match.hpp
@@ -0,0 +1,512 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         sub_match.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares template class sub_match.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_SUB_MATCH_HPP
+#define NDNBOOST_REGEX_V4_SUB_MATCH_HPP
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace ndnboost{
+
+template <class BidiIterator>
+struct sub_match : public std::pair<BidiIterator, BidiIterator>
+{
+   typedef typename re_detail::regex_iterator_traits<BidiIterator>::value_type       value_type;
+#if defined(NDNBOOST_NO_STD_ITERATOR_TRAITS) || defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+   typedef          std::ptrdiff_t                                                   difference_type;
+#else
+   typedef typename re_detail::regex_iterator_traits<BidiIterator>::difference_type  difference_type;
+#endif
+   typedef          BidiIterator                                                     iterator_type;
+   typedef          BidiIterator                                                     iterator;
+   typedef          BidiIterator                                                     const_iterator;
+
+   bool matched;
+
+   sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
+   sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
+#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)\
+               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)\
+               && !NDNBOOST_WORKAROUND(__DECCXX_VER, NDNBOOST_TESTED_AT(60590042))
+   template <class T, class A>
+   operator std::basic_string<value_type, T, A> ()const
+   {
+      return matched ? std::basic_string<value_type, T, A>(this->first, this->second) : std::basic_string<value_type, T, A>();
+   }
+#else
+   operator std::basic_string<value_type> ()const
+   {
+      return str();
+   }
+#endif
+   difference_type NDNBOOST_REGEX_CALL length()const
+   {
+      difference_type n = matched ? ::ndnboost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0;
+      return n;
+   }
+   std::basic_string<value_type> str()const
+   {
+      std::basic_string<value_type> result;
+      if(matched)
+      {
+         std::size_t len = ::ndnboost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
+         result.reserve(len);
+         BidiIterator i = this->first;
+         while(i != this->second)
+         {
+            result.append(1, *i);
+            ++i;
+         }
+      }
+      return result;
+   }
+   int compare(const sub_match& s)const
+   {
+      if(matched != s.matched)
+         return static_cast<int>(matched) - static_cast<int>(s.matched);
+      return str().compare(s.str());
+   }
+   int compare(const std::basic_string<value_type>& s)const
+   {
+      return str().compare(s);
+   }
+   int compare(const value_type* p)const
+   {
+      return str().compare(p);
+   }
+
+   bool operator==(const sub_match& that)const
+   { return compare(that) == 0; }
+   bool NDNBOOST_REGEX_CALL operator !=(const sub_match& that)const
+   { return compare(that) != 0; }
+   bool operator<(const sub_match& that)const
+   { return compare(that) < 0; }
+   bool operator>(const sub_match& that)const
+   { return compare(that) > 0; }
+   bool operator<=(const sub_match& that)const
+   { return compare(that) <= 0; }
+   bool operator>=(const sub_match& that)const
+   { return compare(that) >= 0; }
+
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+   typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;
+
+   const capture_sequence_type& captures()const
+   {
+      if(!m_captures) 
+         m_captures.reset(new capture_sequence_type());
+      return *m_captures;
+   }
+   //
+   // Private implementation API: DO NOT USE!
+   //
+   capture_sequence_type& get_captures()const
+   {
+      if(!m_captures) 
+         m_captures.reset(new capture_sequence_type());
+      return *m_captures;
+   }
+
+private:
+   mutable ndnboost::scoped_ptr<capture_sequence_type> m_captures;
+public:
+
+#endif
+   sub_match(const sub_match& that, bool 
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+      deep_copy
+#endif
+      = true
+      ) 
+      : std::pair<BidiIterator, BidiIterator>(that), 
+        matched(that.matched) 
+   {
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+      if(that.m_captures)
+         if(deep_copy)
+            m_captures.reset(new capture_sequence_type(*(that.m_captures)));
+#endif
+   }
+   sub_match& operator=(const sub_match& that)
+   {
+      this->first = that.first;
+      this->second = that.second;
+      matched = that.matched;
+#ifdef NDNBOOST_REGEX_MATCH_EXTRA
+      if(that.m_captures)
+         get_captures() = *(that.m_captures);
+#endif
+      return *this;
+   }
+
+
+#ifdef NDNBOOST_OLD_REGEX_H
+   //
+   // the following are deprecated, do not use!!
+   //
+   operator int()const;
+   operator unsigned int()const;
+   operator short()const
+   {
+      return (short)(int)(*this);
+   }
+   operator unsigned short()const
+   {
+      return (unsigned short)(unsigned int)(*this);
+   }
+#endif
+};
+
+typedef sub_match<const char*> csub_match;
+typedef sub_match<std::string::const_iterator> ssub_match;
+#ifndef NDNBOOST_NO_WREGEX
+typedef sub_match<const wchar_t*> wcsub_match;
+typedef sub_match<std::wstring::const_iterator> wssub_match;
+#endif
+
+// comparison to std::basic_string<> part 1:
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator == (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) == 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator != (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) != 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator < (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                 const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) < 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator <= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) <= 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator >= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) >= 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator > (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                 const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) > 0; }
+// comparison to std::basic_string<> part 2:
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator == (const sub_match<RandomAccessIterator>& m,
+                  const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) == 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator != (const sub_match<RandomAccessIterator>& m,
+                  const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) != 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator < (const sub_match<RandomAccessIterator>& m,
+                  const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) < 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator > (const sub_match<RandomAccessIterator>& m,
+                  const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) > 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator <= (const sub_match<RandomAccessIterator>& m,
+                  const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) <= 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator >= (const sub_match<RandomAccessIterator>& m,
+                  const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) >= 0; }
+// comparison to const charT* part 1:
+template <class RandomAccessIterator>
+inline bool operator == (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) != 0; }
+template <class RandomAccessIterator>
+inline bool operator > (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) > 0; }
+template <class RandomAccessIterator>
+inline bool operator < (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) < 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) <= 0; }
+// comparison to const charT* part 2:
+template <class RandomAccessIterator>
+inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) != 0; }
+template <class RandomAccessIterator>
+inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) > 0; }
+template <class RandomAccessIterator>
+inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) < 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) <= 0; }
+
+// comparison to const charT& part 1:
+template <class RandomAccessIterator>
+inline bool operator == (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) != 0; }
+template <class RandomAccessIterator>
+inline bool operator > (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) > 0; }
+template <class RandomAccessIterator>
+inline bool operator < (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) < 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (const sub_match<RandomAccessIterator>& m,
+                  typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
+// comparison to const charT* part 2:
+template <class RandomAccessIterator>
+inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) != 0; }
+template <class RandomAccessIterator>
+inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) > 0; }
+template <class RandomAccessIterator>
+inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) < 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
+
+// addition operators:
+template <class RandomAccessIterator, class traits, class Allocator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> 
+operator + (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+                  const sub_match<RandomAccessIterator>& m)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
+   result.reserve(s.size() + m.length() + 1);
+   return result.append(s).append(m.first, m.second);
+}
+template <class RandomAccessIterator, class traits, class Allocator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> 
+operator + (const sub_match<RandomAccessIterator>& m,
+            const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
+   result.reserve(s.size() + m.length() + 1);
+   return result.append(m.first, m.second).append(s);
+}
+#if !(defined(__GNUC__) && defined(NDNBOOST_NO_STD_LOCALE))
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+   result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
+   return result.append(s).append(m.first, m.second);
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (const sub_match<RandomAccessIterator>& m,
+            typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+   result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
+   return result.append(m.first, m.second).append(s);
+}
+#else
+// worwaround versions:
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+                  const sub_match<RandomAccessIterator>& m)
+{
+   return s + m.str();
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (const sub_match<RandomAccessIterator>& m,
+            typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
+{
+   return m.str() + s;
+}
+#endif
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+                  const sub_match<RandomAccessIterator>& m)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+   result.reserve(m.length() + 2);
+   return result.append(1, s).append(m.first, m.second);
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (const sub_match<RandomAccessIterator>& m,
+            typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+   result.reserve(m.length() + 2);
+   return result.append(m.first, m.second).append(1, s);
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> 
+operator + (const sub_match<RandomAccessIterator>& m1,
+            const sub_match<RandomAccessIterator>& m2)
+{
+   std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+   result.reserve(m1.length() + m2.length() + 1);
+   return result.append(m1.first, m1.second).append(m2.first, m2.second);
+}
+#ifndef NDNBOOST_NO_STD_LOCALE
+template <class charT, class traits, class RandomAccessIterator>
+std::basic_ostream<charT, traits>&
+   operator << (std::basic_ostream<charT, traits>& os,
+                const sub_match<RandomAccessIterator>& s)
+{
+   return (os << s.str());
+}
+#else
+template <class RandomAccessIterator>
+std::ostream& operator << (std::ostream& os,
+                           const sub_match<RandomAccessIterator>& s)
+{
+   return (os << s.str());
+}
+#endif
+
+#ifdef NDNBOOST_OLD_REGEX_H
+namespace re_detail{
+template <class BidiIterator, class charT>
+int do_toi(BidiIterator i, BidiIterator j, char c, int radix)
+{
+   std::string s(i, j);
+   char* p;
+   int result = std::strtol(s.c_str(), &p, radix);
+   if(*p)raise_regex_exception("Bad sub-expression");
+   return result;
+}
+
+//
+// helper:
+template <class I, class charT>
+int do_toi(I& i, I j, charT c)
+{
+   int result = 0;
+   while((i != j) && (isdigit(*i)))
+   {
+      result = result*10 + (*i - '0');
+      ++i;
+   }
+   return result;
+}
+}
+
+
+template <class BidiIterator>
+sub_match<BidiIterator>::operator int()const
+{
+   BidiIterator i = first;
+   BidiIterator j = second;
+   if(i == j)raise_regex_exception("Bad sub-expression");
+   int neg = 1;
+   if((i != j) && (*i == '-'))
+   {
+      neg = -1;
+      ++i;
+   }
+   neg *= re_detail::do_toi(i, j, *i);
+   if(i != j)raise_regex_exception("Bad sub-expression");
+   return neg;
+}
+template <class BidiIterator>
+sub_match<BidiIterator>::operator unsigned int()const
+{
+   BidiIterator i = first;
+   BidiIterator j = second;
+   if(i == j)
+      raise_regex_exception("Bad sub-expression");
+   return re_detail::do_toi(i, j, *first);
+}
+#endif
+
+} // namespace ndnboost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/include/ndnboost/regex/v4/syntax_type.hpp b/include/ndnboost/regex/v4/syntax_type.hpp
new file mode 100644
index 0000000..e8c5170
--- /dev/null
+++ b/include/ndnboost/regex/v4/syntax_type.hpp
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         syntax_type.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression synatx type enumerator.
+  */
+
+#ifndef NDNBOOST_REGEX_SYNTAX_TYPE_HPP
+#define NDNBOOST_REGEX_SYNTAX_TYPE_HPP
+
+namespace ndnboost{
+namespace regex_constants{
+
+typedef unsigned char syntax_type;
+
+//
+// values chosen are binary compatible with previous version:
+//
+static const syntax_type syntax_char = 0;
+static const syntax_type syntax_open_mark = 1;
+static const syntax_type syntax_close_mark = 2;
+static const syntax_type syntax_dollar = 3;
+static const syntax_type syntax_caret = 4;
+static const syntax_type syntax_dot = 5;
+static const syntax_type syntax_star = 6;
+static const syntax_type syntax_plus = 7;
+static const syntax_type syntax_question = 8;
+static const syntax_type syntax_open_set = 9;
+static const syntax_type syntax_close_set = 10;
+static const syntax_type syntax_or = 11;
+static const syntax_type syntax_escape = 12;
+static const syntax_type syntax_dash = 14;
+static const syntax_type syntax_open_brace = 15;
+static const syntax_type syntax_close_brace = 16;
+static const syntax_type syntax_digit = 17;
+static const syntax_type syntax_comma = 27;
+static const syntax_type syntax_equal = 37;
+static const syntax_type syntax_colon = 36;
+static const syntax_type syntax_not = 53;
+
+// extensions:
+
+static const syntax_type syntax_hash = 13;
+static const syntax_type syntax_newline = 26;
+
+// escapes:
+
+typedef syntax_type escape_syntax_type;
+
+static const escape_syntax_type escape_type_word_assert = 18;
+static const escape_syntax_type escape_type_not_word_assert = 19;
+static const escape_syntax_type escape_type_control_f = 29;
+static const escape_syntax_type escape_type_control_n = 30;
+static const escape_syntax_type escape_type_control_r = 31;
+static const escape_syntax_type escape_type_control_t = 32;
+static const escape_syntax_type escape_type_control_v = 33;
+static const escape_syntax_type escape_type_ascii_control = 35;
+static const escape_syntax_type escape_type_hex = 34;
+static const escape_syntax_type escape_type_unicode = 0; // not used
+static const escape_syntax_type escape_type_identity = 0; // not used
+static const escape_syntax_type escape_type_backref = syntax_digit;
+static const escape_syntax_type escape_type_decimal = syntax_digit; // not used
+static const escape_syntax_type escape_type_class = 22; 
+static const escape_syntax_type escape_type_not_class = 23; 
+
+// extensions:
+
+static const escape_syntax_type escape_type_left_word = 20;
+static const escape_syntax_type escape_type_right_word = 21;
+static const escape_syntax_type escape_type_start_buffer = 24;                 // for \`
+static const escape_syntax_type escape_type_end_buffer = 25;                   // for \'
+static const escape_syntax_type escape_type_control_a = 28;                    // for \a
+static const escape_syntax_type escape_type_e = 38;                            // for \e
+static const escape_syntax_type escape_type_E = 47;                            // for \Q\E
+static const escape_syntax_type escape_type_Q = 48;                            // for \Q\E
+static const escape_syntax_type escape_type_X = 49;                            // for \X
+static const escape_syntax_type escape_type_C = 50;                            // for \C
+static const escape_syntax_type escape_type_Z = 51;                            // for \Z
+static const escape_syntax_type escape_type_G = 52;                            // for \G
+
+static const escape_syntax_type escape_type_property = 54;                     // for \p
+static const escape_syntax_type escape_type_not_property = 55;                 // for \P
+static const escape_syntax_type escape_type_named_char = 56;                   // for \N
+static const escape_syntax_type escape_type_extended_backref = 57;             // for \g
+static const escape_syntax_type escape_type_reset_start_mark = 58;             // for \K
+static const escape_syntax_type escape_type_line_ending = 59;                  // for \R
+
+static const escape_syntax_type syntax_max = 60;
+
+}
+}
+
+
+#endif
diff --git a/include/ndnboost/regex/v4/u32regex_iterator.hpp b/include/ndnboost/regex/v4/u32regex_iterator.hpp
new file mode 100644
index 0000000..27149f6
--- /dev/null
+++ b/include/ndnboost/regex/v4/u32regex_iterator.hpp
@@ -0,0 +1,193 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         u32regex_iterator.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides u32regex_iterator implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_U32REGEX_ITERATOR_HPP
+#define NDNBOOST_REGEX_V4_U32REGEX_ITERATOR_HPP
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+
+template <class BidirectionalIterator>
+class u32regex_iterator_implementation 
+{
+   typedef u32regex regex_type;
+
+   match_results<BidirectionalIterator> what;  // current match
+   BidirectionalIterator                base;  // start of sequence
+   BidirectionalIterator                end;   // end of sequence
+   const regex_type                     re;   // the expression
+   match_flag_type                      flags; // flags for matching
+
+public:
+   u32regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
+      : base(), end(last), re(*p), flags(f){}
+   bool init(BidirectionalIterator first)
+   {
+      base = first;
+      return u32regex_search(first, end, what, re, flags, base);
+   }
+   bool compare(const u32regex_iterator_implementation& that)
+   {
+      if(this == &that) return true;
+      return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
+   }
+   const match_results<BidirectionalIterator>& get()
+   { return what; }
+   bool next()
+   {
+      //if(what.prefix().first != what[0].second)
+      //   flags |= match_prev_avail;
+      BidirectionalIterator next_start = what[0].second;
+      match_flag_type f(flags);
+      if(!what.length())
+         f |= regex_constants::match_not_initial_null;
+      //if(base != next_start)
+      //   f |= regex_constants::match_not_bob;
+      bool result = u32regex_search(next_start, end, what, re, f, base);
+      if(result)
+         what.set_base(base);
+      return result;
+   }
+private:
+   u32regex_iterator_implementation& operator=(const u32regex_iterator_implementation&);
+};
+
+template <class BidirectionalIterator>
+class u32regex_iterator 
+#ifndef NDNBOOST_NO_STD_ITERATOR
+   : public std::iterator<
+         std::forward_iterator_tag, 
+         match_results<BidirectionalIterator>,
+         typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+         const match_results<BidirectionalIterator>*,
+         const match_results<BidirectionalIterator>& >         
+#endif
+{
+private:
+   typedef u32regex_iterator_implementation<BidirectionalIterator> impl;
+   typedef shared_ptr<impl> pimpl;
+public:
+   typedef          u32regex                                                regex_type;
+   typedef          match_results<BidirectionalIterator>                    value_type;
+   typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type 
+                                                                            difference_type;
+   typedef          const value_type*                                       pointer;
+   typedef          const value_type&                                       reference; 
+   typedef          std::forward_iterator_tag                               iterator_category;
+   
+   u32regex_iterator(){}
+   u32regex_iterator(BidirectionalIterator a, BidirectionalIterator b, 
+                  const regex_type& re, 
+                  match_flag_type m = match_default)
+                  : pdata(new impl(&re, b, m))
+   {
+      if(!pdata->init(a))
+      {
+         pdata.reset();
+      }
+   }
+   u32regex_iterator(const u32regex_iterator& that)
+      : pdata(that.pdata) {}
+   u32regex_iterator& operator=(const u32regex_iterator& that)
+   {
+      pdata = that.pdata;
+      return *this;
+   }
+   bool operator==(const u32regex_iterator& that)const
+   { 
+      if((pdata.get() == 0) || (that.pdata.get() == 0))
+         return pdata.get() == that.pdata.get();
+      return pdata->compare(*(that.pdata.get())); 
+   }
+   bool operator!=(const u32regex_iterator& that)const
+   { return !(*this == that); }
+   const value_type& operator*()const
+   { return pdata->get(); }
+   const value_type* operator->()const
+   { return &(pdata->get()); }
+   u32regex_iterator& operator++()
+   {
+      cow();
+      if(0 == pdata->next())
+      {
+         pdata.reset();
+      }
+      return *this;
+   }
+   u32regex_iterator operator++(int)
+   {
+      u32regex_iterator result(*this);
+      ++(*this);
+      return result;
+   }
+private:
+
+   pimpl pdata;
+
+   void cow()
+   {
+      // copy-on-write
+      if(pdata.get() && !pdata.unique())
+      {
+         pdata.reset(new impl(*(pdata.get())));
+      }
+   }
+};
+
+typedef u32regex_iterator<const char*> utf8regex_iterator;
+typedef u32regex_iterator<const UChar*> utf16regex_iterator;
+typedef u32regex_iterator<const UChar32*> utf32regex_iterator;
+
+inline u32regex_iterator<const char*> make_u32regex_iterator(const char* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_iterator<const char*>(p, p+std::strlen(p), e, m);
+}
+#ifndef NDNBOOST_NO_WREGEX
+inline u32regex_iterator<const wchar_t*> make_u32regex_iterator(const wchar_t* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_iterator<const wchar_t*>(p, p+std::wcslen(p), e, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex_iterator<const UChar*> make_u32regex_iterator(const UChar* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_iterator<const UChar*>(p, p+u_strlen(p), e, m);
+}
+#endif
+template <class charT, class Traits, class Alloc>
+inline u32regex_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+   return u32regex_iterator<iter_type>(p.begin(), p.end(), e, m);
+}
+inline u32regex_iterator<const UChar*> make_u32regex_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, m);
+}
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_REGEX_V4_REGEX_ITERATOR_HPP
+
diff --git a/include/ndnboost/regex/v4/u32regex_token_iterator.hpp b/include/ndnboost/regex/v4/u32regex_token_iterator.hpp
new file mode 100644
index 0000000..08d40cf
--- /dev/null
+++ b/include/ndnboost/regex/v4/u32regex_token_iterator.hpp
@@ -0,0 +1,377 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         u32regex_token_iterator.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Provides u32regex_token_iterator implementation.
+  */
+
+#ifndef NDNBOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP
+#define NDNBOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP
+
+#if (NDNBOOST_WORKAROUND(__BORLANDC__, >= 0x560) && NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x570)))\
+      || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+      || NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3003))
+//
+// Borland C++ Builder 6, and Visual C++ 6,
+// can't cope with the array template constructor
+// so we have a template member that will accept any type as 
+// argument, and then assert that is really is an array:
+//
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_array.hpp>
+#endif
+
+namespace ndnboost{
+
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, > 1300)
+#  pragma warning(push)
+#  pragma warning(disable:4700)
+#endif
+
+template <class BidirectionalIterator>
+class u32regex_token_iterator_implementation 
+{
+   typedef u32regex                              regex_type;
+   typedef sub_match<BidirectionalIterator>      value_type;
+
+   match_results<BidirectionalIterator> what;   // current match
+   BidirectionalIterator                end;    // end of search area
+   BidirectionalIterator                base;   // start of search area
+   const regex_type                     re;     // the expression
+   match_flag_type                      flags;  // match flags
+   value_type                           result; // the current string result
+   int                                  N;      // the current sub-expression being enumerated
+   std::vector<int>                     subs;   // the sub-expressions to enumerate
+
+public:
+   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
+      : end(last), re(*p), flags(f){ subs.push_back(sub); }
+   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
+      : end(last), re(*p), flags(f), subs(v){}
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+      // can't reliably get this to work....
+#elif (NDNBOOST_WORKAROUND(__BORLANDC__, >= 0x560) && NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x570)))\
+      || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+      || NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3003)) \
+      || NDNBOOST_WORKAROUND(__HP_aCC, < 60700)
+   template <class T>
+   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
+      : end(last), re(*p), flags(f)
+   {
+      // assert that T really is an array:
+      NDNBOOST_STATIC_ASSERT(::ndnboost::is_array<T>::value);
+      const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);
+      for(std::size_t i = 0; i < array_size; ++i)
+      {
+         subs.push_back(submatches[i]);
+      }
+   }
+#else
+   template <std::size_t CN>
+   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
+      : end(last), re(*p), flags(f)
+   {
+      for(std::size_t i = 0; i < CN; ++i)
+      {
+         subs.push_back(submatches[i]);
+      }
+   }
+#endif
+
+   bool init(BidirectionalIterator first)
+   {
+      base = first;
+      N = 0;
+      if(u32regex_search(first, end, what, re, flags, base) == true)
+      {
+         N = 0;
+         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
+         return true;
+      }
+      else if((subs[N] == -1) && (first != end))
+      {
+         result.first = first;
+         result.second = end;
+         result.matched = (first != end);
+         N = -1;
+         return true;
+      }
+      return false;
+   }
+   bool compare(const u32regex_token_iterator_implementation& that)
+   {
+      if(this == &that) return true;
+      return (&re.get_data() == &that.re.get_data()) 
+         && (end == that.end) 
+         && (flags == that.flags) 
+         && (N == that.N) 
+         && (what[0].first == that.what[0].first) 
+         && (what[0].second == that.what[0].second);
+   }
+   const value_type& get()
+   { return result; }
+   bool next()
+   {
+      if(N == -1)
+         return false;
+      if(N+1 < (int)subs.size())
+      {
+         ++N;
+         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+         return true;
+      }
+      //if(what.prefix().first != what[0].second)
+      //   flags |= match_prev_avail | regex_constants::match_not_bob;
+      BidirectionalIterator last_end(what[0].second);
+      if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
+      {
+         N =0;
+         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+         return true;
+      }
+      else if((last_end != end) && (subs[0] == -1))
+      {
+         N =-1;
+         result.first = last_end;
+         result.second = end;
+         result.matched = (last_end != end);
+         return true;
+      }
+      return false;
+   }
+private:
+   u32regex_token_iterator_implementation& operator=(const u32regex_token_iterator_implementation&);
+};
+
+template <class BidirectionalIterator>
+class u32regex_token_iterator 
+#ifndef NDNBOOST_NO_STD_ITERATOR
+   : public std::iterator<
+         std::forward_iterator_tag, 
+         sub_match<BidirectionalIterator>,
+         typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+         const sub_match<BidirectionalIterator>*,
+         const sub_match<BidirectionalIterator>& >         
+#endif
+{
+private:
+   typedef u32regex_token_iterator_implementation<BidirectionalIterator> impl;
+   typedef shared_ptr<impl> pimpl;
+public:
+   typedef          u32regex                                                regex_type;
+   typedef          sub_match<BidirectionalIterator>                        value_type;
+   typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type 
+                                                                            difference_type;
+   typedef          const value_type*                                       pointer;
+   typedef          const value_type&                                       reference; 
+   typedef          std::forward_iterator_tag                               iterator_category;
+   
+   u32regex_token_iterator(){}
+   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, 
+                        int submatch = 0, match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatch, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, 
+                        const std::vector<int>& submatches, match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatches, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+      // can't reliably get this to work....
+#elif (NDNBOOST_WORKAROUND(__BORLANDC__, >= 0x560) && NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x570)))\
+      || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+      || NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3003)) \
+      || NDNBOOST_WORKAROUND(__HP_aCC, < 60700)
+   template <class T>
+   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+                        const T& submatches, match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatches, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+#else
+   template <std::size_t N>
+   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+                        const int (&submatches)[N], match_flag_type m = match_default)
+                        : pdata(new impl(&re, b, submatches, m))
+   {
+      if(!pdata->init(a))
+         pdata.reset();
+   }
+#endif
+   u32regex_token_iterator(const u32regex_token_iterator& that)
+      : pdata(that.pdata) {}
+   u32regex_token_iterator& operator=(const u32regex_token_iterator& that)
+   {
+      pdata = that.pdata;
+      return *this;
+   }
+   bool operator==(const u32regex_token_iterator& that)const
+   { 
+      if((pdata.get() == 0) || (that.pdata.get() == 0))
+         return pdata.get() == that.pdata.get();
+      return pdata->compare(*(that.pdata.get())); 
+   }
+   bool operator!=(const u32regex_token_iterator& that)const
+   { return !(*this == that); }
+   const value_type& operator*()const
+   { return pdata->get(); }
+   const value_type* operator->()const
+   { return &(pdata->get()); }
+   u32regex_token_iterator& operator++()
+   {
+      cow();
+      if(0 == pdata->next())
+      {
+         pdata.reset();
+      }
+      return *this;
+   }
+   u32regex_token_iterator operator++(int)
+   {
+      u32regex_token_iterator result(*this);
+      ++(*this);
+      return result;
+   }
+private:
+
+   pimpl pdata;
+
+   void cow()
+   {
+      // copy-on-write
+      if(pdata.get() && !pdata.unique())
+      {
+         pdata.reset(new impl(*(pdata.get())));
+      }
+   }
+};
+
+typedef u32regex_token_iterator<const char*> utf8regex_token_iterator;
+typedef u32regex_token_iterator<const UChar*> utf16regex_token_iterator;
+typedef u32regex_token_iterator<const UChar32*> utf32regex_token_iterator;
+
+// construction from an integral sub_match state_id:
+inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
+}
+#ifndef NDNBOOST_NO_WREGEX
+inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
+}
+#endif
+template <class charT, class Traits, class Alloc>
+inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);
+}
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
+}
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+// construction from a reference to an array:
+template <std::size_t N>
+inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
+}
+#ifndef NDNBOOST_NO_WREGEX
+template <std::size_t N>
+inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+template <std::size_t N>
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
+}
+#endif
+template <class charT, class Traits, class Alloc, std::size_t N>
+inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);
+}
+template <std::size_t N>
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
+}
+#endif // NDNBOOST_MSVC < 1300
+
+// construction from a vector of sub_match state_id's:
+inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
+}
+#ifndef NDNBOOST_NO_WREGEX
+inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
+}
+#endif
+template <class charT, class Traits, class Alloc>
+inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);
+}
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
+}
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, > 1300)
+#  pragma warning(pop)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+
+
+
+
diff --git a/include/ndnboost/regex/v4/w32_regex_traits.hpp b/include/ndnboost/regex/v4/w32_regex_traits.hpp
new file mode 100644
index 0000000..dafb189
--- /dev/null
+++ b/include/ndnboost/regex/v4/w32_regex_traits.hpp
@@ -0,0 +1,741 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+ 
+ /*
+  *   LOCATION:    see http://www.boost.org for most recent version.
+  *   FILE         w32_regex_traits.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression traits class w32_regex_traits.
+  */
+
+#ifndef NDNBOOST_W32_REGEX_TRAITS_HPP_INCLUDED
+#define NDNBOOST_W32_REGEX_TRAITS_HPP_INCLUDED
+
+#ifndef NDNBOOST_RE_PAT_EXCEPT_HPP
+#include <ndnboost/regex/pattern_except.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#include <ndnboost/regex/v4/regex_traits_defaults.hpp>
+#endif
+#ifdef NDNBOOST_HAS_THREADS
+#include <ndnboost/regex/pending/static_mutex.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_PRIMARY_TRANSFORM
+#include <ndnboost/regex/v4/primary_transform.hpp>
+#endif
+#ifndef NDNBOOST_REGEX_OBJECT_CACHE_HPP
+#include <ndnboost/regex/pending/object_cache.hpp>
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_PREFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4786)
+#pragma warning(disable:4800)
+#endif
+
+namespace ndnboost{ 
+
+//
+// forward declaration is needed by some compilers:
+//
+template <class charT>
+class w32_regex_traits;
+   
+namespace re_detail{
+
+//
+// start by typedeffing the types we'll need:
+//
+typedef ::ndnboost::uint32_t lcid_type;   // placeholder for LCID.
+typedef ::ndnboost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.
+
+//
+// then add wrappers around the actual Win32 API's (ie implementation hiding):
+//
+NDNBOOST_REGEX_DECL lcid_type NDNBOOST_REGEX_CALL w32_get_default_locale();
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is_lower(char, lcid_type);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type state_id);
+#endif
+#endif
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is_upper(char, lcid_type);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type state_id);
+#endif
+#endif
+NDNBOOST_REGEX_DECL cat_type NDNBOOST_REGEX_CALL w32_cat_open(const std::string& name);
+NDNBOOST_REGEX_DECL std::string NDNBOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL std::wstring NDNBOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL std::basic_string<unsigned short> NDNBOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::basic_string<unsigned short>& def);
+#endif
+#endif
+NDNBOOST_REGEX_DECL std::string NDNBOOST_REGEX_CALL w32_transform(lcid_type state_id, const char* p1, const char* p2);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL std::wstring NDNBOOST_REGEX_CALL w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL std::basic_string<unsigned short> NDNBOOST_REGEX_CALL w32_transform(lcid_type state_id, const unsigned short* p1, const unsigned short* p2);
+#endif
+#endif
+NDNBOOST_REGEX_DECL char NDNBOOST_REGEX_CALL w32_tolower(char c, lcid_type);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL wchar_t NDNBOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL unsigned short NDNBOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type state_id);
+#endif
+#endif
+NDNBOOST_REGEX_DECL char NDNBOOST_REGEX_CALL w32_toupper(char c, lcid_type);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL wchar_t NDNBOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);
+#endif
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is(lcid_type, ndnboost::uint32_t mask, char c);
+#ifndef NDNBOOST_NO_WREGEX
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is(lcid_type, ndnboost::uint32_t mask, wchar_t c);
+#ifdef NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+NDNBOOST_REGEX_DECL bool NDNBOOST_REGEX_CALL w32_is(lcid_type state_id, ndnboost::uint32_t m, unsigned short c);
+#endif
+#endif
+//
+// class w32_regex_traits_base:
+// acts as a container for locale and the facets we are using.
+//
+template <class charT>
+struct w32_regex_traits_base
+{
+   w32_regex_traits_base(lcid_type l)
+   { imbue(l); }
+   lcid_type imbue(lcid_type l);
+
+   lcid_type m_locale;
+};
+
+template <class charT>
+inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
+{
+   lcid_type result(m_locale);
+   m_locale = l;
+   return result;
+}
+
+//
+// class w32_regex_traits_char_layer:
+// implements methods that require specialisation for narrow characters:
+//
+template <class charT>
+class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
+{
+   typedef std::basic_string<charT> string_type;
+   typedef std::map<charT, regex_constants::syntax_type> map_type;
+   typedef typename map_type::const_iterator map_iterator_type;
+public:
+   w32_regex_traits_char_layer(const lcid_type l);
+
+   regex_constants::syntax_type syntax_type(charT c)const
+   {
+      map_iterator_type i = m_char_map.find(c);
+      return ((i == m_char_map.end()) ? 0 : i->second);
+   }
+   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+   {
+      map_iterator_type i = m_char_map.find(c);
+      if(i == m_char_map.end())
+      {
+         if(::ndnboost::re_detail::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
+         if(::ndnboost::re_detail::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
+         return 0;
+      }
+      return i->second;
+   }
+   charT tolower(charT c)const
+   {
+      return ::ndnboost::re_detail::w32_tolower(c, this->m_locale);
+   }
+   bool isctype(ndnboost::uint32_t mask, charT c)const
+   {
+      return ::ndnboost::re_detail::w32_is(this->m_locale, mask, c);
+   }
+
+private:
+   string_type get_default_message(regex_constants::syntax_type);
+   // TODO: use a hash table when available!
+   map_type m_char_map;
+};
+
+template <class charT>
+w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::ndnboost::re_detail::lcid_type l) 
+   : w32_regex_traits_base<charT>(l)
+{
+   // we need to start by initialising our syntax map so we know which
+   // character is used for which purpose:
+   cat_type cat;
+   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
+   if(cat_name.size())
+   {
+      cat = ::ndnboost::re_detail::w32_cat_open(cat_name);
+      if(!cat)
+      {
+         std::string m("Unable to open message catalog: ");
+         std::runtime_error err(m + cat_name);
+         ndnboost::re_detail::raise_runtime_error(err);
+      }
+   }
+   //
+   // if we have a valid catalog then load our messages:
+   //
+   if(cat)
+   {
+      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+      {
+         string_type mss = ::ndnboost::re_detail::w32_cat_get(cat, this->m_locale, i, get_default_message(i));
+         for(typename string_type::size_type j = 0; j < mss.size(); ++j)
+         {
+            this->m_char_map[mss[j]] = i;
+         }
+      }
+   }
+   else
+   {
+      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+      {
+         const char* ptr = get_default_syntax(i);
+         while(ptr && *ptr)
+         {
+            this->m_char_map[static_cast<charT>(*ptr)] = i;
+            ++ptr;
+         }
+      }
+   }
+}
+
+template <class charT>
+typename w32_regex_traits_char_layer<charT>::string_type 
+   w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
+{
+   const char* ptr = get_default_syntax(i);
+   string_type result;
+   while(ptr && *ptr)
+   {
+      result.append(1, static_cast<charT>(*ptr));
+      ++ptr;
+   }
+   return result;
+}
+
+//
+// specialised version for narrow characters:
+//
+template <>
+class NDNBOOST_REGEX_DECL w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
+{
+   typedef std::string string_type;
+public:
+   w32_regex_traits_char_layer(::ndnboost::re_detail::lcid_type l)
+   : w32_regex_traits_base<char>(l)
+   {
+      init();
+   }
+
+   regex_constants::syntax_type syntax_type(char c)const
+   {
+      return m_char_map[static_cast<unsigned char>(c)];
+   }
+   regex_constants::escape_syntax_type escape_syntax_type(char c) const
+   {
+      return m_char_map[static_cast<unsigned char>(c)];
+   }
+   char tolower(char c)const
+   {
+      return m_lower_map[static_cast<unsigned char>(c)];
+   }
+   bool isctype(ndnboost::uint32_t mask, char c)const
+   {
+      return m_type_map[static_cast<unsigned char>(c)] & mask;
+   }
+
+private:
+   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
+   char m_lower_map[1u << CHAR_BIT];
+   ndnboost::uint16_t m_type_map[1u << CHAR_BIT];
+   void init();
+};
+
+//
+// class w32_regex_traits_implementation:
+// provides pimpl implementation for w32_regex_traits.
+//
+template <class charT>
+class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
+{
+public:
+   typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 0x1000); // must be C1_DEFINED << 3
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 0x2000); // must be C1_DEFINED << 4
+   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff);  // all the masks used by the CT_CTYPE1 group
+
+   typedef std::basic_string<charT> string_type;
+   typedef charT char_type;
+   w32_regex_traits_implementation(::ndnboost::re_detail::lcid_type l);
+   std::string error_string(regex_constants::error_type n) const
+   {
+      if(!m_error_strings.empty())
+      {
+         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
+         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
+      }
+      return get_default_error_string(n);
+   }
+   char_class_type lookup_classname(const charT* p1, const charT* p2) const
+   {
+      char_class_type result = lookup_classname_imp(p1, p2);
+      if(result == 0)
+      {
+         typedef typename string_type::size_type size_type;
+         string_type temp(p1, p2);
+         for(size_type i = 0; i < temp.size(); ++i)
+            temp[i] = this->tolower(temp[i]);
+         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
+      }
+      return result;
+   }
+   string_type lookup_collatename(const charT* p1, const charT* p2) const;
+   string_type transform_primary(const charT* p1, const charT* p2) const;
+   string_type transform(const charT* p1, const charT* p2) const
+   {
+      return ::ndnboost::re_detail::w32_transform(this->m_locale, p1, p2);
+   }
+private:
+   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID
+   std::map<string_type, char_class_type>  m_custom_class_names; // character class names
+   std::map<string_type, string_type>      m_custom_collate_names; // collating element names
+   unsigned                       m_collate_type;    // the form of the collation string
+   charT                          m_collate_delim;   // the collation group delimiter
+   //
+   // helpers:
+   //
+   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
+};
+
+template <class charT>
+typename w32_regex_traits_implementation<charT>::string_type 
+   w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
+{
+   string_type result;
+   //
+   // What we do here depends upon the format of the sort key returned by
+   // sort key returned by this->transform:
+   //
+   switch(m_collate_type)
+   {
+   case sort_C:
+   case sort_unknown:
+      // the best we can do is translate to lower case, then get a regular sort key:
+      {
+         result.assign(p1, p2);
+         typedef typename string_type::size_type size_type;
+         for(size_type i = 0; i < result.size(); ++i)
+            result[i] = this->tolower(result[i]);
+         result = this->transform(&*result.begin(), &*result.begin() + result.size());
+         break;
+      }
+   case sort_fixed:
+      {
+         // get a regular sort key, and then truncate it:
+         result.assign(this->transform(p1, p2));
+         result.erase(this->m_collate_delim);
+         break;
+      }
+   case sort_delim:
+         // get a regular sort key, and then truncate everything after the delim:
+         result.assign(this->transform(p1, p2));
+         std::size_t i;
+         for(i = 0; i < result.size(); ++i)
+         {
+            if(result[i] == m_collate_delim)
+               break;
+         }
+         result.erase(i);
+         break;
+   }
+   if(result.empty())
+      result = string_type(1, charT(0));
+   return result;
+}
+
+template <class charT>
+typename w32_regex_traits_implementation<charT>::string_type 
+   w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
+{
+   typedef typename std::map<string_type, string_type>::const_iterator iter_type;
+   if(m_custom_collate_names.size())
+   {
+      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
+      if(pos != m_custom_collate_names.end())
+         return pos->second;
+   }
+#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)\
+               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+   std::string name(p1, p2);
+#else
+   std::string name;
+   const charT* p0 = p1;
+   while(p0 != p2)
+      name.append(1, char(*p0++));
+#endif
+   name = lookup_default_collate_name(name);
+#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)\
+               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+   if(name.size())
+      return string_type(name.begin(), name.end());
+#else
+   if(name.size())
+   {
+      string_type result;
+      typedef std::string::const_iterator iter;
+      iter b = name.begin();
+      iter e = name.end();
+      while(b != e)
+         result.append(1, charT(*b++));
+      return result;
+   }
+#endif
+   if(p2 - p1 == 1)
+      return string_type(1, *p1);
+   return string_type();
+}
+
+template <class charT>
+w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::ndnboost::re_detail::lcid_type l)
+: w32_regex_traits_char_layer<charT>(l)
+{
+   cat_type cat;
+   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
+   if(cat_name.size())
+   {
+      cat = ::ndnboost::re_detail::w32_cat_open(cat_name);
+      if(!cat)
+      {
+         std::string m("Unable to open message catalog: ");
+         std::runtime_error err(m + cat_name);
+         ndnboost::re_detail::raise_runtime_error(err);
+      }
+   }
+   //
+   // if we have a valid catalog then load our messages:
+   //
+   if(cat)
+   {
+      //
+      // Error messages:
+      //
+      for(ndnboost::regex_constants::error_type i = static_cast<ndnboost::regex_constants::error_type>(0); 
+         i <= ndnboost::regex_constants::error_unknown; 
+         i = static_cast<ndnboost::regex_constants::error_type>(i + 1))
+      {
+         const char* p = get_default_error_string(i);
+         string_type default_message;
+         while(*p)
+         {
+            default_message.append(1, static_cast<charT>(*p));
+            ++p;
+         }
+         string_type s = ::ndnboost::re_detail::w32_cat_get(cat, this->m_locale, i+200, default_message);
+         std::string result;
+         for(std::string::size_type j = 0; j < s.size(); ++j)
+         {
+            result.append(1, static_cast<char>(s[j]));
+         }
+         m_error_strings[i] = result;
+      }
+      //
+      // Custom class names:
+      //
+      static const char_class_type masks[14] = 
+      {
+         0x0104u, // C1_ALPHA | C1_DIGIT
+         0x0100u, // C1_ALPHA
+         0x0020u, // C1_CNTRL
+         0x0004u, // C1_DIGIT
+         (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE
+         0x0002u, // C1_LOWER
+         (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
+         0x0010u, // C1_PUNCT
+         0x0008u, // C1_SPACE
+         0x0001u, // C1_UPPER
+         0x0080u, // C1_XDIGIT
+         0x0040u, // C1_BLANK
+         w32_regex_traits_implementation<charT>::mask_word,
+         w32_regex_traits_implementation<charT>::mask_unicode,
+      };
+      static const string_type null_string;
+      for(unsigned int j = 0; j <= 13; ++j)
+      {
+         string_type s(::ndnboost::re_detail::w32_cat_get(cat, this->m_locale, j+300, null_string));
+         if(s.size())
+            this->m_custom_class_names[s] = masks[j];
+      }
+   }
+   //
+   // get the collation format used by m_pcollate:
+   //
+   m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
+}
+
+template <class charT>
+typename w32_regex_traits_implementation<charT>::char_class_type 
+   w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
+{
+   static const char_class_type masks[22] = 
+   {
+      0,
+      0x0104u, // C1_ALPHA | C1_DIGIT
+      0x0100u, // C1_ALPHA
+      0x0040u, // C1_BLANK
+      0x0020u, // C1_CNTRL
+      0x0004u, // C1_DIGIT
+      0x0004u, // C1_DIGIT
+      (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK
+      w32_regex_traits_implementation<charT>::mask_horizontal, 
+      0x0002u, // C1_LOWER
+      0x0002u, // C1_LOWER
+      (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
+      0x0010u, // C1_PUNCT
+      0x0008u, // C1_SPACE
+      0x0008u, // C1_SPACE
+      0x0001u, // C1_UPPER
+      w32_regex_traits_implementation<charT>::mask_unicode,
+      0x0001u, // C1_UPPER
+      w32_regex_traits_implementation<charT>::mask_vertical, 
+      0x0104u | w32_regex_traits_implementation<charT>::mask_word, 
+      0x0104u | w32_regex_traits_implementation<charT>::mask_word, 
+      0x0080u, // C1_XDIGIT
+   };
+   if(m_custom_class_names.size())
+   {
+      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
+      map_iter pos = m_custom_class_names.find(string_type(p1, p2));
+      if(pos != m_custom_class_names.end())
+         return pos->second;
+   }
+   std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
+   if(state_id < sizeof(masks) / sizeof(masks[0]))
+      return masks[state_id];
+   return masks[0];
+}
+
+
+template <class charT>
+ndnboost::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::ndnboost::re_detail::lcid_type l NDNBOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
+{
+   // TODO: create a cache for previously constructed objects.
+   return ndnboost::object_cache< ::ndnboost::re_detail::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
+}
+
+} // re_detail
+
+template <class charT>
+class w32_regex_traits
+{
+public:
+   typedef charT                         char_type;
+   typedef std::size_t                   size_type;
+   typedef std::basic_string<char_type>  string_type;
+   typedef ::ndnboost::re_detail::lcid_type locale_type;
+   typedef ndnboost::uint_least32_t         char_class_type;
+
+   struct boost_extensions_tag{};
+
+   w32_regex_traits()
+      : m_pimpl(re_detail::create_w32_regex_traits<charT>(::ndnboost::re_detail::w32_get_default_locale()))
+   { }
+   static size_type length(const char_type* p)
+   {
+      return std::char_traits<charT>::length(p);
+   }
+   regex_constants::syntax_type syntax_type(charT c)const
+   {
+      return m_pimpl->syntax_type(c);
+   }
+   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+   {
+      return m_pimpl->escape_syntax_type(c);
+   }
+   charT translate(charT c) const
+   {
+      return c;
+   }
+   charT translate_nocase(charT c) const
+   {
+      return this->m_pimpl->tolower(c);
+   }
+   charT translate(charT c, bool icase) const
+   {
+      return icase ? this->m_pimpl->tolower(c) : c;
+   }
+   charT tolower(charT c) const
+   {
+      return this->m_pimpl->tolower(c);
+   }
+   charT toupper(charT c) const
+   {
+      return ::ndnboost::re_detail::w32_toupper(c, this->m_pimpl->m_locale);
+   }
+   string_type transform(const charT* p1, const charT* p2) const
+   {
+      return ::ndnboost::re_detail::w32_transform(this->m_pimpl->m_locale, p1, p2);
+   }
+   string_type transform_primary(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->transform_primary(p1, p2);
+   }
+   char_class_type lookup_classname(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->lookup_classname(p1, p2);
+   }
+   string_type lookup_collatename(const charT* p1, const charT* p2) const
+   {
+      return m_pimpl->lookup_collatename(p1, p2);
+   }
+   bool isctype(charT c, char_class_type f) const
+   {
+      if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base) 
+         && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
+         return true;
+      else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
+         return true;
+      else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
+         return true;
+      else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_vertical)
+         && (::ndnboost::re_detail::is_separator(c) || (c == '\v')))
+         return true;
+      else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_horizontal) 
+         && this->isctype(c, 0x0008u) && !this->isctype(c, re_detail::w32_regex_traits_implementation<charT>::mask_vertical))
+         return true;
+      return false;
+   }
+   int toi(const charT*& p1, const charT* p2, int radix)const
+   {
+      return ::ndnboost::re_detail::global_toi(p1, p2, radix, *this);
+   }
+   int value(charT c, int radix)const
+   {
+      int result = ::ndnboost::re_detail::global_value(c);
+      return result < radix ? result : -1;
+   }
+   locale_type imbue(locale_type l)
+   {
+      ::ndnboost::re_detail::lcid_type result(getloc());
+      m_pimpl = re_detail::create_w32_regex_traits<charT>(l);
+      return result;
+   }
+   locale_type getloc()const
+   {
+      return m_pimpl->m_locale;
+   }
+   std::string error_string(regex_constants::error_type n) const
+   {
+      return m_pimpl->error_string(n);
+   }
+
+   //
+   // extension:
+   // set the name of the message catalog in use (defaults to "boost_regex").
+   //
+   static std::string catalog_name(const std::string& name);
+   static std::string get_catalog_name();
+
+private:
+   ndnboost::shared_ptr<const re_detail::w32_regex_traits_implementation<charT> > m_pimpl;
+   //
+   // catalog name handler:
+   //
+   static std::string& get_catalog_name_inst();
+
+#ifdef NDNBOOST_HAS_THREADS
+   static static_mutex& get_mutex_inst();
+#endif
+};
+
+template <class charT>
+std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
+{
+#ifdef NDNBOOST_HAS_THREADS
+   static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+   std::string result(get_catalog_name_inst());
+   get_catalog_name_inst() = name;
+   return result;
+}
+
+template <class charT>
+std::string& w32_regex_traits<charT>::get_catalog_name_inst()
+{
+   static std::string s_name;
+   return s_name;
+}
+
+template <class charT>
+std::string w32_regex_traits<charT>::get_catalog_name()
+{
+#ifdef NDNBOOST_HAS_THREADS
+   static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+   std::string result(get_catalog_name_inst());
+   return result;
+}
+
+#ifdef NDNBOOST_HAS_THREADS
+template <class charT>
+static_mutex& w32_regex_traits<charT>::get_mutex_inst()
+{
+   static static_mutex s_mutex = NDNBOOST_STATIC_MUTEX_INIT;
+   return s_mutex;
+}
+#endif
+
+
+} // boost
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef NDNBOOST_HAS_ABI_HEADERS
+#  include NDNBOOST_ABI_SUFFIX
+#endif
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
