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
+
+
