ndnboost: Include boost::iostreams for internal use.
diff --git a/include/ndn-cpp/common.hpp b/include/ndn-cpp/common.hpp
index 1df861b..1af6cf2 100644
--- a/include/ndn-cpp/common.hpp
+++ b/include/ndn-cpp/common.hpp
@@ -22,25 +22,27 @@
 #include <boost/make_shared.hpp>
 namespace ndn { namespace ptr_lib = boost; }
 #else
-// Use the boost header files in this distribution that were extracted with:
-// cd <BOOST DEVELOPMENT DIRECTORY WITH boost SUBDIRECTORY>
-// dist/bin/bcp --namespace=ndnboost shared_ptr make_shared weak_ptr function bind any <NDN-CPP ROOT>/include
-// cd <NDN-CPP ROOT>/include
-// mv boost ndnboost
-// cd ndnboost
-// # Replace when including files.
-// (unset LANG; find . -type f -exec sed -i '' 's/\<boost\//\<ndnboost\//g' {} +)
-// (unset LANG; find . -type f -exec sed -i '' 's/\"boost\//\"ndnboost\//g' {} +)
-// (unset LANG; find . -type f -exec sed -i '' 's/ boost\// ndnboost\//g' {} +)
-// (unset LANG; find . -type f -exec sed -i '' 's/(boost\//(ndnboost\//g' {} +)
-// # Replace macro definitions.
-// (unset LANG; find . -type f -exec sed -i '' 's/BOOST_/NDNBOOST_/g' {} +)
-// # Replace header include guards which don't start with BOOST_ .  This may result in some with NDNBOOST twice, but that is OK.
-// (unset LANG; find . -type f -exec sed -i '' 's/_DWA/_NDNBOOST_DWA/g' {} +)
-// (unset LANG; find . -type f -exec sed -i '' 's/ UUID_/ NDNBOOST_UUID_/g' {} +)
-// (unset LANG; find . -type f -exec sed -i '' 's/ FILE_boost/ FILE_ndnboost/g' {} +)
-// # Replace the mpl_ barrier namespace.  This should only change file adl_barrier.hpp.
-// (unset LANG; find . -type f -exec sed -i '' 's/ mpl_/ ndnboost_mpl_/g' {} +)
+/* Use the boost header files in this distribution that were extracted with:
+cd <BOOST DEVELOPMENT DIRECTORY WITH boost SUBDIRECTORY>
+dist/bin/bcp --namespace=ndnboost shared_ptr make_shared weak_ptr function bind any iostreams <NDN-CPP ROOT>/include
+cd <NDN-CPP ROOT>/include
+rm -rf boost.css boost.png Jamroot libs
+mv boost ndnboost
+cd ndnboost
+# Replace when including files.
+(unset LANG; find . -type f -exec sed -i '' 's/\<boost\//\<ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/\"boost\//\"ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ boost\// ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/(boost\//(ndnboost\//g' {} +)
+# Replace macro definitions.
+(unset LANG; find . -type f -exec sed -i '' 's/BOOST_/NDNBOOST_/g' {} +)
+# Replace header include guards which don't start with BOOST_ .  This may result in some with NDNBOOST twice, but that is OK.
+(unset LANG; find . -type f -exec sed -i '' 's/_DWA/_NDNBOOST_DWA/g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ UUID_/ NDNBOOST_UUID_/g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ FILE_boost/ FILE_ndnboost/g' {} +)
+# Replace the mpl_ barrier namespace.  This should only change file adl_barrier.hpp.
+(unset LANG; find . -type f -exec sed -i '' 's/ mpl_/ ndnboost_mpl_/g' {} +)
+ */
 #include <ndnboost/shared_ptr.hpp>
 #include <ndnboost/make_shared.hpp>
 namespace ndn { namespace ptr_lib = ndnboost; }
diff --git a/include/ndnboost/cerrno.hpp b/include/ndnboost/cerrno.hpp
new file mode 100644
index 0000000..edb8363
--- /dev/null
+++ b/include/ndnboost/cerrno.hpp
@@ -0,0 +1,331 @@
+//  Boost cerrno.hpp header  -------------------------------------------------//
+
+//  Copyright Beman Dawes 2005.
+//  Use, modification, and distribution is 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)
+
+//  See library home page at http://www.boost.org/libs/system
+
+#ifndef NDNBOOST_CERRNO_HPP
+#define NDNBOOST_CERRNO_HPP
+
+#include <cerrno>
+
+//  supply errno values likely to be missing, particularly on Windows
+
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT 9901
+#endif
+
+#ifndef EADDRINUSE
+#define EADDRINUSE 9902
+#endif
+
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL 9903
+#endif
+
+#ifndef EISCONN
+#define EISCONN 9904
+#endif
+
+#ifndef EBADMSG
+#define EBADMSG 9905
+#endif
+
+#ifndef ECONNABORTED
+#define ECONNABORTED 9906
+#endif
+
+#ifndef EALREADY
+#define EALREADY 9907
+#endif
+
+#ifndef ECONNREFUSED
+#define ECONNREFUSED 9908
+#endif
+
+#ifndef ECONNRESET
+#define ECONNRESET 9909
+#endif
+
+#ifndef EDESTADDRREQ
+#define EDESTADDRREQ 9910
+#endif
+
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH 9911
+#endif
+
+#ifndef EIDRM
+#define EIDRM 9912
+#endif
+
+#ifndef EMSGSIZE
+#define EMSGSIZE 9913
+#endif
+
+#ifndef ENETDOWN
+#define ENETDOWN 9914
+#endif
+
+#ifndef ENETRESET
+#define ENETRESET 9915
+#endif
+
+#ifndef ENETUNREACH
+#define ENETUNREACH 9916
+#endif
+
+#ifndef ENOBUFS
+#define ENOBUFS 9917
+#endif
+
+#ifndef ENOLINK
+#define ENOLINK 9918
+#endif
+
+#ifndef ENODATA
+#define ENODATA 9919
+#endif
+
+#ifndef ENOMSG
+#define ENOMSG 9920
+#endif
+
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT 9921
+#endif
+
+#ifndef ENOSR
+#define ENOSR 9922
+#endif
+
+#ifndef ENOTSOCK
+#define ENOTSOCK 9923
+#endif
+
+#ifndef ENOSTR
+#define ENOSTR 9924
+#endif
+
+#ifndef ENOTCONN
+#define ENOTCONN 9925
+#endif
+
+#ifndef ENOTSUP
+#define ENOTSUP 9926
+#endif
+
+#ifndef ECANCELED
+#define ECANCELED 9927
+#endif
+
+#ifndef EINPROGRESS
+#define EINPROGRESS 9928
+#endif
+
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 9929
+#endif
+
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK 9930
+#endif
+
+#ifndef EOWNERDEAD
+#define EOWNERDEAD  9931
+#endif
+
+#ifndef EPROTO
+#define EPROTO 9932
+#endif
+
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT 9933
+#endif
+
+#ifndef ENOTRECOVERABLE
+#define ENOTRECOVERABLE 9934
+#endif
+
+#ifndef ETIME
+#define ETIME 9935
+#endif
+
+#ifndef ETXTBSY
+#define ETXTBSY 9936
+#endif
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 9938
+#endif
+
+#ifndef ELOOP
+#define ELOOP 9939
+#endif
+
+#ifndef EOVERFLOW
+#define EOVERFLOW 9940
+#endif
+
+#ifndef EPROTOTYPE
+#define EPROTOTYPE 9941
+#endif
+
+#ifndef ENOSYS
+#define ENOSYS 9942
+#endif
+
+#ifndef EINVAL
+#define EINVAL 9943
+#endif
+
+#ifndef ERANGE
+#define ERANGE 9944
+#endif
+
+#ifndef EILSEQ
+#define EILSEQ 9945
+#endif
+
+//  Windows Mobile doesn't appear to define these:
+
+#ifndef E2BIG
+#define E2BIG 9946
+#endif
+
+#ifndef EDOM
+#define EDOM 9947
+#endif
+
+#ifndef EFAULT
+#define EFAULT 9948
+#endif
+
+#ifndef EBADF
+#define EBADF 9949
+#endif
+
+#ifndef EPIPE
+#define EPIPE 9950
+#endif
+
+#ifndef EXDEV
+#define EXDEV 9951
+#endif
+
+#ifndef EBUSY
+#define EBUSY 9952
+#endif
+
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 9953
+#endif
+
+#ifndef ENOEXEC
+#define ENOEXEC 9954
+#endif
+
+#ifndef EEXIST
+#define EEXIST 9955
+#endif
+
+#ifndef EFBIG
+#define EFBIG 9956
+#endif
+
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG 9957
+#endif
+
+#ifndef ENOTTY
+#define ENOTTY 9958
+#endif
+
+#ifndef EINTR
+#define EINTR 9959
+#endif
+
+#ifndef ESPIPE
+#define ESPIPE 9960
+#endif
+
+#ifndef EIO
+#define EIO 9961
+#endif
+
+#ifndef EISDIR
+#define EISDIR 9962
+#endif
+
+#ifndef ECHILD
+#define ECHILD 9963
+#endif
+
+#ifndef ENOLCK
+#define ENOLCK 9964
+#endif
+
+#ifndef ENOSPC
+#define ENOSPC 9965
+#endif
+
+#ifndef ENXIO
+#define ENXIO 9966
+#endif
+
+#ifndef ENODEV
+#define ENODEV 9967
+#endif
+
+#ifndef ENOENT
+#define ENOENT 9968
+#endif
+
+#ifndef ESRCH
+#define ESRCH 9969
+#endif
+
+#ifndef ENOTDIR
+#define ENOTDIR 9970
+#endif
+
+#ifndef ENOMEM
+#define ENOMEM 9971
+#endif
+
+#ifndef EPERM
+#define EPERM 9972
+#endif
+
+#ifndef EACCES
+#define EACCES 9973
+#endif
+
+#ifndef EROFS
+#define EROFS 9974
+#endif
+
+#ifndef EDEADLK
+#define EDEADLK 9975
+#endif
+
+#ifndef EAGAIN
+#define EAGAIN 9976
+#endif
+
+#ifndef ENFILE
+#define ENFILE 9977
+#endif
+
+#ifndef EMFILE
+#define EMFILE 9978
+#endif
+
+#ifndef EMLINK
+#define EMLINK 9979
+#endif
+
+#endif // include guard
diff --git a/include/ndnboost/cregex.hpp b/include/ndnboost/cregex.hpp
new file mode 100644
index 0000000..1384a2a
--- /dev/null
+++ b/include/ndnboost/cregex.hpp
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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/libs/regex 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
+#define NDNBOOST_RE_CREGEX_HPP
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+
+#include <ndnboost/regex/v4/cregex.hpp>
+
+#endif /* include guard */
+
+
+
+
+
+
+
+
+
+
diff --git a/include/ndnboost/detail/bitmask.hpp b/include/ndnboost/detail/bitmask.hpp
new file mode 100644
index 0000000..e5dce4a
--- /dev/null
+++ b/include/ndnboost/detail/bitmask.hpp
@@ -0,0 +1,47 @@
+//  ndnboost/detail/bitmask.hpp  ------------------------------------------------//
+
+//  Copyright Beman Dawes 2006
+
+//  Distributed under the Boost Software License, Version 1.0
+//  http://www.boost.org/LICENSE_1_0.txt
+
+//  Usage:  enum foo { a=1, b=2, c=4 };
+//          NDNBOOST_BITMASK( foo );
+//
+//          void f( foo arg );
+//          ...
+//          f( a | c );
+
+#ifndef NDNBOOST_BITMASK_HPP
+#define NDNBOOST_BITMASK_HPP
+
+#include <ndnboost/cstdint.hpp>
+
+#define NDNBOOST_BITMASK(Bitmask)                                            \
+                                                                          \
+  inline Bitmask operator| (Bitmask x , Bitmask y )                       \
+  { return static_cast<Bitmask>( static_cast<ndnboost::int_least32_t>(x)     \
+      | static_cast<ndnboost::int_least32_t>(y)); }                          \
+                                                                          \
+  inline Bitmask operator& (Bitmask x , Bitmask y )                       \
+  { return static_cast<Bitmask>( static_cast<ndnboost::int_least32_t>(x)     \
+      & static_cast<ndnboost::int_least32_t>(y)); }                          \
+                                                                          \
+  inline Bitmask operator^ (Bitmask x , Bitmask y )                       \
+  { return static_cast<Bitmask>( static_cast<ndnboost::int_least32_t>(x)     \
+      ^ static_cast<ndnboost::int_least32_t>(y)); }                          \
+                                                                          \
+  inline Bitmask operator~ (Bitmask x )                                   \
+  { return static_cast<Bitmask>(~static_cast<ndnboost::int_least32_t>(x)); } \
+                                                                          \
+  inline Bitmask & operator&=(Bitmask & x , Bitmask y)                    \
+  { x = x & y ; return x ; }                                              \
+                                                                          \
+  inline Bitmask & operator|=(Bitmask & x , Bitmask y)                    \
+  { x = x | y ; return x ; }                                              \
+                                                                          \
+  inline Bitmask & operator^=(Bitmask & x , Bitmask y)                    \
+  { x = x ^ y ; return x ; }                                              
+
+#endif // NDNBOOST_BITMASK_HPP
+
diff --git a/include/ndnboost/detail/scoped_enum_emulation.hpp b/include/ndnboost/detail/scoped_enum_emulation.hpp
new file mode 100644
index 0000000..cd2f599
--- /dev/null
+++ b/include/ndnboost/detail/scoped_enum_emulation.hpp
@@ -0,0 +1,337 @@
+//  scoped_enum_emulation.hpp  ---------------------------------------------------------//
+
+//  Copyright Beman Dawes, 2009
+//  Copyright (C) 2011-2012 Vicente J. Botet Escriba
+//  Copyright (C) 2012 Anthony Williams
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+[section:scoped_enums Scoped Enums]
+
+Generates C++0x scoped enums if the feature is present, otherwise emulates C++0x
+scoped enums with C++03 namespaces and enums. The Boost.Config NDNBOOST_NO_CXX11_SCOPED_ENUMS
+macro is used to detect feature support.
+
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf for a
+description of the scoped enum feature. Note that the committee changed the name
+from strongly typed enum to scoped enum.
+
+Some of the enumerations defined in the standard library are scoped enums.
+
+  enum class future_errc
+  {
+      broken_promise,
+      future_already_retrieved,
+      promise_already_satisfied,
+      no_state
+  };
+
+On compilers that don't support them, the library provides two emulations:
+
+[heading Strict]
+
+* Able to specify the underlying type.
+* explicit conversion to/from underlying type.
+* The wrapper is not a C++03 enum type.
+
+The user can declare  declare these types as
+
+  NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
+  {
+      broken_promise,
+      future_already_retrieved,
+      promise_already_satisfied,
+      no_state
+  }
+  NDNBOOST_SCOPED_ENUM_DECLARE_END(future_errc)
+
+These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
+
+  future_errc err = future_errc::no_state;
+
+There are however some limitations:
+
+* The type is not a C++ enum, so 'is_enum<future_errc>' will be false_type.
+* The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some macros.
+
+Instead of
+
+        switch (ev)
+        {
+        case future_errc::broken_promise:
+  // ...
+
+use
+
+        switch (ndnboost::native_value(ev))
+        {
+        case future_errc::broken_promise:
+
+And instead of
+
+    #ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+    template <>
+    struct NDNBOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
+    #endif
+
+use
+
+    #ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+    template <>
+    struct NDNBOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type > : public true_type { };
+    #endif
+
+
+Sample usage:
+
+     NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char) { green, red, cyan }; NDNBOOST_SCOPED_ENUM_DECLARE_END(algae)
+     ...
+     algae sample( algae::red );
+     void foo( algae color );
+     ...
+     sample = algae::green;
+     foo( algae::cyan );
+
+ Light
+  Caution: only the syntax is emulated; the semantics are not emulated and
+  the syntax emulation doesn't include being able to specify the underlying
+  representation type.
+
+  The literal scoped emulation is via struct rather than namespace to allow use within classes.
+  Thanks to Andrey Semashev for pointing that out.
+  However the type is an real C++03 enum and so convertible implicitly to an int.
+
+  Sample usage:
+
+     NDNBOOST_SCOPED_ENUM_START(algae) { green, red, cyan }; NDNBOOST_SCOPED_ENUM_END
+     ...
+     NDNBOOST_SCOPED_ENUM(algae) sample( algae::red );
+     void foo( NDNBOOST_SCOPED_ENUM(algae) color );
+     ...
+     sample = algae::green;
+     foo( algae::cyan );
+
+  Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott,
+  Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida, Matt Calabrese, Vicente
+  Botet, and Daniel James.
+
+[endsect]
+*/
+
+
+#ifndef NDNBOOST_SCOPED_ENUM_EMULATION_HPP
+#define NDNBOOST_SCOPED_ENUM_EMULATION_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+namespace ndnboost
+{
+
+#ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+  /**
+   * Meta-function to get the underlying type of a scoped enum.
+   *
+   * Requires EnumType must be an enum type or the emulation of a scoped enum
+   */
+  template <typename EnumType>
+  struct underlying_type
+  {
+    /**
+     * The member typedef type names the underlying type of EnumType. It is EnumType::underlying_type when the EnumType is an emulated scoped enum,
+     * std::underlying_type<EnumType>::type when the standard library std::underlying_type is provided.
+     *
+     * The user will need to specialize it when the compiler supports scoped enums but don't provides std::underlying_type.
+     */
+    typedef typename EnumType::underlying_type type;
+  };
+
+  /**
+   * Meta-function to get the native enum type associated to an enum class or its emulation.
+   */
+  template <typename EnumType>
+  struct native_type
+  {
+    /**
+     * The member typedef type names the native enum type associated to the scoped enum,
+     * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum.
+     */
+    typedef typename EnumType::enum_type type;
+  };
+
+  /**
+   * Casts a scoped enum to its underlying type.
+   *
+   * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type.
+   * @param v A scoped enum.
+   * @returns The underlying type.
+   * @throws No-throws.
+   */
+  template <typename UnderlyingType, typename EnumType>
+  UnderlyingType underlying_cast(EnumType v)
+  {
+    return v.get_underlying_value_();
+  }
+
+  /**
+   * Casts a scoped enum to its native enum type.
+   *
+   * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can.
+   *
+   * EnumType the scoped enum type
+   *
+   * @param v A scoped enum.
+   * @returns The native enum value.
+   * @throws No-throws.
+   */
+  template <typename EnumType>
+  inline
+  typename EnumType::enum_type native_value(EnumType e)
+  {
+    return e.native_value_();
+  }
+
+#else  // NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+  template <typename EnumType>
+  struct underlying_type
+  {
+    //typedef typename std::underlying_type<EnumType>::type type;
+  };
+
+  template <typename EnumType>
+  struct native_type
+  {
+    typedef EnumType type;
+  };
+
+  template <typename UnderlyingType, typename EnumType>
+  UnderlyingType underlying_cast(EnumType v)
+  {
+    return static_cast<UnderlyingType>(v);
+  }
+
+  template <typename EnumType>
+  inline
+  EnumType native_value(EnumType e)
+  {
+    return e;
+ }
+
+#endif
+}
+
+
+#ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+#ifndef NDNBOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
+     explicit operator underlying_type() const { return get_underlying_value_(); }
+
+#else
+
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR
+
+#endif
+
+/**
+ * Start a declaration of a scoped enum.
+ *
+ * @param EnumType The new scoped enum.
+ * @param UnderlyingType The underlying type.
+ */
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType)    \
+    struct EnumType {                                                   \
+        typedef UnderlyingType underlying_type;                         \
+        EnumType() NDNBOOST_NOEXCEPT {}                                    \
+        explicit EnumType(underlying_type v) : v_(v) {}                 \
+        underlying_type get_underlying_value_() const { return v_; }               \
+        NDNBOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR                \
+    private:                                                            \
+        underlying_type v_;                                             \
+        typedef EnumType self_type;                                     \
+    public:                                                             \
+        enum enum_type
+
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END2() \
+        enum_type get_native_value_() const NDNBOOST_NOEXCEPT { return enum_type(v_); } \
+        operator enum_type() const NDNBOOST_NOEXCEPT { return get_native_value_(); } \
+        friend bool operator ==(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \
+        friend bool operator ==(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \
+        friend bool operator ==(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \
+        friend bool operator !=(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \
+        friend bool operator !=(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \
+        friend bool operator !=(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \
+        friend bool operator <(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \
+        friend bool operator <(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \
+        friend bool operator <(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \
+        friend bool operator <=(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \
+        friend bool operator <=(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \
+        friend bool operator <=(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \
+        friend bool operator >(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \
+        friend bool operator >(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \
+        friend bool operator >(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \
+        friend bool operator >=(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \
+        friend bool operator >=(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \
+        friend bool operator >=(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \
+    };
+
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END(EnumType) \
+    ; \
+    EnumType(enum_type v) NDNBOOST_NOEXCEPT : v_(v) {}                 \
+    NDNBOOST_SCOPED_ENUM_DECLARE_END2()
+
+/**
+ * Starts a declaration of a scoped enum with the default int underlying type.
+ *
+ * @param EnumType The new scoped enum.
+ */
+#define NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \
+  NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int)
+
+/**
+ * Name of the native enum type.
+ *
+ * @param NT The new scoped enum.
+ */
+#define NDNBOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type
+/**
+ * Forward declares an scoped enum.
+ *
+ * @param NT The scoped enum.
+ */
+#define NDNBOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType
+
+#else  // NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType:UnderlyingType
+#define NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END2()
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END(EnumType) ;
+
+#define NDNBOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType
+#define NDNBOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType
+
+#endif  // NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+#define NDNBOOST_SCOPED_ENUM_START(name) NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(name)
+#define NDNBOOST_SCOPED_ENUM_END NDNBOOST_SCOPED_ENUM_DECLARE_END2()
+#define NDNBOOST_SCOPED_ENUM(name) NDNBOOST_SCOPED_ENUM_NATIVE(name)
+
+//#ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+//
+//# define NDNBOOST_SCOPED_ENUM_START(name) struct name { enum enum_type
+//# define NDNBOOST_SCOPED_ENUM_END };
+//# define NDNBOOST_SCOPED_ENUM(name) name::enum_type
+//
+//#else
+//
+//# define NDNBOOST_SCOPED_ENUM_START(name) enum class name
+//# define NDNBOOST_SCOPED_ENUM_END
+//# define NDNBOOST_SCOPED_ENUM(name) name
+//
+//#endif
+#endif  // NDNBOOST_SCOPED_ENUM_EMULATION_HPP
diff --git a/include/ndnboost/detail/utf8_codecvt_facet.hpp b/include/ndnboost/detail/utf8_codecvt_facet.hpp
new file mode 100644
index 0000000..37d9133
--- /dev/null
+++ b/include/ndnboost/detail/utf8_codecvt_facet.hpp
@@ -0,0 +1,190 @@
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NDNBOOST_UTF8_CODECVT_FACET_HPP
+#define NDNBOOST_UTF8_CODECVT_FACET_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// utf8_codecvt_facet.hpp
+
+// This header defines class utf8_codecvt_facet, derived fro 
+// std::codecvt<wchar_t, char>, which can be used to convert utf8 data in
+// files into wchar_t strings in the application.
+//
+// The header is NOT STANDALONE, and is not to be included by the USER.
+// There are at least two libraries which want to use this functionality, and
+// we want to avoid code duplication. It would be possible to create utf8
+// library, but:
+// - this requires review process first
+// - in the case, when linking the a library which uses utf8 
+//   (say 'program_options'), user should also link to the utf8 library.
+//   This seems inconvenient, and asking a user to link to an unrevieved 
+//   library is strange. 
+// Until the above points are fixed, a library which wants to use utf8 must:
+// - include this header from one of it's headers or sources
+// - include the corresponding .cpp file from one of the sources
+// - before including either file, the library must define
+//   - NDNBOOST_UTF8_BEGIN_NAMESPACE to the namespace declaration that must be used
+//   - NDNBOOST_UTF8_END_NAMESPACE to the code to close the previous namespace
+//   - declaration.
+//   - NDNBOOST_UTF8_DECL -- to the code which must be used for all 'exportable'
+//     symbols.
+//
+// For example, program_options library might contain:
+//    #define NDNBOOST_UTF8_BEGIN_NAMESPACE <backslash character> 
+//             namespace ndnboost { namespace program_options {
+//    #define NDNBOOST_UTF8_END_NAMESPACE }}
+//    #define NDNBOOST_UTF8_DECL NDNBOOST_PROGRAM_OPTIONS_DECL
+//    #include "../../detail/utf8/utf8_codecvt.cpp"
+//
+// Essentially, each library will have its own copy of utf8 code, in
+// different namespaces. 
+
+// Note:(Robert Ramey).  I have made the following alterations in the original
+// code.
+// a) Rendered utf8_codecvt<wchar_t, char>  with using templates
+// b) Move longer functions outside class definition to prevent inlining
+// and make code smaller
+// c) added on a derived class to permit translation to/from current
+// locale to utf8
+
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+// archives stored as text - note these ar templated on the basic
+// stream templates to accommodate wide (and other?) kind of characters
+//
+// note the fact that on libraries without wide characters, ostream is
+// is not a specialization of basic_ostream which in fact is not defined
+// in such cases.   So we can't use basic_ostream<OStream::char_type> but rather
+// use two template parameters
+//
+// utf8_codecvt_facet
+//   This is an implementation of a std::codecvt facet for translating 
+//   from UTF-8 externally to UCS-4.  Note that this is not tied to
+//   any specific types in order to allow customization on platforms
+//   where wchar_t is not big enough.
+//
+// NOTES:  The current implementation jumps through some unpleasant hoops in
+// order to deal with signed character types.  As a std::codecvt_base::result,
+// it is necessary  for the ExternType to be convertible to unsigned  char.
+// I chose not to tie the extern_type explicitly to char. But if any combination
+// of types other than <wchar_t,char_t> is used, then std::codecvt must be
+// specialized on those types for this to work.
+
+#include <locale>
+#include <cwchar>   // for mbstate_t
+#include <cstddef>  // for std::size_t
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+#if defined(NDNBOOST_NO_STDC_NAMESPACE)
+namespace std {
+    using ::mbstate_t;
+    using ::size_t;
+}
+#endif
+
+#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__)
+    #define NDNBOOST_CODECVT_DO_LENGTH_CONST const
+#else
+    #define NDNBOOST_CODECVT_DO_LENGTH_CONST
+#endif
+
+// maximum lenght of a multibyte string
+#define MB_LENGTH_MAX 8
+
+NDNBOOST_UTF8_BEGIN_NAMESPACE
+
+struct NDNBOOST_UTF8_DECL utf8_codecvt_facet :
+    public std::codecvt<wchar_t, char, std::mbstate_t>  
+{
+public:
+    explicit utf8_codecvt_facet(std::size_t no_locale_manage=0)
+        : std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage) 
+    {}
+protected:
+    virtual std::codecvt_base::result do_in(
+        std::mbstate_t& state, 
+        const char * from,
+        const char * from_end, 
+        const char * & from_next,
+        wchar_t * to, 
+        wchar_t * to_end, 
+        wchar_t*& to_next
+    ) const;
+
+    virtual std::codecvt_base::result do_out(
+        std::mbstate_t & state, const wchar_t * from,
+        const wchar_t * from_end, const wchar_t*  & from_next,
+        char * to, char * to_end, char * & to_next
+    ) const;
+
+    bool invalid_continuing_octet(unsigned char octet_1) const {
+        return (octet_1 < 0x80|| 0xbf< octet_1);
+    }
+
+    bool invalid_leading_octet(unsigned char octet_1)   const {
+        return (0x7f < octet_1 && octet_1 < 0xc0) ||
+            (octet_1 > 0xfd);
+    }
+
+    // continuing octets = octets except for the leading octet
+    static unsigned int get_cont_octet_count(unsigned   char lead_octet) {
+        return get_octet_count(lead_octet) - 1;
+    }
+
+    static unsigned int get_octet_count(unsigned char   lead_octet);
+
+    // How many "continuing octets" will be needed for this word
+    // ==   total octets - 1.
+    int get_cont_octet_out_count(wchar_t word) const ;
+
+    virtual bool do_always_noconv() const throw() { return false; }
+
+    // UTF-8 isn't really stateful since we rewind on partial conversions
+    virtual std::codecvt_base::result do_unshift(
+        std::mbstate_t&,
+        char * from,
+        char * /*to*/,
+        char * & next
+    ) const 
+    {
+        next = from;
+        return ok;
+    }
+
+    virtual int do_encoding() const throw() {
+        const int variable_byte_external_encoding=0;
+        return variable_byte_external_encoding;
+    }
+
+    // How many char objects can I process to get <= max_limit
+    // wchar_t objects?
+    virtual int do_length(
+        NDNBOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
+        const char * from,
+        const char * from_end, 
+        std::size_t max_limit
+#if NDNBOOST_WORKAROUND(__IBMCPP__, NDNBOOST_TESTED_AT(600))
+        ) const throw();
+#else
+        ) const;
+#endif
+
+    // Largest possible value do_length(state,from,from_end,1) could return.
+    virtual int do_max_length() const throw () {
+        return 6; // largest UTF-8 encoding of a UCS-4 character
+    }
+};
+
+NDNBOOST_UTF8_END_NAMESPACE
+
+#endif // NDNBOOST_UTF8_CODECVT_FACET_HPP
diff --git a/include/ndnboost/detail/utf8_codecvt_facet.ipp b/include/ndnboost/detail/utf8_codecvt_facet.ipp
new file mode 100644
index 0000000..00e893d
--- /dev/null
+++ b/include/ndnboost/detail/utf8_codecvt_facet.ipp
@@ -0,0 +1,285 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// utf8_codecvt_facet.ipp
+
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). 
+// Use, modification and distribution is 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)
+
+// Please see the comments in <ndnboost/detail/utf8_codecvt_facet.hpp> to
+// learn how this file should be used.
+
+#include <ndnboost/detail/utf8_codecvt_facet.hpp>
+
+#include <cstdlib> // for multi-byte converson routines
+#include <cassert>
+
+#include <ndnboost/limits.hpp>
+#include <ndnboost/config.hpp>
+
+// If we don't have wstring, then Unicode support 
+// is not available anyway, so we don't need to even
+// compiler this file. This also fixes the problem
+// with mingw, which can compile this file, but will
+// generate link error when building DLL.
+#ifndef NDNBOOST_NO_STD_WSTRING
+
+NDNBOOST_UTF8_BEGIN_NAMESPACE
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// implementation for wchar_t
+
+// Translate incoming UTF-8 into UCS-4
+std::codecvt_base::result utf8_codecvt_facet::do_in(
+    std::mbstate_t& /*state*/, 
+    const char * from,
+    const char * from_end, 
+    const char * & from_next,
+    wchar_t * to, 
+    wchar_t * to_end, 
+    wchar_t * & to_next
+) const {
+    // Basic algorithm:  The first octet determines how many
+    // octets total make up the UCS-4 character.  The remaining
+    // "continuing octets" all begin with "10". To convert, subtract
+    // the amount that specifies the number of octets from the first
+    // octet.  Subtract 0x80 (1000 0000) from each continuing octet,
+    // then mash the whole lot together.  Note that each continuing
+    // octet only uses 6 bits as unique values, so only shift by
+    // multiples of 6 to combine.
+    while (from != from_end && to != to_end) {
+
+        // Error checking   on the first octet
+        if (invalid_leading_octet(*from)){
+            from_next = from;
+            to_next = to;
+            return std::codecvt_base::error;
+        }
+
+        // The first octet is   adjusted by a value dependent upon 
+        // the number   of "continuing octets" encoding the character
+        const   int cont_octet_count = get_cont_octet_count(*from);
+        const   wchar_t octet1_modifier_table[] =   {
+            0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
+        };
+
+        // The unsigned char conversion is necessary in case char is
+        // signed   (I learned this the hard way)
+        wchar_t ucs_result = 
+            (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];
+
+        // Invariants   : 
+        //   1) At the start of the loop,   'i' continuing characters have been
+        //    processed 
+        //   2) *from   points to the next continuing character to be processed.
+        int i   = 0;
+        while(i != cont_octet_count && from != from_end) {
+
+            // Error checking on continuing characters
+            if (invalid_continuing_octet(*from)) {
+                from_next   = from;
+                to_next =   to;
+                return std::codecvt_base::error;
+            }
+
+            ucs_result *= (1 << 6); 
+
+            // each continuing character has an extra (10xxxxxx)b attached to 
+            // it that must be removed.
+            ucs_result += (unsigned char)(*from++) - 0x80;
+            ++i;
+        }
+
+        // If   the buffer ends with an incomplete unicode character...
+        if (from == from_end && i   != cont_octet_count) {
+            // rewind "from" to before the current character translation
+            from_next = from - (i+1); 
+            to_next = to;
+            return std::codecvt_base::partial;
+        }
+        *to++   = ucs_result;
+    }
+    from_next = from;
+    to_next = to;
+
+    // Were we done converting or did we run out of destination space?
+    if(from == from_end) return std::codecvt_base::ok;
+    else return std::codecvt_base::partial;
+}
+
+std::codecvt_base::result utf8_codecvt_facet::do_out(
+    std::mbstate_t& /*state*/, 
+    const wchar_t *   from,
+    const wchar_t * from_end, 
+    const wchar_t * & from_next,
+    char * to, 
+    char * to_end, 
+    char * & to_next
+) const
+{
+    // RG - consider merging this table with the other one
+    const wchar_t octet1_modifier_table[] = {
+        0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
+    };
+
+    wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)();
+    while (from != from_end && to != to_end) {
+
+        // Check for invalid UCS-4 character
+        if (*from  > max_wchar) {
+            from_next = from;
+            to_next = to;
+            return std::codecvt_base::error;
+        }
+
+        int cont_octet_count = get_cont_octet_out_count(*from);
+
+        // RG  - comment this formula better
+        int shift_exponent = (cont_octet_count) *   6;
+
+        // Process the first character
+        *to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] +
+            (unsigned char)(*from / (1 << shift_exponent)));
+
+        // Process the continuation characters 
+        // Invariants: At   the start of the loop:
+        //   1) 'i' continuing octets   have been generated
+        //   2) '*to'   points to the next location to place an octet
+        //   3) shift_exponent is   6 more than needed for the next octet
+        int i   = 0;
+        while   (i != cont_octet_count && to != to_end) {
+            shift_exponent -= 6;
+            *to++ = static_cast<char>(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6)));
+            ++i;
+        }
+        // If   we filled up the out buffer before encoding the character
+        if(to   == to_end && i != cont_octet_count) {
+            from_next = from;
+            to_next = to - (i+1);
+            return std::codecvt_base::partial;
+        }
+        ++from;
+    }
+    from_next = from;
+    to_next = to;
+    // Were we done or did we run out of destination space
+    if(from == from_end) return std::codecvt_base::ok;
+    else return std::codecvt_base::partial;
+}
+
+// How many char objects can I process to get <= max_limit
+// wchar_t objects?
+int utf8_codecvt_facet::do_length(
+    NDNBOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
+    const char * from,
+    const char * from_end, 
+    std::size_t max_limit
+#if NDNBOOST_WORKAROUND(__IBMCPP__, NDNBOOST_TESTED_AT(600))
+) const throw()
+#else
+) const
+#endif
+{ 
+    // RG - this code is confusing!  I need a better way to express it.
+    // and test cases.
+
+    // Invariants:
+    // 1) last_octet_count has the size of the last measured character
+    // 2) char_count holds the number of characters shown to fit
+    // within the bounds so far (no greater than max_limit)
+    // 3) from_next points to the octet 'last_octet_count' before the
+    // last measured character.  
+    int last_octet_count=0;
+    std::size_t char_count = 0;
+    const char* from_next = from;
+    // Use "<" because the buffer may represent incomplete characters
+    while (from_next+last_octet_count <= from_end && char_count <= max_limit) {
+        from_next += last_octet_count;
+        last_octet_count = (get_octet_count(*from_next));
+        ++char_count;
+    }
+    return static_cast<int>(from_next-from_end);
+}
+
+unsigned int utf8_codecvt_facet::get_octet_count(
+    unsigned char   lead_octet
+){
+    // if the 0-bit (MSB) is 0, then 1 character
+    if (lead_octet <= 0x7f) return 1;
+
+    // Otherwise the count number of consecutive 1 bits starting at MSB
+//    assert(0xc0 <= lead_octet && lead_octet <= 0xfd);
+
+    if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2;
+    else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3;
+    else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4;
+    else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5;
+    else return 6;
+}
+NDNBOOST_UTF8_END_NAMESPACE
+
+namespace {
+template<std::size_t s>
+int get_cont_octet_out_count_impl(wchar_t word){
+    if (word < 0x80) {
+        return 0;
+    }
+    if (word < 0x800) {
+        return 1;
+    }
+    return 2;
+}
+
+template<>
+int get_cont_octet_out_count_impl<4>(wchar_t word){
+    if (word < 0x80) {
+        return 0;
+    }
+    if (word < 0x800) {
+        return 1;
+    }
+
+    // Note that the following code will generate warnings on some platforms
+    // where wchar_t is defined as UCS2.  The warnings are superfluous as the
+    // specialization is never instantitiated with such compilers, but this
+    // can cause problems if warnings are being treated as errors, so we guard
+    // against that.  Including <ndnboost/detail/utf8_codecvt_facet.hpp> as we do
+    // should be enough to get WCHAR_MAX defined.
+#if !defined(WCHAR_MAX)
+#   error WCHAR_MAX not defined!
+#endif
+    // cope with VC++ 7.1 or earlier having invalid WCHAR_MAX
+#if defined(_MSC_VER) && _MSC_VER <= 1310 // 7.1 or earlier
+    return 2;
+#elif WCHAR_MAX > 0x10000
+    
+   if (word < 0x10000) {
+        return 2;
+    }
+    if (word < 0x200000) {
+        return 3;
+    }
+    if (word < 0x4000000) {
+        return 4;
+    }
+    return 5;
+    
+#else
+    return 2;
+#endif
+}
+
+} // namespace anonymous
+
+NDNBOOST_UTF8_BEGIN_NAMESPACE
+// How many "continuing octets" will be needed for this word
+// ==   total octets - 1.
+int utf8_codecvt_facet::get_cont_octet_out_count(
+    wchar_t word
+) const {
+    return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
+}
+NDNBOOST_UTF8_END_NAMESPACE
+
+#endif
diff --git a/include/ndnboost/filesystem.hpp b/include/ndnboost/filesystem.hpp
new file mode 100644
index 0000000..b0f5509
--- /dev/null
+++ b/include/ndnboost/filesystem.hpp
@@ -0,0 +1,20 @@
+//  ndnboost/filesystem.hpp  --------------------------------------------------------------//
+
+//  Copyright Beman Dawes 2010
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------// 
+
+#ifndef NDNBOOST_FILESYSTEM_FILESYSTEM_HPP
+#define NDNBOOST_FILESYSTEM_FILESYSTEM_HPP
+
+#  include <ndnboost/filesystem/config.hpp>
+#  include <ndnboost/filesystem/path.hpp>
+#  include <ndnboost/filesystem/operations.hpp>
+#  include <ndnboost/filesystem/convenience.hpp>
+
+#endif  // NDNBOOST_FILESYSTEM_FILESYSTEM_HPP 
diff --git a/include/ndnboost/filesystem/config.hpp b/include/ndnboost/filesystem/config.hpp
new file mode 100644
index 0000000..f70bec2
--- /dev/null
+++ b/include/ndnboost/filesystem/config.hpp
@@ -0,0 +1,109 @@
+//  ndnboost/filesystem/v3/config.hpp  ----------------------------------------------------//
+
+//  Copyright Beman Dawes 2003
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------// 
+
+#ifndef NDNBOOST_FILESYSTEM3_CONFIG_HPP
+#define NDNBOOST_FILESYSTEM3_CONFIG_HPP
+
+# if defined(NDNBOOST_FILESYSTEM_VERSION) && NDNBOOST_FILESYSTEM_VERSION != 3
+#   error Compiling Filesystem version 3 file with NDNBOOST_FILESYSTEM_VERSION defined != 3
+# endif
+
+# if !defined(NDNBOOST_FILESYSTEM_VERSION)
+#   define NDNBOOST_FILESYSTEM_VERSION 3
+# endif
+
+#define NDNBOOST_FILESYSTEM_I18N  // aid users wishing to compile several versions
+
+// This header implements separate compilation features as described in
+// http://www.boost.org/more/separate_compilation.html
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/system/api_config.hpp>  // for NDNBOOST_POSIX_API or NDNBOOST_WINDOWS_API
+#include <ndnboost/detail/workaround.hpp> 
+
+//  NDNBOOST_FILESYSTEM_DEPRECATED needed for source compiles -----------------------------//
+
+# ifdef NDNBOOST_FILESYSTEM_SOURCE
+#   define NDNBOOST_FILESYSTEM_DEPRECATED
+# endif
+
+//  throw an exception  ----------------------------------------------------------------//
+//
+//  Exceptions were originally thrown via ndnboost::throw_exception().
+//  As throw_exception() became more complex, it caused user error reporting
+//  to be harder to interpret, since the exception reported became much more complex.
+//  The immediate fix was to throw directly, wrapped in a macro to make any later change
+//  easier.
+
+#define NDNBOOST_FILESYSTEM_THROW(EX) throw EX
+
+# if defined( NDNBOOST_NO_STD_WSTRING )
+#   error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
+# endif
+
+//  This header implements separate compilation features as described in
+//  http://www.boost.org/more/separate_compilation.html
+
+//  normalize macros  ------------------------------------------------------------------//
+
+#if !defined(NDNBOOST_FILESYSTEM_DYN_LINK) && !defined(NDNBOOST_FILESYSTEM_STATIC_LINK) \
+  && !defined(NDNBOOST_ALL_DYN_LINK) && !defined(NDNBOOST_ALL_STATIC_LINK)
+# define NDNBOOST_FILESYSTEM_STATIC_LINK
+#endif
+
+#if defined(NDNBOOST_ALL_DYN_LINK) && !defined(NDNBOOST_FILESYSTEM_DYN_LINK)
+# define NDNBOOST_FILESYSTEM_DYN_LINK 
+#elif defined(NDNBOOST_ALL_STATIC_LINK) && !defined(NDNBOOST_FILESYSTEM_STATIC_LINK)
+# define NDNBOOST_FILESYSTEM_STATIC_LINK 
+#endif
+
+#if defined(NDNBOOST_FILESYSTEM_DYN_LINK) && defined(NDNBOOST_FILESYSTEM_STATIC_LINK)
+# error Must not define both NDNBOOST_FILESYSTEM_DYN_LINK and NDNBOOST_FILESYSTEM_STATIC_LINK
+#endif
+
+#if defined(NDNBOOST_ALL_NO_LIB) && !defined(NDNBOOST_FILESYSTEM_NO_LIB)
+# define NDNBOOST_FILESYSTEM_NO_LIB 
+#endif
+
+//  enable dynamic linking  ------------------------------------------------------------//
+
+#if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_FILESYSTEM_DYN_LINK)
+# if defined(NDNBOOST_FILESYSTEM_SOURCE)
+#   define NDNBOOST_FILESYSTEM_DECL NDNBOOST_SYMBOL_EXPORT
+# else 
+#   define NDNBOOST_FILESYSTEM_DECL NDNBOOST_SYMBOL_IMPORT
+# endif
+#else
+# define NDNBOOST_FILESYSTEM_DECL
+#endif
+
+//  enable automatic library variant selection  ----------------------------------------// 
+
+#if !defined(NDNBOOST_FILESYSTEM_SOURCE) && !defined(NDNBOOST_ALL_NO_LIB) \
+  && !defined(NDNBOOST_FILESYSTEM_NO_LIB)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define NDNBOOST_LIB_NAME ndnboost_filesystem
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_FILESYSTEM_DYN_LINK)
+#  define NDNBOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <ndnboost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+
+#endif // NDNBOOST_FILESYSTEM3_CONFIG_HPP
diff --git a/include/ndnboost/filesystem/convenience.hpp b/include/ndnboost/filesystem/convenience.hpp
new file mode 100644
index 0000000..5e91750
--- /dev/null
+++ b/include/ndnboost/filesystem/convenience.hpp
@@ -0,0 +1,58 @@
+//  ndnboost/filesystem/convenience.hpp  ----------------------------------------//
+
+//  Copyright Beman Dawes, 2002-2005
+//  Copyright Vladimir Prus, 2002
+//  Use, modification, and distribution is 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)
+
+//  See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------// 
+
+#ifndef NDNBOOST_FILESYSTEM3_CONVENIENCE_HPP
+#define NDNBOOST_FILESYSTEM3_CONVENIENCE_HPP
+
+#include <ndnboost/config.hpp>
+
+# if defined( NDNBOOST_NO_STD_WSTRING )
+#   error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
+# endif
+
+#include <ndnboost/filesystem/operations.hpp>
+#include <ndnboost/system/error_code.hpp>
+
+#include <ndnboost/config/abi_prefix.hpp> // must be the last #include
+
+namespace ndnboost
+{
+  namespace filesystem
+  {
+
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+
+    inline std::string extension(const path & p)
+    {
+      return p.extension().string();
+    }
+
+    inline std::string basename(const path & p)
+    {
+      return p.stem().string();
+    }
+
+    inline path change_extension( const path & p, const path & new_extension )
+    { 
+      path new_p( p );
+      new_p.replace_extension( new_extension );
+      return new_p;
+    }
+
+# endif
+
+
+  } // namespace filesystem
+} // namespace ndnboost
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+#endif // NDNBOOST_FILESYSTEM3_CONVENIENCE_HPP
diff --git a/include/ndnboost/filesystem/detail/utf8_codecvt_facet.hpp b/include/ndnboost/filesystem/detail/utf8_codecvt_facet.hpp
new file mode 100644
index 0000000..5e8251c
--- /dev/null
+++ b/include/ndnboost/filesystem/detail/utf8_codecvt_facet.hpp
@@ -0,0 +1,24 @@
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NDNBOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
+#define NDNBOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
+
+#include <ndnboost/filesystem/config.hpp>
+
+#define NDNBOOST_UTF8_BEGIN_NAMESPACE \
+     namespace ndnboost { namespace filesystem { namespace detail {
+
+#define NDNBOOST_UTF8_END_NAMESPACE }}}
+#define NDNBOOST_UTF8_DECL NDNBOOST_FILESYSTEM_DECL
+
+#include <ndnboost/detail/utf8_codecvt_facet.hpp>
+
+#undef NDNBOOST_UTF8_BEGIN_NAMESPACE
+#undef NDNBOOST_UTF8_END_NAMESPACE
+#undef NDNBOOST_UTF8_DECL
+
+#endif
diff --git a/include/ndnboost/filesystem/operations.hpp b/include/ndnboost/filesystem/operations.hpp
new file mode 100644
index 0000000..b395e49
--- /dev/null
+++ b/include/ndnboost/filesystem/operations.hpp
@@ -0,0 +1,1096 @@
+//  ndnboost/filesystem/operations.hpp  ---------------------------------------------------//
+
+//  Copyright Beman Dawes 2002-2009
+//  Copyright Jan Langer 2002
+//  Copyright Dietmar Kuehl 2001                                        
+//  Copyright Vladimir Prus 2002
+   
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+#ifndef NDNBOOST_FILESYSTEM3_OPERATIONS_HPP
+#define NDNBOOST_FILESYSTEM3_OPERATIONS_HPP
+
+#include <ndnboost/config.hpp>
+
+# if defined( NDNBOOST_NO_STD_WSTRING )
+#   error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
+# endif
+
+#include <ndnboost/filesystem/config.hpp>
+#include <ndnboost/filesystem/path.hpp>
+
+#include <ndnboost/detail/scoped_enum_emulation.hpp>
+#include <ndnboost/detail/bitmask.hpp>
+#include <ndnboost/system/error_code.hpp>
+#include <ndnboost/system/system_error.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+#include <ndnboost/iterator.hpp>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/assert.hpp>
+
+#include <string>
+#include <utility> // for pair
+#include <ctime>
+#include <vector>
+#include <stack>
+
+#ifdef NDNBOOST_WINDOWS_API
+#  include <fstream>
+#endif
+
+#include <ndnboost/config/abi_prefix.hpp> // must be the last #include
+
+//--------------------------------------------------------------------------------------//
+
+namespace ndnboost
+{
+  namespace filesystem
+  {
+
+//--------------------------------------------------------------------------------------//
+//                                     file_type                                        //
+//--------------------------------------------------------------------------------------//
+
+  enum file_type
+  { 
+    status_error,
+#   ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+    status_unknown = status_error,
+#   endif
+    file_not_found,
+    regular_file,
+    directory_file,
+    // the following may not apply to some operating systems or file systems
+    symlink_file,
+    block_file,
+    character_file,
+    fifo_file,
+    socket_file,
+    reparse_file,  // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink
+    type_unknown,  // file does exist, but isn't one of the above types or
+                   // we don't have strong enough permission to find its type
+
+    _detail_directory_symlink  // internal use only; never exposed to users
+  };
+
+//--------------------------------------------------------------------------------------//
+//                                       perms                                          //
+//--------------------------------------------------------------------------------------//
+
+  enum perms
+  {
+    no_perms = 0,       // file_not_found is no_perms rather than perms_not_known
+
+    // POSIX equivalent macros given in comments.
+    // Values are from POSIX and are given in octal per the POSIX standard.
+
+    // permission bits
+    
+    owner_read = 0400,  // S_IRUSR, Read permission, owner
+    owner_write = 0200, // S_IWUSR, Write permission, owner
+    owner_exe = 0100,   // S_IXUSR, Execute/search permission, owner
+    owner_all = 0700,   // S_IRWXU, Read, write, execute/search by owner
+
+    group_read = 040,   // S_IRGRP, Read permission, group
+    group_write = 020,  // S_IWGRP, Write permission, group
+    group_exe = 010,    // S_IXGRP, Execute/search permission, group
+    group_all = 070,    // S_IRWXG, Read, write, execute/search by group
+
+    others_read = 04,   // S_IROTH, Read permission, others
+    others_write = 02,  // S_IWOTH, Write permission, others
+    others_exe = 01,    // S_IXOTH, Execute/search permission, others
+    others_all = 07,    // S_IRWXO, Read, write, execute/search by others
+
+    all_all = owner_all|group_all|others_all,  // 0777
+
+    // other POSIX bits
+
+    set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution
+    set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution
+    sticky_bit     = 01000, // S_ISVTX,
+                            // (POSIX XSI) On directories, restricted deletion flag 
+	                          // (V7) 'sticky bit': save swapped text even after use 
+                            // (SunOS) On non-directories: don't cache this file
+                            // (SVID-v4.2) On directories: restricted deletion flag
+                            // Also see http://en.wikipedia.org/wiki/Sticky_bit
+
+    perms_mask = all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit,  // 07777
+
+    perms_not_known = 0xFFFF, // present when directory_entry cache not loaded
+
+    // options for permissions() function
+
+    add_perms = 0x1000,     // adds the given permission bits to the current bits
+    remove_perms = 0x2000,  // removes the given permission bits from the current bits;
+                            // choose add_perms or remove_perms, not both; if neither add_perms
+                            // nor remove_perms is given, replace the current bits with
+                            // the given bits.
+
+    symlink_perms = 0x4000  // on POSIX, don't resolve symlinks; implied on Windows
+  };
+
+  NDNBOOST_BITMASK(perms)
+
+//--------------------------------------------------------------------------------------//
+//                                    file_status                                       //
+//--------------------------------------------------------------------------------------//
+
+  class NDNBOOST_FILESYSTEM_DECL file_status
+  {
+  public:
+             file_status()            : m_value(status_error), m_perms(perms_not_known) {}
+    explicit file_status(file_type v, perms prms = perms_not_known)
+                                      : m_value(v), m_perms(prms) {}
+
+    // observers
+    file_type  type() const                       { return m_value; }
+    perms      permissions() const                { return m_perms; } 
+
+    // modifiers
+    void       type(file_type v)                  { m_value = v; }
+    void       permissions(perms prms)            { m_perms = prms; }
+
+    bool operator==(const file_status& rhs) const { return type() == rhs.type() && 
+                                                    permissions() == rhs.permissions(); }
+    bool operator!=(const file_status& rhs) const { return !(*this == rhs); }
+
+  private:
+    file_type   m_value;
+    enum perms  m_perms;
+  };
+
+  inline bool type_present(file_status f) { return f.type() != status_error; }
+  inline bool permissions_present(file_status f)
+                                          {return f.permissions() != perms_not_known;}
+  inline bool status_known(file_status f) { return type_present(f) && permissions_present(f); }
+  inline bool exists(file_status f)       { return f.type() != status_error
+                                                && f.type() != file_not_found; }
+  inline bool is_regular_file(file_status f){ return f.type() == regular_file; }
+  inline bool is_directory(file_status f) { return f.type() == directory_file; }
+  inline bool is_symlink(file_status f)   { return f.type() == symlink_file; }
+  inline bool is_other(file_status f)     { return exists(f) && !is_regular_file(f)
+                                                && !is_directory(f) && !is_symlink(f); }
+
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+  inline bool is_regular(file_status f)   { return f.type() == regular_file; }
+# endif
+
+  struct space_info
+  {
+    // all values are byte counts
+    ndnboost::uintmax_t capacity;
+    ndnboost::uintmax_t free;      // <= capacity
+    ndnboost::uintmax_t available; // <= free
+  };
+
+  NDNBOOST_SCOPED_ENUM_START(copy_option)
+    {none, fail_if_exists = none, overwrite_if_exists};
+  NDNBOOST_SCOPED_ENUM_END
+
+//--------------------------------------------------------------------------------------//
+//                             implementation details                                   //
+//--------------------------------------------------------------------------------------//
+
+  namespace detail
+  {
+    NDNBOOST_FILESYSTEM_DECL
+    file_status status(const path&p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    file_status symlink_status(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    bool is_empty(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    path initial_path(system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    path canonical(const path& p, const path& base, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void copy(const path& from, const path& to, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void copy_directory(const path& from, const path& to, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void copy_file(const path& from, const path& to,
+                    NDNBOOST_SCOPED_ENUM(copy_option) option,  // See ticket #2925
+                    system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    bool create_directories(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    bool create_directory(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void create_directory_symlink(const path& to, const path& from,
+                                  system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void create_hard_link(const path& to, const path& from, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void create_symlink(const path& to, const path& from, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    path current_path(system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void current_path(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    bool equivalent(const path& p1, const path& p2, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    ndnboost::uintmax_t file_size(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    ndnboost::uintmax_t hard_link_count(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    std::time_t last_write_time(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void last_write_time(const path& p, const std::time_t new_time,
+                         system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void permissions(const path& p, perms prms, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    path read_symlink(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+      // For standardization, if the committee doesn't like "remove", consider "eliminate"
+    bool remove(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    ndnboost::uintmax_t remove_all(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void rename(const path& old_p, const path& new_p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    void resize_file(const path& p, uintmax_t size, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    space_info space(const path& p, system::error_code* ec=0); 
+    NDNBOOST_FILESYSTEM_DECL
+    path system_complete(const path& p, system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    path temp_directory_path(system::error_code* ec=0);
+    NDNBOOST_FILESYSTEM_DECL
+    path unique_path(const path& p, system::error_code* ec=0);
+  }  // namespace detail
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                             status query functions                                   //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+  inline
+  file_status status(const path& p)    {return detail::status(p);}
+  inline 
+  file_status status(const path& p, system::error_code& ec)
+                                       {return detail::status(p, &ec);}
+  inline 
+  file_status symlink_status(const path& p) {return detail::symlink_status(p);}
+  inline
+  file_status symlink_status(const path& p, system::error_code& ec)
+                                       {return detail::symlink_status(p, &ec);}
+  inline 
+  bool exists(const path& p)           {return exists(detail::status(p));}
+  inline 
+  bool exists(const path& p, system::error_code& ec)
+                                       {return exists(detail::status(p, &ec));}
+  inline 
+  bool is_directory(const path& p)     {return is_directory(detail::status(p));}
+  inline 
+  bool is_directory(const path& p, system::error_code& ec)
+                                       {return is_directory(detail::status(p, &ec));}
+  inline 
+  bool is_regular_file(const path& p)  {return is_regular_file(detail::status(p));}
+  inline 
+  bool is_regular_file(const path& p, system::error_code& ec)
+                                       {return is_regular_file(detail::status(p, &ec));}
+  inline 
+  bool is_other(const path& p)         {return is_other(detail::status(p));}
+  inline 
+  bool is_other(const path& p, system::error_code& ec)
+                                       {return is_other(detail::status(p, &ec));}
+  inline
+  bool is_symlink(const path& p)       {return is_symlink(detail::symlink_status(p));}
+  inline 
+  bool is_symlink(const path& p, system::error_code& ec)
+                                       {return is_symlink(detail::symlink_status(p, &ec));}
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+  inline
+  bool is_regular(const path& p)       {return is_regular(detail::status(p));}
+  inline
+  bool is_regular(const path& p, system::error_code& ec)
+                                       {return is_regular(detail::status(p, &ec));}
+# endif
+
+  inline
+  bool is_empty(const path& p)         {return detail::is_empty(p);}
+  inline
+  bool is_empty(const path& p, system::error_code& ec)
+                                       {return detail::is_empty(p, &ec);}
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                             operational functions                                    //
+//                  in alphabetical order, unless otherwise noted                       //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+ 
+  //  forward declarations
+  path current_path();  // fwd declaration
+  path initial_path();
+
+  NDNBOOST_FILESYSTEM_DECL
+  path absolute(const path& p, const path& base=current_path());
+  //  If base.is_absolute(), throws nothing. Thus no need for ec argument
+
+  inline
+  path canonical(const path& p, const path& base=current_path())
+                                       {return detail::canonical(p, base);}
+  inline
+  path canonical(const path& p, system::error_code& ec)
+                                       {return detail::canonical(p, current_path(), &ec);}
+  inline
+  path canonical(const path& p, const path& base, system::error_code& ec)
+                                       {return detail::canonical(p, base, &ec);}
+
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+  inline
+  path complete(const path& p)
+  {
+    return absolute(p, initial_path());
+  }
+
+  inline
+  path complete(const path& p, const path& base)
+  {
+    return absolute(p, base);
+  }
+# endif
+
+  inline
+  void copy(const path& from, const path& to) {detail::copy(from, to);}
+
+  inline
+  void copy(const path& from, const path& to, system::error_code& ec) 
+                                       {detail::copy(from, to, &ec);}
+  inline
+  void copy_directory(const path& from, const path& to)
+                                       {detail::copy_directory(from, to);}
+  inline
+  void copy_directory(const path& from, const path& to, system::error_code& ec)
+                                       {detail::copy_directory(from, to, &ec);}
+  inline
+  void copy_file(const path& from, const path& to,   // See ticket #2925
+                 NDNBOOST_SCOPED_ENUM(copy_option) option)
+                                       {detail::copy_file(from, to, option);}
+  inline
+  void copy_file(const path& from, const path& to)
+                                       {detail::copy_file(from, to, copy_option::fail_if_exists);}
+  inline
+  void copy_file(const path& from, const path& to,   // See ticket #2925
+                 NDNBOOST_SCOPED_ENUM(copy_option) option, system::error_code& ec)
+                                       {detail::copy_file(from, to, option, &ec);}
+  inline
+  void copy_file(const path& from, const path& to, system::error_code& ec)
+                                       {detail::copy_file(from, to, copy_option::fail_if_exists, &ec);}
+  inline
+  void copy_symlink(const path& existing_symlink, const path& new_symlink) {detail::copy_symlink(existing_symlink, new_symlink);}
+
+  inline
+  void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec)
+                                       {detail::copy_symlink(existing_symlink, new_symlink, &ec);}
+  inline
+  bool create_directories(const path& p) {return detail::create_directories(p);}
+
+  inline
+  bool create_directories(const path& p, system::error_code& ec)
+                                       {return detail::create_directories(p, &ec);}
+  inline
+  bool create_directory(const path& p) {return detail::create_directory(p);}
+
+  inline
+  bool create_directory(const path& p, system::error_code& ec)
+                                       {return detail::create_directory(p, &ec);}
+  inline
+  void create_directory_symlink(const path& to, const path& from)
+                                       {detail::create_directory_symlink(to, from);}
+  inline
+  void create_directory_symlink(const path& to, const path& from, system::error_code& ec)
+                                       {detail::create_directory_symlink(to, from, &ec);}
+  inline
+  void create_hard_link(const path& to, const path& new_hard_link) {detail::create_hard_link(to, new_hard_link);}
+
+  inline
+  void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec)
+                                       {detail::create_hard_link(to, new_hard_link, &ec);}
+  inline
+  void create_symlink(const path& to, const path& new_symlink) {detail::create_symlink(to, new_symlink);}
+
+  inline
+  void create_symlink(const path& to, const path& new_symlink, system::error_code& ec)
+                                       {detail::create_symlink(to, new_symlink, &ec);}
+  inline
+  path current_path()                  {return detail::current_path();}
+
+  inline
+  path current_path(system::error_code& ec) {return detail::current_path(&ec);}
+
+  inline
+  void current_path(const path& p)     {detail::current_path(p);}
+
+  inline
+  void current_path(const path& p, system::error_code& ec) {detail::current_path(p, &ec);}
+
+  inline
+  bool equivalent(const path& p1, const path& p2) {return detail::equivalent(p1, p2);}
+
+  inline
+  bool equivalent(const path& p1, const path& p2, system::error_code& ec)
+                                       {return detail::equivalent(p1, p2, &ec);}
+  inline
+  ndnboost::uintmax_t file_size(const path& p) {return detail::file_size(p);}
+
+  inline
+  ndnboost::uintmax_t file_size(const path& p, system::error_code& ec)
+                                       {return detail::file_size(p, &ec);}
+  inline
+  ndnboost::uintmax_t hard_link_count(const path& p) {return detail::hard_link_count(p);}
+
+  inline
+  ndnboost::uintmax_t hard_link_count(const path& p, system::error_code& ec)
+                                       {return detail::hard_link_count(p, &ec);}
+  inline
+  path initial_path()                  {return detail::initial_path();}
+
+  inline
+  path initial_path(system::error_code& ec) {return detail::initial_path(&ec);}
+
+  template <class Path>
+  path initial_path() {return initial_path();}
+  template <class Path>
+  path initial_path(system::error_code& ec) {return detail::initial_path(&ec);}
+
+  inline
+  std::time_t last_write_time(const path& p) {return detail::last_write_time(p);}
+
+  inline
+  std::time_t last_write_time(const path& p, system::error_code& ec)
+                                       {return detail::last_write_time(p, &ec);}
+  inline
+  void last_write_time(const path& p, const std::time_t new_time)
+                                       {detail::last_write_time(p, new_time);}
+  inline
+  void last_write_time(const path& p, const std::time_t new_time, system::error_code& ec)
+                                       {detail::last_write_time(p, new_time, &ec);}
+  inline
+  void permissions(const path& p, perms prms)
+                                       {detail::permissions(p, prms);}
+  inline
+  void permissions(const path& p, perms prms, system::error_code& ec)
+                                       {detail::permissions(p, prms, &ec);}
+
+  inline
+  path read_symlink(const path& p)     {return detail::read_symlink(p);}
+
+  inline
+  path read_symlink(const path& p, system::error_code& ec)
+                                       {return detail::read_symlink(p, &ec);}
+  inline
+    // For standardization, if the committee doesn't like "remove", consider "eliminate"
+  bool remove(const path& p)           {return detail::remove(p);}
+
+  inline
+  bool remove(const path& p, system::error_code& ec) {return detail::remove(p, &ec);}
+
+  inline
+  ndnboost::uintmax_t remove_all(const path& p) {return detail::remove_all(p);}
+    
+  inline
+  ndnboost::uintmax_t remove_all(const path& p, system::error_code& ec)
+                                       {return detail::remove_all(p, &ec);}
+  inline
+  void rename(const path& old_p, const path& new_p) {detail::rename(old_p, new_p);}
+
+  inline
+  void rename(const path& old_p, const path& new_p, system::error_code& ec)
+                                       {detail::rename(old_p, new_p, &ec);}
+  inline  // name suggested by Scott McMurray
+  void resize_file(const path& p, uintmax_t size) {detail::resize_file(p, size);}
+
+  inline
+  void resize_file(const path& p, uintmax_t size, system::error_code& ec)
+                                       {detail::resize_file(p, size, &ec);}
+  inline
+  space_info space(const path& p)      {return detail::space(p);} 
+
+  inline
+  space_info space(const path& p, system::error_code& ec) {return detail::space(p, &ec);} 
+
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+  inline bool symbolic_link_exists(const path& p)
+                                       { return is_symlink(symlink_status(p)); }
+# endif
+
+  inline
+  path system_complete(const path& p)  {return detail::system_complete(p);}
+
+  inline
+  path system_complete(const path& p, system::error_code& ec)
+                                       {return detail::system_complete(p, &ec);}
+  inline
+  path temp_directory_path()           {return detail::temp_directory_path();}
+
+  inline
+  path temp_directory_path(system::error_code& ec) 
+                                       {return detail::temp_directory_path(&ec);}
+  inline
+  path unique_path(const path& p="%%%%-%%%%-%%%%-%%%%")
+                                       { return detail::unique_path(p); }
+  inline
+  path unique_path(const path& p, system::error_code& ec)
+                                       { return detail::unique_path(p, &ec); }
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                                 directory_entry                                      //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+//  GCC has a problem with a member function named path within a namespace or 
+//  sub-namespace that also has a class named path. The workaround is to always
+//  fully qualify the name path when it refers to the class name.
+
+class NDNBOOST_FILESYSTEM_DECL directory_entry
+{
+public:
+
+  // compiler generated copy constructor, copy assignment, and destructor apply
+
+  directory_entry() {}
+  explicit directory_entry(const ndnboost::filesystem::path& p,
+    file_status st = file_status(), file_status symlink_st=file_status())
+    : m_path(p), m_status(st), m_symlink_status(symlink_st)
+    {}
+
+  void assign(const ndnboost::filesystem::path& p,
+    file_status st = file_status(), file_status symlink_st = file_status())
+    { m_path = p; m_status = st; m_symlink_status = symlink_st; }
+
+  void replace_filename(const ndnboost::filesystem::path& p,
+    file_status st = file_status(), file_status symlink_st = file_status())
+  {
+    m_path.remove_filename();
+    m_path /= p;
+    m_status = st;
+    m_symlink_status = symlink_st;
+  }
+
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+  void replace_leaf(const ndnboost::filesystem::path& p,
+    file_status st, file_status symlink_st)
+      { replace_filename(p, st, symlink_st); }
+# endif
+
+  const ndnboost::filesystem::path&  path() const               {return m_path;}
+  file_status   status() const                               {return m_get_status();}
+  file_status   status(system::error_code& ec) const         {return m_get_status(&ec);}
+  file_status   symlink_status() const                       {return m_get_symlink_status();}
+  file_status   symlink_status(system::error_code& ec) const {return m_get_symlink_status(&ec);}
+
+  bool operator==(const directory_entry& rhs) {return m_path == rhs.m_path;} 
+  bool operator!=(const directory_entry& rhs) {return m_path != rhs.m_path;} 
+  bool operator< (const directory_entry& rhs) {return m_path < rhs.m_path;} 
+  bool operator<=(const directory_entry& rhs) {return m_path <= rhs.m_path;} 
+  bool operator> (const directory_entry& rhs) {return m_path > rhs.m_path;} 
+  bool operator>=(const directory_entry& rhs) {return m_path >= rhs.m_path;} 
+
+private:
+  ndnboost::filesystem::path   m_path;
+  mutable file_status       m_status;           // stat()-like
+  mutable file_status       m_symlink_status;   // lstat()-like
+
+  file_status m_get_status(system::error_code* ec=0) const;
+  file_status m_get_symlink_status(system::error_code* ec=0) const;
+}; // directory_entry
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                            directory_iterator helpers                                //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+class directory_iterator;
+
+namespace detail
+{
+  NDNBOOST_FILESYSTEM_DECL
+    system::error_code dir_itr_close(// never throws()
+    void *& handle
+#   if     defined(NDNBOOST_POSIX_API)
+    , void *& buffer
+#   endif
+  ); 
+
+  struct dir_itr_imp
+  {
+    directory_entry  dir_entry;
+    void*            handle;
+
+#   ifdef NDNBOOST_POSIX_API
+    void*            buffer;  // see dir_itr_increment implementation
+#   endif
+
+    dir_itr_imp() : handle(0)
+#   ifdef NDNBOOST_POSIX_API
+      , buffer(0)
+#   endif
+    {}
+
+    ~dir_itr_imp() // never throws
+    {
+      dir_itr_close(handle
+#       if defined(NDNBOOST_POSIX_API)
+         , buffer
+#       endif
+    );
+    }
+  };
+
+  // see path::iterator: comment below
+  NDNBOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it,
+    const path& p, system::error_code* ec);
+  NDNBOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it,
+    system::error_code* ec);
+
+}  // namespace detail
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                                directory_iterator                                    //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+  class directory_iterator
+    : public ndnboost::iterator_facade< directory_iterator,
+                                     directory_entry,
+                                     ndnboost::single_pass_traversal_tag >
+  {
+  public:
+
+    directory_iterator(){}  // creates the "end" iterator
+
+    // iterator_facade derived classes don't seem to like implementations in
+    // separate translation unit dll's, so forward to detail functions
+    explicit directory_iterator(const path& p)
+        : m_imp(new detail::dir_itr_imp)
+          { detail::directory_iterator_construct(*this, p, 0); }
+
+    directory_iterator(const path& p, system::error_code& ec)
+        : m_imp(new detail::dir_itr_imp)
+          { detail::directory_iterator_construct(*this, p, &ec); }
+
+   ~directory_iterator() {} // never throws
+
+    directory_iterator& increment(system::error_code& ec)
+    { 
+      detail::directory_iterator_increment(*this, &ec);
+      return *this;
+    }
+
+  private:
+    friend struct detail::dir_itr_imp;
+    friend NDNBOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it,
+      const path& p, system::error_code* ec);
+    friend NDNBOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it,
+      system::error_code* ec);
+
+    // shared_ptr provides shallow-copy semantics required for InputIterators.
+    // m_imp.get()==0 indicates the end iterator.
+    ndnboost::shared_ptr< detail::dir_itr_imp >  m_imp;
+
+    friend class ndnboost::iterator_core_access;
+
+    ndnboost::iterator_facade<
+      directory_iterator,
+      directory_entry,
+      ndnboost::single_pass_traversal_tag >::reference dereference() const 
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(), "attempt to dereference end iterator");
+      return m_imp->dir_entry;
+    }
+
+    void increment() { detail::directory_iterator_increment(*this, 0); }
+
+    bool equal(const directory_iterator& rhs) const
+      { return m_imp == rhs.m_imp; }
+  };
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                      recursive_directory_iterator helpers                            //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+  NDNBOOST_SCOPED_ENUM_START(symlink_option)
+  {
+    none,
+    no_recurse = none,         // don't follow directory symlinks (default behavior)
+    recurse,                   // follow directory symlinks
+    _detail_no_push = recurse << 1  // internal use only
+  };
+  NDNBOOST_SCOPED_ENUM_END
+
+  NDNBOOST_BITMASK(NDNBOOST_SCOPED_ENUM(symlink_option))
+
+  namespace detail
+  {
+    struct recur_dir_itr_imp
+    {
+      typedef directory_iterator element_type;
+      std::stack< element_type, std::vector< element_type > > m_stack;
+      int  m_level;
+      NDNBOOST_SCOPED_ENUM(symlink_option) m_options;
+
+      recur_dir_itr_imp() : m_level(0), m_options(symlink_option::none) {}
+
+      void increment(system::error_code* ec);  // ec == 0 means throw on error
+
+      void pop();
+
+    };
+
+    //  Implementation is inline to avoid dynamic linking difficulties with m_stack:
+    //  Microsoft warning C4251, m_stack needs to have dll-interface to be used by
+    //  clients of struct 'ndnboost::filesystem::detail::recur_dir_itr_imp'
+
+    inline
+    void recur_dir_itr_imp::increment(system::error_code* ec)
+    // ec == 0 means throw on error
+    {
+      if ((m_options & symlink_option::_detail_no_push) == symlink_option::_detail_no_push)
+        m_options &= ~symlink_option::_detail_no_push;
+
+      else
+      {
+        // Logic for following predicate was contributed by Daniel Aarno to handle cyclic
+        // symlinks correctly and efficiently, fixing ticket #5652.
+        //   if (((m_options & symlink_option::recurse) == symlink_option::recurse
+        //         || !is_symlink(m_stack.top()->symlink_status()))
+        //       && is_directory(m_stack.top()->status())) ...
+        // The predicate code has since been rewritten to pass error_code arguments,
+        // per ticket #5653.
+        bool or_pred = (m_options & symlink_option::recurse) == symlink_option::recurse
+                       || (ec == 0 ? !is_symlink(m_stack.top()->symlink_status())
+                                   : !is_symlink(m_stack.top()->symlink_status(*ec)));
+        if (ec != 0 && *ec)
+          return;
+        bool and_pred = or_pred && (ec == 0 ? is_directory(m_stack.top()->status())
+                                            : is_directory(m_stack.top()->status(*ec)));
+        if (ec != 0 && *ec)
+          return;
+
+        if (and_pred)
+        {
+          if (ec == 0)
+            m_stack.push(directory_iterator(m_stack.top()->path()));
+          else
+          {
+            m_stack.push(directory_iterator(m_stack.top()->path(), *ec));
+            if (*ec)
+              return;
+          }
+          if (m_stack.top() != directory_iterator())
+          {
+            ++m_level;
+            return;
+          }
+          m_stack.pop();
+        }
+      }
+
+      while (!m_stack.empty() && ++m_stack.top() == directory_iterator())
+      {
+        m_stack.pop();
+        --m_level;
+      }
+    }
+
+    inline
+    void recur_dir_itr_imp::pop()
+    {
+      NDNBOOST_ASSERT_MSG(m_level > 0,
+        "pop() on recursive_directory_iterator with level < 1");
+
+      do
+      {
+        m_stack.pop();
+        --m_level;
+      }
+      while (!m_stack.empty() && ++m_stack.top() == directory_iterator());
+    }
+  } // namespace detail
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                           recursive_directory_iterator                               //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+  class recursive_directory_iterator
+    : public ndnboost::iterator_facade<
+        recursive_directory_iterator,
+        directory_entry,
+        ndnboost::single_pass_traversal_tag >
+  {
+  public:
+
+    recursive_directory_iterator(){}  // creates the "end" iterator
+
+    explicit recursive_directory_iterator(const path& dir_path,
+      NDNBOOST_SCOPED_ENUM(symlink_option) opt = symlink_option::none)
+      : m_imp(new detail::recur_dir_itr_imp)
+    {
+      m_imp->m_options = opt;
+      m_imp->m_stack.push(directory_iterator(dir_path));
+      if (m_imp->m_stack.top() == directory_iterator())
+        { m_imp.reset (); }
+    }
+
+    recursive_directory_iterator(const path& dir_path,
+      NDNBOOST_SCOPED_ENUM(symlink_option) opt,
+      system::error_code & ec)
+    : m_imp(new detail::recur_dir_itr_imp)
+    {
+      m_imp->m_options = opt;
+      m_imp->m_stack.push(directory_iterator(dir_path, ec));
+      if (m_imp->m_stack.top() == directory_iterator())
+        { m_imp.reset (); }
+    }
+
+    recursive_directory_iterator(const path& dir_path,
+      system::error_code & ec)
+    : m_imp(new detail::recur_dir_itr_imp)
+    {
+      m_imp->m_options = symlink_option::none;
+      m_imp->m_stack.push(directory_iterator(dir_path, ec));
+      if (m_imp->m_stack.top() == directory_iterator())
+        { m_imp.reset (); }
+    }
+
+    recursive_directory_iterator& increment(system::error_code& ec)
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "increment() on end recursive_directory_iterator");
+      m_imp->increment(&ec);
+      if (m_imp->m_stack.empty())
+        m_imp.reset(); // done, so make end iterator
+      return *this;
+    }
+
+    int level() const
+    { 
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "level() on end recursive_directory_iterator");
+      return m_imp->m_level;
+    }
+
+    bool no_push_pending() const
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "is_no_push_requested() on end recursive_directory_iterator");
+      return (m_imp->m_options & symlink_option::_detail_no_push)
+        == symlink_option::_detail_no_push;
+    }
+
+#   ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+    bool no_push_request() const { return no_push_pending(); }
+#   endif
+
+    void pop()
+    { 
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "pop() on end recursive_directory_iterator");
+      m_imp->pop();
+      if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator
+    }
+
+    void no_push(bool value=true)
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "no_push() on end recursive_directory_iterator");
+      if (value)
+        m_imp->m_options |= symlink_option::_detail_no_push;
+      else
+        m_imp->m_options &= ~symlink_option::_detail_no_push;
+    }
+
+    file_status status() const
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "status() on end recursive_directory_iterator");
+      return m_imp->m_stack.top()->status();
+    }
+
+    file_status symlink_status() const
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "symlink_status() on end recursive_directory_iterator");
+      return m_imp->m_stack.top()->symlink_status();
+    }
+
+  private:
+
+    // shared_ptr provides shallow-copy semantics required for InputIterators.
+    // m_imp.get()==0 indicates the end iterator.
+    ndnboost::shared_ptr< detail::recur_dir_itr_imp >  m_imp;
+
+    friend class ndnboost::iterator_core_access;
+
+    ndnboost::iterator_facade< 
+      recursive_directory_iterator,
+      directory_entry,
+      ndnboost::single_pass_traversal_tag >::reference
+    dereference() const 
+    {
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "dereference of end recursive_directory_iterator");
+      return *m_imp->m_stack.top();
+    }
+
+    void increment()
+    { 
+      NDNBOOST_ASSERT_MSG(m_imp.get(),
+        "increment of end recursive_directory_iterator");
+      m_imp->increment(0);
+      if (m_imp->m_stack.empty())
+        m_imp.reset(); // done, so make end iterator
+    }
+
+    bool equal(const recursive_directory_iterator& rhs) const
+      { return m_imp == rhs.m_imp; }
+
+  };
+
+# if !defined(NDNBOOST_FILESYSTEM_NO_DEPRECATED)
+  typedef recursive_directory_iterator wrecursive_directory_iterator;
+# endif
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                            class filesystem_error                                    //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+  
+  class NDNBOOST_SYMBOL_VISIBLE filesystem_error : public system::system_error
+  {
+  // see http://www.boost.org/more/error_handling.html for design rationale
+
+  // all functions are inline to avoid issues with crossing dll boundaries
+
+  public:
+    // compiler generates copy constructor and copy assignment
+
+    filesystem_error(
+      const std::string & what_arg, system::error_code ec)
+      : system::system_error(ec, what_arg)
+    {
+      try
+      {
+        m_imp_ptr.reset(new m_imp);
+      }
+      catch (...) { m_imp_ptr.reset(); }
+    }
+
+    filesystem_error(
+      const std::string & what_arg, const path& path1_arg,
+      system::error_code ec)
+      : system::system_error(ec, what_arg)
+    {
+      try
+      {
+        m_imp_ptr.reset(new m_imp);
+        m_imp_ptr->m_path1 = path1_arg;
+      }
+      catch (...) { m_imp_ptr.reset(); }
+    }
+    
+    filesystem_error(
+      const std::string & what_arg, const path& path1_arg,
+      const path& path2_arg, system::error_code ec)
+      : system::system_error(ec, what_arg)
+    {
+      try
+      {
+        m_imp_ptr.reset(new m_imp);
+        m_imp_ptr->m_path1 = path1_arg;
+        m_imp_ptr->m_path2 = path2_arg;
+      }
+      catch (...) { m_imp_ptr.reset(); }
+    }
+
+    ~filesystem_error() throw() {}
+
+    const path& path1() const
+    {
+      static const path empty_path;
+      return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ;
+    }
+    const path& path2() const
+    {
+      static const path empty_path;
+      return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ;
+    }
+
+    const char* what() const throw()
+    {
+      if (!m_imp_ptr.get())
+        return system::system_error::what();
+
+      try
+      {
+        if (m_imp_ptr->m_what.empty())
+        {
+          m_imp_ptr->m_what = system::system_error::what();
+          if (!m_imp_ptr->m_path1.empty())
+          {
+            m_imp_ptr->m_what += ": \"";
+            m_imp_ptr->m_what += m_imp_ptr->m_path1.string();
+            m_imp_ptr->m_what += "\"";
+          }
+          if (!m_imp_ptr->m_path2.empty())
+          {
+            m_imp_ptr->m_what += ", \"";
+            m_imp_ptr->m_what += m_imp_ptr->m_path2.string();
+            m_imp_ptr->m_what += "\"";
+          }
+        }
+        return m_imp_ptr->m_what.c_str();
+      }
+      catch (...)
+      {
+        return system::system_error::what();
+      }
+    }
+
+  private:
+    struct m_imp
+    {
+      path         m_path1; // may be empty()
+      path         m_path2; // may be empty()
+      std::string  m_what;  // not built until needed
+    };
+    ndnboost::shared_ptr<m_imp> m_imp_ptr;
+  };
+
+//  test helper  -----------------------------------------------------------------------//
+
+//  Not part of the documented interface since false positives are possible;
+//  there is no law that says that an OS that has large stat.st_size
+//  actually supports large file sizes.
+
+  namespace detail
+  {
+    NDNBOOST_FILESYSTEM_DECL bool possible_large_file_size_support();
+  }
+
+  } // namespace filesystem
+} // namespace ndnboost
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+#endif // NDNBOOST_FILESYSTEM3_OPERATIONS_HPP
diff --git a/include/ndnboost/filesystem/path.hpp b/include/ndnboost/filesystem/path.hpp
new file mode 100644
index 0000000..8dee66f
--- /dev/null
+++ b/include/ndnboost/filesystem/path.hpp
@@ -0,0 +1,758 @@
+//  filesystem path.hpp  ---------------------------------------------------------------//
+
+//  Copyright Beman Dawes 2002-2005, 2009
+//  Copyright Vladimir Prus 2002
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  Library home page: http://www.boost.org/libs/filesystem
+
+//  path::stem(), extension(), and replace_extension() are based on
+//  basename(), extension(), and change_extension() from the original
+//  filesystem/convenience.hpp header by Vladimir Prus.
+
+#ifndef NDNBOOST_FILESYSTEM_PATH_HPP
+#define NDNBOOST_FILESYSTEM_PATH_HPP
+
+#include <ndnboost/config.hpp>
+
+# if defined( NDNBOOST_NO_STD_WSTRING )
+#   error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
+# endif
+
+#include <ndnboost/filesystem/config.hpp>
+#include <ndnboost/filesystem/path_traits.hpp>  // includes <cwchar>
+#include <ndnboost/system/error_code.hpp>
+#include <ndnboost/system/system_error.hpp>
+#include <ndnboost/iterator/iterator_facade.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/io/detail/quoted_manip.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/functional/hash_fwd.hpp>
+#include <ndnboost/type_traits/is_integral.hpp>
+#include <string>
+#include <iterator>
+#include <cstring>
+#include <iosfwd>
+#include <stdexcept>
+#include <cassert>
+#include <locale>
+#include <algorithm>
+
+#include <ndnboost/config/abi_prefix.hpp> // must be the last #include
+
+namespace ndnboost
+{
+namespace filesystem
+{
+  //------------------------------------------------------------------------------------//
+  //                                                                                    //
+  //                                    class path                                      //
+  //                                                                                    //
+  //------------------------------------------------------------------------------------//
+
+  class NDNBOOST_FILESYSTEM_DECL path
+  {
+  public:
+
+    //  value_type is the character type used by the operating system API to
+    //  represent paths.
+
+# ifdef NDNBOOST_WINDOWS_API
+    typedef wchar_t                        value_type;
+    NDNBOOST_STATIC_CONSTEXPR value_type      preferred_separator = L'\\';
+# else 
+    typedef char                           value_type;
+    NDNBOOST_STATIC_CONSTEXPR value_type      preferred_separator = '/';
+# endif
+    typedef std::basic_string<value_type>  string_type;  
+    typedef std::codecvt<wchar_t, char,
+                         std::mbstate_t>   codecvt_type;
+
+
+    //  ----- character encoding conversions -----
+
+    //  Following the principle of least astonishment, path input arguments
+    //  passed to or obtained from the operating system via objects of
+    //  class path behave as if they were directly passed to or
+    //  obtained from the O/S API, unless conversion is explicitly requested.
+    //
+    //  POSIX specfies that path strings are passed unchanged to and from the
+    //  API. Note that this is different from the POSIX command line utilities,
+    //  which convert according to a locale.
+    //
+    //  Thus for POSIX, char strings do not undergo conversion.  wchar_t strings
+    //  are converted to/from char using the path locale or, if a conversion
+    //  argument is given, using a conversion object modeled on
+    //  std::wstring_convert.
+    //
+    //  The path locale, which is global to the thread, can be changed by the
+    //  imbue() function. It is initialized to an implementation defined locale.
+    //  
+    //  For Windows, wchar_t strings do not undergo conversion. char strings
+    //  are converted using the "ANSI" or "OEM" code pages, as determined by
+    //  the AreFileApisANSI() function, or, if a conversion argument is given,
+    //  using a conversion object modeled on std::wstring_convert.
+    //
+    //  See m_pathname comments for further important rationale.
+
+    //  TODO: rules needed for operating systems that use / or .
+    //  differently, or format directory paths differently from file paths. 
+    //
+    //  **********************************************************************************
+    //
+    //  More work needed: How to handle an operating system that may have
+    //  slash characters or dot characters in valid filenames, either because
+    //  it doesn't follow the POSIX standard, or because it allows MBCS
+    //  filename encodings that may contain slash or dot characters. For
+    //  example, ISO/IEC 2022 (JIS) encoding which allows switching to
+    //  JIS x0208-1983 encoding. A valid filename in this set of encodings is
+    //  0x1B 0x24 0x42 [switch to X0208-1983] 0x24 0x2F [U+304F Kiragana letter KU]
+    //                                             ^^^^
+    //  Note that 0x2F is the ASCII slash character
+    //
+    //  **********************************************************************************
+
+    //  Supported source arguments: half-open iterator range, container, c-array,
+    //  and single pointer to null terminated string.
+
+    //  All source arguments except pointers to null terminated byte strings support
+    //  multi-byte character strings which may have embedded nulls. Embedded null
+    //  support is required for some Asian languages on Windows.
+
+    //  [defaults] "const codecvt_type& cvt=codecvt()" default arguments are not used
+    //  because some compilers, such as Microsoft prior to VC++ 10, do not handle defaults
+    //  correctly in templates.
+
+    //  -----  constructors  -----
+
+    path(){}                                          
+
+    path(const path& p) : m_pathname(p.m_pathname) {}
+
+    template <class Source>
+    path(Source const& source,
+      typename ndnboost::enable_if<path_traits::is_pathable<
+        typename ndnboost::decay<Source>::type> >::type* =0)
+    {
+      path_traits::dispatch(source, m_pathname, codecvt());
+    }
+
+    //  Overloads for the operating system API's native character type. Rationale:
+    //    - Avoids use of codecvt() for native value_type strings. This limits the
+    //      impact of locale("") initialization failures on POSIX systems to programs
+    //      that actually depend on locale(""). It further ensures that exceptions thrown
+    //      as a result of such failues occur after main() has started, so can be caught.
+    //      This is a partial resolution of tickets 4688, 5100, and 5289.
+    //    - A slight optimization for a common use case, particularly on POSIX since
+    //      value_type is char and that is the most common useage.
+    path(const value_type* s) : m_pathname(s) {}
+    path(const std::basic_string<value_type>& s) : m_pathname(s) {}
+
+    template <class Source>
+    path(Source const& source, const codecvt_type& cvt)
+    //  see [defaults] note above explaining why codecvt() default arguments are not used
+    {
+      path_traits::dispatch(source, m_pathname, cvt);
+    }
+
+    template <class InputIterator>
+    path(InputIterator begin, InputIterator end)
+    { 
+      if (begin != end)
+      {
+        std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+          s(begin, end);
+        path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, codecvt());
+      }
+    }
+
+    template <class InputIterator>
+    path(InputIterator begin, InputIterator end, const codecvt_type& cvt)
+    { 
+      if (begin != end)
+      {
+        std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+          s(begin, end);
+        path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt);
+      }
+    }
+
+    //  -----  assignments  -----
+
+    path& operator=(const path& p)
+    {
+      m_pathname = p.m_pathname;
+      return *this;
+    }
+
+    path& operator=(const value_type* ptr)  // required in case ptr overlaps *this
+    {
+      m_pathname = ptr;
+      return *this;
+    }
+
+    template <class Source>
+      typename ndnboost::enable_if<path_traits::is_pathable<
+        typename ndnboost::decay<Source>::type>, path&>::type
+    operator=(Source const& source)
+    {
+      m_pathname.clear();
+      path_traits::dispatch(source, m_pathname, codecvt());
+      return *this;
+    }
+
+    path& assign(const value_type* ptr, const codecvt_type&)  // required in case ptr overlaps *this
+    {
+      m_pathname = ptr;
+      return *this;
+    }
+
+    template <class Source>
+    path& assign(Source const& source, const codecvt_type& cvt)
+    {
+      m_pathname.clear();
+      path_traits::dispatch(source, m_pathname, cvt);
+      return *this;
+    }
+
+    template <class InputIterator>
+    path& assign(InputIterator begin, InputIterator end)
+    {
+      return assign(begin, end, codecvt());
+    }
+
+    template <class InputIterator>
+    path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt)
+    { 
+      m_pathname.clear();
+      if (begin != end)
+      {
+        std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+          s(begin, end);
+        path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt);
+      }
+      return *this;
+    }
+
+    //  -----  concatenation  -----
+
+    path& operator+=(const path& p)         {m_pathname += p.m_pathname; return *this;}
+    path& operator+=(const string_type& s)  {m_pathname += s; return *this;}
+    path& operator+=(const value_type* ptr) {m_pathname += ptr; return *this;}
+    path& operator+=(value_type c)          {m_pathname += c; return *this;}
+
+    template <class Source>
+      typename ndnboost::enable_if<path_traits::is_pathable<
+        typename ndnboost::decay<Source>::type>, path&>::type
+    operator+=(Source const& source)
+    {
+      return concat(source, codecvt());
+    }
+
+    template <class CharT>
+      typename ndnboost::enable_if<is_integral<CharT>, path&>::type
+    operator+=(CharT c)
+    {
+      CharT tmp[2];
+      tmp[0] = c;
+      tmp[1] = 0;
+      return concat(tmp, codecvt());
+    }
+
+    template <class Source>
+    path& concat(Source const& source, const codecvt_type& cvt)
+    {
+      path_traits::dispatch(source, m_pathname, cvt);
+      return *this;
+    }
+
+    template <class InputIterator>
+    path& concat(InputIterator begin, InputIterator end)
+    { 
+      return concat(begin, end, codecvt());
+    }
+
+    template <class InputIterator>
+    path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt)
+    { 
+      if (begin == end)
+        return *this;
+      std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+        s(begin, end);
+      path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt);
+      return *this;
+    }
+
+    //  -----  appends  -----
+
+    //  if a separator is added, it is the preferred separator for the platform;
+    //  slash for POSIX, backslash for Windows
+
+    path& operator/=(const path& p);
+
+    path& operator/=(const value_type* ptr);
+
+    template <class Source>
+      typename ndnboost::enable_if<path_traits::is_pathable<
+        typename ndnboost::decay<Source>::type>, path&>::type
+    operator/=(Source const& source)
+    {
+      return append(source, codecvt());
+    }
+
+    path& append(const value_type* ptr, const codecvt_type&)  // required in case ptr overlaps *this
+    {
+      this->operator/=(ptr);
+      return *this;
+    }
+
+    template <class Source>
+    path& append(Source const& source, const codecvt_type& cvt);
+
+    template <class InputIterator>
+    path& append(InputIterator begin, InputIterator end)
+    { 
+      return append(begin, end, codecvt());
+    }
+
+    template <class InputIterator>
+    path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt);
+
+    //  -----  modifiers  -----
+
+    void   clear()             { m_pathname.clear(); }
+    path&  make_preferred()
+#   ifdef NDNBOOST_POSIX_API
+      { return *this; }  // POSIX no effect
+#   else // NDNBOOST_WINDOWS_API
+      ;  // change slashes to backslashes
+#   endif
+    path&  remove_filename();
+    path&  replace_extension(const path& new_extension = path());
+    void   swap(path& rhs)     { m_pathname.swap(rhs.m_pathname); }
+
+    //  -----  observers  -----
+  
+    //  For operating systems that format file paths differently than directory
+    //  paths, return values from observers are formatted as file names unless there
+    //  is a trailing separator, in which case returns are formatted as directory
+    //  paths. POSIX and Windows make no such distinction.
+
+    //  Implementations are permitted to return const values or const references.
+
+    //  The string or path returned by an observer are specified as being formatted
+    //  as "native" or "generic".
+    //
+    //  For POSIX, these are all the same format; slashes and backslashes are as input and
+    //  are not modified.
+    //
+    //  For Windows,   native:    as input; slashes and backslashes are not modified;
+    //                            this is the format of the internally stored string.
+    //                 generic:   backslashes are converted to slashes
+
+    //  -----  native format observers  -----
+
+    const string_type&  native() const { return m_pathname; }          // Throws: nothing
+    const value_type*   c_str() const  { return m_pathname.c_str(); }  // Throws: nothing
+
+    template <class String>
+    String string() const;
+
+    template <class String>
+    String string(const codecvt_type& cvt) const;
+
+#   ifdef NDNBOOST_WINDOWS_API
+    const std::string string() const { return string(codecvt()); } 
+    const std::string string(const codecvt_type& cvt) const
+    { 
+      std::string tmp;
+      if (!m_pathname.empty())
+        path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
+          tmp, cvt);
+      return tmp;
+    }
+    
+    //  string_type is std::wstring, so there is no conversion
+    const std::wstring&  wstring() const { return m_pathname; }
+    const std::wstring&  wstring(const codecvt_type&) const { return m_pathname; }
+
+#   else   // NDNBOOST_POSIX_API
+    //  string_type is std::string, so there is no conversion
+    const std::string&  string() const { return m_pathname; }
+    const std::string&  string(const codecvt_type&) const { return m_pathname; }
+
+    const std::wstring  wstring() const { return wstring(codecvt()); }
+    const std::wstring  wstring(const codecvt_type& cvt) const
+    { 
+      std::wstring tmp;
+      if (!m_pathname.empty())
+        path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
+          tmp, cvt);
+      return tmp;
+    }
+
+#   endif
+
+    //  -----  generic format observers  -----
+
+    template <class String>
+    String generic_string() const;
+
+    template <class String>
+    String generic_string(const codecvt_type& cvt) const;
+
+#   ifdef NDNBOOST_WINDOWS_API
+    const std::string   generic_string() const { return generic_string(codecvt()); } 
+    const std::string   generic_string(const codecvt_type& cvt) const; 
+    const std::wstring  generic_wstring() const;
+    const std::wstring  generic_wstring(const codecvt_type&) const { return generic_wstring(); };
+
+#   else // NDNBOOST_POSIX_API
+    //  On POSIX-like systems, the generic format is the same as the native format
+    const std::string&  generic_string() const  { return m_pathname; }
+    const std::string&  generic_string(const codecvt_type&) const  { return m_pathname; }
+    const std::wstring  generic_wstring() const { return wstring(codecvt()); }
+    const std::wstring  generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); }
+
+#   endif
+
+    //  -----  compare  -----
+
+    int compare(const path& p) const NDNBOOST_NOEXCEPT;  // generic, lexicographical
+    int compare(const std::string& s) const { return compare(path(s)); }
+    int compare(const value_type* s) const  { return compare(path(s)); }
+
+    //  -----  decomposition  -----
+
+    path  root_path() const; 
+    path  root_name() const;         // returns 0 or 1 element path
+                                     // even on POSIX, root_name() is non-empty() for network paths
+    path  root_directory() const;    // returns 0 or 1 element path
+    path  relative_path() const;
+    path  parent_path() const;
+    path  filename() const;          // returns 0 or 1 element path
+    path  stem() const;              // returns 0 or 1 element path
+    path  extension() const;         // returns 0 or 1 element path
+
+    //  -----  query  -----
+
+    bool empty() const               { return m_pathname.empty(); } // name consistent with std containers
+    bool has_root_path() const       { return has_root_directory() || has_root_name(); }
+    bool has_root_name() const       { return !root_name().empty(); }
+    bool has_root_directory() const  { return !root_directory().empty(); }
+    bool has_relative_path() const   { return !relative_path().empty(); }
+    bool has_parent_path() const     { return !parent_path().empty(); }
+    bool has_filename() const        { return !m_pathname.empty(); }
+    bool has_stem() const            { return !stem().empty(); }
+    bool has_extension() const       { return !extension().empty(); }
+    bool is_absolute() const
+    {
+#     ifdef NDNBOOST_WINDOWS_API
+      return has_root_name() && has_root_directory();
+#     else
+      return has_root_directory();
+#     endif
+    }
+    bool is_relative() const         { return !is_absolute(); } 
+
+    //  -----  iterators  -----
+
+    class iterator;
+    typedef iterator const_iterator;
+
+    iterator begin() const;
+    iterator end() const;
+
+    //  -----  static member functions  -----
+
+    static std::locale  imbue(const std::locale& loc);
+    static const        codecvt_type& codecvt();
+
+    //  -----  deprecated functions  -----
+
+# if defined(NDNBOOST_FILESYSTEM_DEPRECATED) && defined(NDNBOOST_FILESYSTEM_NO_DEPRECATED)
+#   error both NDNBOOST_FILESYSTEM_DEPRECATED and NDNBOOST_FILESYSTEM_NO_DEPRECATED are defined
+# endif
+
+# if !defined(NDNBOOST_FILESYSTEM_NO_DEPRECATED)
+    //  recently deprecated functions supplied by default
+    path&  normalize()              { return m_normalize(); }
+    path&  remove_leaf()            { return remove_filename(); }
+    path   leaf() const             { return filename(); }
+    path   branch_path() const      { return parent_path(); }
+    bool   has_leaf() const         { return !m_pathname.empty(); }
+    bool   has_branch_path() const  { return !parent_path().empty(); }
+    bool   is_complete() const      { return is_absolute(); }
+# endif
+
+# if defined(NDNBOOST_FILESYSTEM_DEPRECATED)
+    //  deprecated functions with enough signature or semantic changes that they are
+    //  not supplied by default 
+    const std::string file_string() const               { return string(); }
+    const std::string directory_string() const          { return string(); }
+    const std::string native_file_string() const        { return string(); }
+    const std::string native_directory_string() const   { return string(); }
+    const string_type external_file_string() const      { return native(); }
+    const string_type external_directory_string() const { return native(); }
+
+    //  older functions no longer supported
+    //typedef bool (*name_check)(const std::string & name);
+    //basic_path(const string_type& str, name_check) { operator/=(str); }
+    //basic_path(const typename string_type::value_type* s, name_check)
+    //  { operator/=(s);}
+    //static bool default_name_check_writable() { return false; } 
+    //static void default_name_check(name_check) {}
+    //static name_check default_name_check() { return 0; }
+    //basic_path& canonize();
+# endif
+
+//--------------------------------------------------------------------------------------//
+//                            class path private members                                //
+//--------------------------------------------------------------------------------------//
+
+  private:
+#   if defined(_MSC_VER)
+#     pragma warning(push) // Save warning settings
+#     pragma warning(disable : 4251) // disable warning: class 'std::basic_string<_Elem,_Traits,_Ax>'
+#   endif                            // needs to have dll-interface...
+/*
+      m_pathname has the type, encoding, and format required by the native
+      operating system. Thus for POSIX and Windows there is no conversion for
+      passing m_pathname.c_str() to the O/S API or when obtaining a path from the
+      O/S API. POSIX encoding is unspecified other than for dot and slash
+      characters; POSIX just treats paths as a sequence of bytes. Windows
+      encoding is UCS-2 or UTF-16 depending on the version.
+*/
+    string_type  m_pathname;  // Windows: as input; backslashes NOT converted to slashes,
+                              // slashes NOT converted to backslashes
+#   if defined(_MSC_VER)
+#     pragma warning(pop) // restore warning settings.
+#   endif 
+
+    string_type::size_type m_append_separator_if_needed();
+    //  Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0.
+    //  Note: An append is never performed if size()==0, so a returned 0 is unambiguous.
+
+    void m_erase_redundant_separator(string_type::size_type sep_pos);
+    string_type::size_type m_parent_path_end() const;
+
+    path& m_normalize();
+
+    // Was qualified; como433beta8 reports:
+    //    warning #427-D: qualified name is not allowed in member declaration 
+    friend class iterator;
+    friend bool operator<(const path& lhs, const path& rhs);
+
+    // see path::iterator::increment/decrement comment below
+    static void m_path_iterator_increment(path::iterator & it);
+    static void m_path_iterator_decrement(path::iterator & it);
+
+  };  // class path
+
+  namespace detail
+  {
+    NDNBOOST_FILESYSTEM_DECL
+      int lex_compare(path::iterator first1, path::iterator last1,
+        path::iterator first2, path::iterator last2);
+  }
+
+# ifndef NDNBOOST_FILESYSTEM_NO_DEPRECATED
+  typedef path wpath;
+# endif
+
+  //------------------------------------------------------------------------------------//
+  //                             class path::iterator                                   //
+  //------------------------------------------------------------------------------------//
+ 
+  class path::iterator
+    : public ndnboost::iterator_facade<
+      path::iterator,
+      path const,
+      ndnboost::bidirectional_traversal_tag >
+  {
+  private:
+    friend class ndnboost::iterator_core_access;
+    friend class ndnboost::filesystem::path;
+    friend void m_path_iterator_increment(path::iterator & it);
+    friend void m_path_iterator_decrement(path::iterator & it);
+
+    const path& dereference() const { return m_element; }
+
+    bool equal(const iterator & rhs) const
+    {
+      return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos;
+    }
+
+    // iterator_facade derived classes don't seem to like implementations in
+    // separate translation unit dll's, so forward to class path static members
+    void increment() { m_path_iterator_increment(*this); }
+    void decrement() { m_path_iterator_decrement(*this); }
+
+    path                    m_element;   // current element
+    const path*             m_path_ptr;  // path being iterated over
+    string_type::size_type  m_pos;       // position of m_element in
+                                         // m_path_ptr->m_pathname.
+                                         // if m_element is implicit dot, m_pos is the
+                                         // position of the last separator in the path.
+                                         // end() iterator is indicated by 
+                                         // m_pos == m_path_ptr->m_pathname.size()
+  }; // path::iterator
+
+  //------------------------------------------------------------------------------------//
+  //                                                                                    //
+  //                              non-member functions                                  //
+  //                                                                                    //
+  //------------------------------------------------------------------------------------//
+
+  //  std::lexicographical_compare would infinately recurse because path iterators
+  //  yield paths, so provide a path aware version
+  inline bool lexicographical_compare(path::iterator first1, path::iterator last1,
+    path::iterator first2, path::iterator last2)
+    { return detail::lex_compare(first1, last1, first2, last2) < 0; }
+  
+  inline bool operator==(const path& lhs, const path& rhs)              {return lhs.compare(rhs) == 0;}
+  inline bool operator==(const path& lhs, const path::string_type& rhs) {return lhs.compare(rhs) == 0;} 
+  inline bool operator==(const path::string_type& lhs, const path& rhs) {return rhs.compare(lhs) == 0;}
+  inline bool operator==(const path& lhs, const path::value_type* rhs)  {return lhs.compare(rhs) == 0;}
+  inline bool operator==(const path::value_type* lhs, const path& rhs)  {return rhs.compare(lhs) == 0;}
+  
+  inline bool operator!=(const path& lhs, const path& rhs)              {return lhs.compare(rhs) != 0;}
+  inline bool operator!=(const path& lhs, const path::string_type& rhs) {return lhs.compare(rhs) != 0;} 
+  inline bool operator!=(const path::string_type& lhs, const path& rhs) {return rhs.compare(lhs) != 0;}
+  inline bool operator!=(const path& lhs, const path::value_type* rhs)  {return lhs.compare(rhs) != 0;}
+  inline bool operator!=(const path::value_type* lhs, const path& rhs)  {return rhs.compare(lhs) != 0;}
+
+  // TODO: why do == and != have additional overloads, but the others don't?
+
+  inline bool operator<(const path& lhs, const path& rhs)  {return lhs.compare(rhs) < 0;}
+  inline bool operator<=(const path& lhs, const path& rhs) {return !(rhs < lhs);}
+  inline bool operator> (const path& lhs, const path& rhs) {return rhs < lhs;}
+  inline bool operator>=(const path& lhs, const path& rhs) {return !(lhs < rhs);}
+
+  inline std::size_t hash_value(const path& x)
+  {
+# ifdef NDNBOOST_WINDOWS_API
+    std::size_t seed = 0;
+    for(const path::value_type* it = x.c_str(); *it; ++it)
+      hash_combine(seed, *it == '/' ? L'\\' : *it);
+    return seed;
+# else   // NDNBOOST_POSIX_API
+    return hash_range(x.native().begin(), x.native().end());
+# endif
+  }
+
+  inline void swap(path& lhs, path& rhs)                   { lhs.swap(rhs); }
+
+  inline path operator/(const path& lhs, const path& rhs)  { return path(lhs) /= rhs; }
+
+  //  inserters and extractors
+  //    use ndnboost::io::quoted() to handle spaces in paths
+  //    use '&' as escape character to ease use for Windows paths
+
+  template <class Char, class Traits>
+  inline std::basic_ostream<Char, Traits>&
+  operator<<(std::basic_ostream<Char, Traits>& os, const path& p)
+  {
+    return os
+      << ndnboost::io::quoted(p.template string<std::basic_string<Char> >(), static_cast<Char>('&'));
+  }
+  
+  template <class Char, class Traits>
+  inline std::basic_istream<Char, Traits>&
+  operator>>(std::basic_istream<Char, Traits>& is, path& p)
+  {
+    std::basic_string<Char> str;
+    is >> ndnboost::io::quoted(str, static_cast<Char>('&'));
+    p = str;
+    return is;
+  }
+  
+  //  name_checks
+
+  //  These functions are holdovers from version 1. It isn't clear they have much
+  //  usefulness, or how to generalize them for later versions.
+
+  NDNBOOST_FILESYSTEM_DECL bool portable_posix_name(const std::string & name);
+  NDNBOOST_FILESYSTEM_DECL bool windows_name(const std::string & name);
+  NDNBOOST_FILESYSTEM_DECL bool portable_name(const std::string & name);
+  NDNBOOST_FILESYSTEM_DECL bool portable_directory_name(const std::string & name);
+  NDNBOOST_FILESYSTEM_DECL bool portable_file_name(const std::string & name);
+  NDNBOOST_FILESYSTEM_DECL bool native(const std::string & name);
+ 
+//--------------------------------------------------------------------------------------//
+//                     class path member template implementation                        //
+//--------------------------------------------------------------------------------------//
+
+  template <class InputIterator>
+  path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt)
+  { 
+    if (begin == end)
+      return *this;
+    string_type::size_type sep_pos(m_append_separator_if_needed());
+    std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+      s(begin, end);
+    path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt);
+    if (sep_pos)
+      m_erase_redundant_separator(sep_pos);
+    return *this;
+  }
+
+  template <class Source>
+  path& path::append(Source const& source, const codecvt_type& cvt)
+  {
+    if (path_traits::empty(source))
+      return *this;
+    string_type::size_type sep_pos(m_append_separator_if_needed());
+    path_traits::dispatch(source, m_pathname, cvt);
+    if (sep_pos)
+      m_erase_redundant_separator(sep_pos);
+    return *this;
+  }
+
+//--------------------------------------------------------------------------------------//
+//                     class path member template specializations                       //
+//--------------------------------------------------------------------------------------//
+
+  template <> inline
+  std::string path::string<std::string>() const
+    { return string(); }
+
+  template <> inline
+  std::wstring path::string<std::wstring>() const
+    { return wstring(); }
+
+  template <> inline
+  std::string path::string<std::string>(const codecvt_type& cvt) const
+    { return string(cvt); }
+
+  template <> inline
+  std::wstring path::string<std::wstring>(const codecvt_type& cvt) const
+    { return wstring(cvt); }
+
+  template <> inline
+  std::string path::generic_string<std::string>() const
+    { return generic_string(); }
+
+  template <> inline
+  std::wstring path::generic_string<std::wstring>() const
+    { return generic_wstring(); }
+
+  template <> inline
+  std::string path::generic_string<std::string>(const codecvt_type& cvt) const
+    { return generic_string(cvt); }
+
+  template <> inline
+  std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const
+    { return generic_wstring(cvt); }
+
+
+}  // namespace filesystem
+}  // namespace ndnboost
+
+//----------------------------------------------------------------------------//
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+
+#endif  // NDNBOOST_FILESYSTEM_PATH_HPP
diff --git a/include/ndnboost/filesystem/path_traits.hpp b/include/ndnboost/filesystem/path_traits.hpp
new file mode 100644
index 0000000..34e13a9
--- /dev/null
+++ b/include/ndnboost/filesystem/path_traits.hpp
@@ -0,0 +1,235 @@
+//  filesystem path_traits.hpp  --------------------------------------------------------//
+
+//  Copyright Beman Dawes 2009
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  Library home page: http://www.boost.org/libs/filesystem
+
+#ifndef NDNBOOST_FILESYSTEM_PATH_TRAITS_HPP
+#define NDNBOOST_FILESYSTEM_PATH_TRAITS_HPP
+
+#include <ndnboost/config.hpp>
+
+# if defined( NDNBOOST_NO_STD_WSTRING )
+#   error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
+# endif
+
+#include <ndnboost/filesystem/config.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+#include <ndnboost/type_traits/is_array.hpp>
+#include <ndnboost/type_traits/decay.hpp>
+#include <ndnboost/system/error_code.hpp>
+#include <cwchar>  // for mbstate_t
+#include <string>
+#include <vector>
+#include <list>
+#include <iterator>
+#include <locale>
+#include <ndnboost/assert.hpp>
+// #include <iostream>   //**** comment me out ****
+
+#include <ndnboost/config/abi_prefix.hpp> // must be the last #include
+
+namespace ndnboost { namespace filesystem {
+
+  NDNBOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category();
+  //  uses std::codecvt_base::result used for error codes:
+  //
+  //    ok:       Conversion successful.
+  //    partial:  Not all source characters converted; one or more additional source
+  //              characters are needed to produce the final target character, or the
+  //              size of the target intermediate buffer was too small to hold the result.
+  //    error:    A character in the source could not be converted to the target encoding.
+  //    noconv:   The source and target characters have the same type and encoding, so no
+  //              conversion was necessary.
+
+  class directory_entry;
+  
+namespace path_traits {
+ 
+  typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
+
+  //  is_pathable type trait; allows disabling over-agressive class path member templates
+
+  template <class T>
+  struct is_pathable { static const bool value = false; };
+
+  template<> struct is_pathable<char*>                  { static const bool value = true; };
+  template<> struct is_pathable<const char*>            { static const bool value = true; };
+  template<> struct is_pathable<wchar_t*>               { static const bool value = true; };
+  template<> struct is_pathable<const wchar_t*>         { static const bool value = true; };
+  template<> struct is_pathable<std::string>            { static const bool value = true; };
+  template<> struct is_pathable<std::wstring>           { static const bool value = true; };
+  template<> struct is_pathable<std::vector<char> >     { static const bool value = true; };
+  template<> struct is_pathable<std::vector<wchar_t> >  { static const bool value = true; };
+  template<> struct is_pathable<std::list<char> >       { static const bool value = true; };
+  template<> struct is_pathable<std::list<wchar_t> >    { static const bool value = true; };
+  template<> struct is_pathable<directory_entry>        { static const bool value = true; };
+
+  //  Pathable empty
+
+  template <class Container> inline
+    // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
+    // conforming compilers. Replace by plain "bool" at some future date (2012?) 
+    typename ndnboost::disable_if<ndnboost::is_array<Container>, bool>::type
+      empty(const Container & c)
+        { return c.begin() == c.end(); }
+
+  template <class T> inline
+    bool empty(T * const & c_str)
+  {
+    NDNBOOST_ASSERT(c_str);
+    return !*c_str;
+  }
+
+  template <typename T, size_t N> inline
+     bool empty(T (&x)[N])
+       { return !x[0]; }
+
+  // value types differ  ---------------------------------------------------------------//
+  //
+  //   A from_end argument of 0 is less efficient than a known end, so use only if needed
+  
+  NDNBOOST_FILESYSTEM_DECL
+  void convert(const char* from,
+                const char* from_end,    // 0 for null terminated MBCS
+                std::wstring & to,
+                const codecvt_type& cvt);
+
+  NDNBOOST_FILESYSTEM_DECL
+  void convert(const wchar_t* from,
+                const wchar_t* from_end,  // 0 for null terminated MBCS
+                std::string & to,
+                const codecvt_type& cvt);
+
+  inline 
+  void convert(const char* from,
+                std::wstring & to,
+                const codecvt_type& cvt)
+  {
+    NDNBOOST_ASSERT(from);
+    convert(from, 0, to, cvt);
+  }
+
+  inline 
+  void convert(const wchar_t* from,
+                std::string & to,
+                const codecvt_type& cvt)
+  {
+    NDNBOOST_ASSERT(from);
+    convert(from, 0, to, cvt);
+  }
+
+  // value types same  -----------------------------------------------------------------//
+
+  // char
+
+  inline 
+  void convert(const char* from, const char* from_end, std::string & to,
+    const codecvt_type&)
+  {
+    NDNBOOST_ASSERT(from);
+    NDNBOOST_ASSERT(from_end);
+    to.append(from, from_end);
+  }
+
+  inline 
+  void convert(const char* from,
+                std::string & to,
+                const codecvt_type&)
+  {
+    NDNBOOST_ASSERT(from);
+    to += from;
+  }
+
+  // wchar_t
+
+  inline 
+  void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to,
+    const codecvt_type&)
+  {
+    NDNBOOST_ASSERT(from);
+    NDNBOOST_ASSERT(from_end);
+    to.append(from, from_end);
+  }
+
+  inline 
+  void convert(const wchar_t* from,
+                std::wstring & to,
+                const codecvt_type&)
+  {
+    NDNBOOST_ASSERT(from);
+    to += from;
+  }
+
+  //  Source dispatch  -----------------------------------------------------------------//
+
+  //  contiguous containers
+  template <class U> inline
+    void dispatch(const std::string& c, U& to, const codecvt_type& cvt)
+  {
+    if (c.size())
+      convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
+  }
+  template <class U> inline
+    void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt)
+  {
+    if (c.size())
+      convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
+  }
+  template <class U> inline
+    void dispatch(const std::vector<char>& c, U& to, const codecvt_type& cvt)
+  {
+    if (c.size())
+      convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
+  }
+  template <class U> inline
+    void dispatch(const std::vector<wchar_t>& c, U& to, const codecvt_type& cvt)
+  {
+    if (c.size())
+      convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
+  }
+
+  //  non-contiguous containers
+  template <class Container, class U> inline
+    // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
+    // conforming compilers. Replace by plain "void" at some future date (2012?) 
+    typename ndnboost::disable_if<ndnboost::is_array<Container>, void>::type
+      dispatch(const Container & c, U& to, const codecvt_type& cvt)
+  {
+    if (c.size())
+    {
+      std::basic_string<typename Container::value_type> s(c.begin(), c.end());
+      convert(s.c_str(), s.c_str()+s.size(), to, cvt);
+    }
+  }
+
+  //  c_str
+  template <class T, class U> inline
+  void dispatch(T * const & c_str, U& to, const codecvt_type& cvt)
+  {
+//    std::cout << "dispatch() const T *\n";
+    NDNBOOST_ASSERT(c_str);
+    convert(c_str, to, cvt);
+  }
+  
+  //  Note: there is no dispatch on C-style arrays because the array may
+  //  contain a string smaller than the array size. 
+
+  NDNBOOST_FILESYSTEM_DECL
+  void dispatch(const directory_entry & de,
+#                ifdef NDNBOOST_WINDOWS_API
+                   std::wstring & to,
+#                else   
+                   std::string & to,
+#                endif
+                 const codecvt_type&);
+
+
+}}} // namespace ndnboost::filesystem::path_traits
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+
+#endif  // NDNBOOST_FILESYSTEM_PATH_TRAITS_HPP
diff --git a/include/ndnboost/functional/hash.hpp b/include/ndnboost/functional/hash.hpp
new file mode 100644
index 0000000..bcc68bc
--- /dev/null
+++ b/include/ndnboost/functional/hash.hpp
@@ -0,0 +1,7 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include <ndnboost/functional/hash/hash.hpp>
+
diff --git a/include/ndnboost/functional/hash/detail/float_functions.hpp b/include/ndnboost/functional/hash/detail/float_functions.hpp
new file mode 100644
index 0000000..131ab62
--- /dev/null
+++ b/include/ndnboost/functional/hash/detail/float_functions.hpp
@@ -0,0 +1,336 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if !defined(NDNBOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
+#define NDNBOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/config/no_tr1/cmath.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// Set NDNBOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
+// sufficiently good floating point support to not require any
+// workarounds.
+//
+// When set to 0, the library tries to automatically
+// use the best available implementation. This normally works well, but
+// breaks when ambiguities are created by odd namespacing of the functions.
+//
+// Note that if this is set to 0, the library should still take full
+// advantage of the platform's floating point support.
+
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__LIBCOMO__)
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
+// Rogue Wave library:
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(_LIBCPP_VERSION)
+// libc++
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 1
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+// GNU libstdc++ 3
+#   if defined(__GNUC__) && __GNUC__ >= 4
+#       define NDNBOOST_HASH_CONFORMANT_FLOATS 1
+#   else
+#       define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#   endif
+#elif defined(__STL_CONFIG_H)
+// generic SGI STL
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__MSL_CPP__)
+// MSL standard lib:
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__IBMCPP__)
+// VACPP std lib (probably conformant for much earlier version).
+#   if __IBMCPP__ >= 1210
+#       define NDNBOOST_HASH_CONFORMANT_FLOATS 1
+#   else
+#       define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#   endif
+#elif defined(MSIPL_COMPILE_H)
+// Modena C++ standard library
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
+// Dinkumware Library (this has to appear after any possible replacement libraries):
+#   if _CPPLIB_VER >= 405
+#       define NDNBOOST_HASH_CONFORMANT_FLOATS 1
+#   else
+#       define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#   endif
+#else
+#   define NDNBOOST_HASH_CONFORMANT_FLOATS 0
+#endif
+
+#if NDNBOOST_HASH_CONFORMANT_FLOATS
+
+// The standard library is known to be compliant, so don't use the
+// configuration mechanism.
+
+namespace ndnboost {
+    namespace hash_detail {
+        template <typename Float>
+        struct call_ldexp {
+            typedef Float float_type;
+            inline Float operator()(Float x, int y) const {
+                return std::ldexp(x, y);
+            }
+        };
+
+        template <typename Float>
+        struct call_frexp {
+            typedef Float float_type;
+            inline Float operator()(Float x, int* y) const {
+                return std::frexp(x, y);
+            }
+        };
+
+        template <typename Float>
+        struct select_hash_type
+        {
+            typedef Float type;
+        };
+    }
+}
+
+#else // NDNBOOST_HASH_CONFORMANT_FLOATS == 0
+
+// The C++ standard requires that the C float functions are overloarded
+// for float, double and long double in the std namespace, but some of the older
+// library implementations don't support this. On some that don't, the C99
+// float functions (frexpf, frexpl, etc.) are available.
+//
+// The following tries to automatically detect which are available.
+
+namespace ndnboost {
+    namespace hash_detail {
+
+        // Returned by dummy versions of the float functions.
+    
+        struct not_found {
+            // Implicitly convertible to float and long double in order to avoid
+            // a compile error when the dummy float functions are used.
+
+            inline operator float() const { return 0; }
+            inline operator long double() const { return 0; }
+        };
+          
+        // A type for detecting the return type of functions.
+
+        template <typename T> struct is;
+        template <> struct is<float> { char x[10]; };
+        template <> struct is<double> { char x[20]; };
+        template <> struct is<long double> { char x[30]; };
+        template <> struct is<ndnboost::hash_detail::not_found> { char x[40]; };
+            
+        // Used to convert the return type of a function to a type for sizeof.
+
+        template <typename T> is<T> float_type(T);
+
+        // call_ldexp
+        //
+        // This will get specialized for float and long double
+        
+        template <typename Float> struct call_ldexp
+        {
+            typedef double float_type;
+            
+            inline double operator()(double a, int b) const
+            {
+                using namespace std;
+                return ldexp(a, b);
+            }
+        };
+
+        // call_frexp
+        //
+        // This will get specialized for float and long double
+
+        template <typename Float> struct call_frexp
+        {
+            typedef double float_type;
+            
+            inline double operator()(double a, int* b) const
+            {
+                using namespace std;
+                return frexp(a, b);
+            }
+        };
+    }
+}
+            
+// A namespace for dummy functions to detect when the actual function we want
+// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
+//
+// AFAICT these have to be outside of the boost namespace, as if they're in
+// the boost namespace they'll always be preferable to any other function
+// (since the arguments are built in types, ADL can't be used).
+
+namespace ndnboost_hash_detect_float_functions {
+    template <class Float> ndnboost::hash_detail::not_found ldexp(Float, int);
+    template <class Float> ndnboost::hash_detail::not_found frexp(Float, int*);    
+}
+
+// Macros for generating specializations of call_ldexp and call_frexp.
+//
+// check_cpp and check_c99 check if the C++ or C99 functions are available.
+//
+// Then the call_* functions select an appropriate implementation.
+//
+// I used c99_func in a few places just to get a unique name.
+//
+// Important: when using 'using namespace' at namespace level, include as
+// little as possible in that namespace, as Visual C++ has an odd bug which
+// can cause the namespace to be imported at the global level. This seems to
+// happen mainly when there's a template in the same namesapce.
+
+#define NDNBOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2)    \
+namespace ndnboost_hash_detect_float_functions {                           \
+    template <class Float>                                              \
+    ndnboost::hash_detail::not_found c99_func(Float, type2);               \
+}                                                                       \
+                                                                        \
+namespace ndnboost {                                                       \
+    namespace hash_detail {                                             \
+        namespace c99_func##_detect {                                   \
+            using namespace std;                                        \
+            using namespace ndnboost_hash_detect_float_functions;          \
+                                                                        \
+            struct check {                                              \
+                static type1 x;                                         \
+                static type2 y;                                         \
+                NDNBOOST_STATIC_CONSTANT(bool, cpp =                       \
+                    sizeof(float_type(cpp_func(x,y)))                   \
+                        == sizeof(is<type1>));                          \
+                NDNBOOST_STATIC_CONSTANT(bool, c99 =                       \
+                    sizeof(float_type(c99_func(x,y)))                   \
+                        == sizeof(is<type1>));                          \
+            };                                                          \
+        }                                                               \
+                                                                        \
+        template <bool x>                                               \
+        struct call_c99_##c99_func :                                    \
+            ndnboost::hash_detail::call_##cpp_func<double> {};             \
+                                                                        \
+        template <>                                                     \
+        struct call_c99_##c99_func<true> {                              \
+            typedef type1 float_type;                                   \
+                                                                        \
+            template <typename T>                                       \
+            inline type1 operator()(type1 a, T b)  const                \
+            {                                                           \
+                using namespace std;                                    \
+                return c99_func(a, b);                                  \
+            }                                                           \
+        };                                                              \
+                                                                        \
+        template <bool x>                                               \
+        struct call_cpp_##c99_func :                                    \
+            call_c99_##c99_func<                                        \
+                ::ndnboost::hash_detail::c99_func##_detect::check::c99     \
+            > {};                                                       \
+                                                                        \
+        template <>                                                     \
+        struct call_cpp_##c99_func<true> {                              \
+            typedef type1 float_type;                                   \
+                                                                        \
+            template <typename T>                                       \
+            inline type1 operator()(type1 a, T b)  const                \
+            {                                                           \
+                using namespace std;                                    \
+                return cpp_func(a, b);                                  \
+            }                                                           \
+        };                                                              \
+                                                                        \
+        template <>                                                     \
+        struct call_##cpp_func<type1> :                                 \
+            call_cpp_##c99_func<                                        \
+                ::ndnboost::hash_detail::c99_func##_detect::check::cpp     \
+            > {};                                                       \
+    }                                                                   \
+}
+
+#define NDNBOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2)   \
+namespace ndnboost {                                                       \
+    namespace hash_detail {                                             \
+                                                                        \
+        template <>                                                     \
+        struct call_##cpp_func<type1> {                                 \
+            typedef type1 float_type;                                   \
+            inline type1 operator()(type1 x, type2 y) const {           \
+                return c99_func(x, y);                                  \
+            }                                                           \
+        };                                                              \
+    }                                                                   \
+}
+
+#if defined(ldexpf)
+NDNBOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
+#else
+NDNBOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
+#endif
+
+#if defined(ldexpl)
+NDNBOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
+#else
+NDNBOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
+#endif
+
+#if defined(frexpf)
+NDNBOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
+#else
+NDNBOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
+#endif
+
+#if defined(frexpl)
+NDNBOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
+#else
+NDNBOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
+#endif
+
+#undef NDNBOOST_HASH_CALL_FLOAT_MACRO
+#undef NDNBOOST_HASH_CALL_FLOAT_FUNC
+
+
+namespace ndnboost
+{
+    namespace hash_detail
+    {
+        template <typename Float1, typename Float2>
+        struct select_hash_type_impl {
+            typedef double type;
+        };
+
+        template <>
+        struct select_hash_type_impl<float, float> {
+            typedef float type;
+        };
+
+        template <>
+        struct select_hash_type_impl<long double, long double> {
+            typedef long double type;
+        };
+
+
+        // select_hash_type
+        //
+        // If there is support for a particular floating point type, use that
+        // otherwise use double (there's always support for double).
+             
+        template <typename Float>
+        struct select_hash_type : select_hash_type_impl<
+                NDNBOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
+                NDNBOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
+            > {};            
+    }
+}
+
+#endif // NDNBOOST_HASH_CONFORMANT_FLOATS
+
+#endif
diff --git a/include/ndnboost/functional/hash/detail/hash_float.hpp b/include/ndnboost/functional/hash/detail/hash_float.hpp
new file mode 100644
index 0000000..76873ae
--- /dev/null
+++ b/include/ndnboost/functional/hash/detail/hash_float.hpp
@@ -0,0 +1,277 @@
+
+// Copyright 2005-2012 Daniel James.
+// 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)
+
+#if !defined(NDNBOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
+#define NDNBOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/functional/hash/detail/float_functions.hpp>
+#include <ndnboost/functional/hash/detail/limits.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+#include <ndnboost/integer/static_log2.hpp>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/limits.hpp>
+#include <cstring>
+
+#if defined(NDNBOOST_MSVC)
+#pragma warning(push)
+#if NDNBOOST_MSVC >= 1400
+#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
+                              // not satisfy test. Loop body not executed
+#endif
+#endif
+
+// Can we use fpclassify?
+
+// STLport
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+#define NDNBOOST_HASH_USE_FPCLASSIFY 0
+
+// GNU libstdc++ 3
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+#  if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
+      !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+#    define NDNBOOST_HASH_USE_FPCLASSIFY 1
+#  else
+#    define NDNBOOST_HASH_USE_FPCLASSIFY 0
+#  endif
+
+// Everything else
+#else
+#  define NDNBOOST_HASH_USE_FPCLASSIFY 0
+#endif
+
+namespace ndnboost
+{
+    namespace hash_detail
+    {
+        inline void hash_float_combine(std::size_t& seed, std::size_t value)
+        {
+            seed ^= value + (seed<<6) + (seed>>2);
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Binary hash function
+        //
+        // Only used for floats with known iec559 floats, and certain values in
+        // numeric_limits
+
+        inline std::size_t hash_binary(char* ptr, std::size_t length)
+        {
+            std::size_t seed = 0;
+
+            if (length >= sizeof(std::size_t)) {
+                seed = *(std::size_t*) ptr;
+                length -= sizeof(std::size_t);
+                ptr += sizeof(std::size_t);
+
+                while(length >= sizeof(std::size_t)) {
+                    std::size_t buffer = 0;
+                    std::memcpy(&buffer, ptr, sizeof(std::size_t));
+                    hash_float_combine(seed, buffer);
+                    length -= sizeof(std::size_t);
+                    ptr += sizeof(std::size_t);
+                }
+            }
+
+            if (length > 0) {
+                std::size_t buffer = 0;
+                std::memcpy(&buffer, ptr, length);
+                hash_float_combine(seed, buffer);
+            }
+
+            return seed;
+        }
+
+        template <typename Float>
+        inline std::size_t float_hash_impl(Float v,
+            NDNBOOST_DEDUCED_TYPENAME ndnboost::enable_if_c<
+                std::numeric_limits<Float>::is_iec559 &&
+                std::numeric_limits<Float>::digits == 24 &&
+                std::numeric_limits<Float>::radix == 2 &&
+                std::numeric_limits<Float>::max_exponent == 128,
+                int>::type
+            )
+        {
+            return hash_binary((char*) &v, 4);
+        }
+
+
+        template <typename Float>
+        inline std::size_t float_hash_impl(Float v,
+            NDNBOOST_DEDUCED_TYPENAME ndnboost::enable_if_c<
+                std::numeric_limits<Float>::is_iec559 &&
+                std::numeric_limits<Float>::digits == 53 &&
+                std::numeric_limits<Float>::radix == 2 &&
+                std::numeric_limits<Float>::max_exponent == 1024,
+                int>::type
+            )
+        {
+            return hash_binary((char*) &v, 8);
+        }
+
+        template <typename Float>
+        inline std::size_t float_hash_impl(Float v,
+            NDNBOOST_DEDUCED_TYPENAME ndnboost::enable_if_c<
+                std::numeric_limits<Float>::is_iec559 &&
+                std::numeric_limits<Float>::digits == 64 &&
+                std::numeric_limits<Float>::radix == 2 &&
+                std::numeric_limits<Float>::max_exponent == 16384,
+                int>::type
+            )
+        {
+            return hash_binary((char*) &v, 10);
+        }
+
+        template <typename Float>
+        inline std::size_t float_hash_impl(Float v,
+            NDNBOOST_DEDUCED_TYPENAME ndnboost::enable_if_c<
+                std::numeric_limits<Float>::is_iec559 &&
+                std::numeric_limits<Float>::digits == 113 &&
+                std::numeric_limits<Float>::radix == 2 &&
+                std::numeric_limits<Float>::max_exponent == 16384,
+                int>::type
+            )
+        {
+            return hash_binary((char*) &v, 16);
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // Portable hash function
+        //
+        // Used as a fallback when the binary hash function isn't supported.
+
+        template <class T>
+        inline std::size_t float_hash_impl2(T v)
+        {
+            ndnboost::hash_detail::call_frexp<T> frexp;
+            ndnboost::hash_detail::call_ldexp<T> ldexp;
+
+            int exp = 0;
+
+            v = frexp(v, &exp);
+
+            // A postive value is easier to hash, so combine the
+            // sign with the exponent and use the absolute value.
+            if(v < 0) {
+                v = -v;
+                exp += limits<T>::max_exponent -
+                    limits<T>::min_exponent;
+            }
+
+            v = ldexp(v, limits<std::size_t>::digits);
+            std::size_t seed = static_cast<std::size_t>(v);
+            v -= static_cast<T>(seed);
+
+            // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
+            std::size_t const length
+                = (limits<T>::digits *
+                        ndnboost::static_log2<limits<T>::radix>::value
+                        + limits<std::size_t>::digits - 1)
+                / limits<std::size_t>::digits;
+
+            for(std::size_t i = 0; i != length; ++i)
+            {
+                v = ldexp(v, limits<std::size_t>::digits);
+                std::size_t part = static_cast<std::size_t>(v);
+                v -= static_cast<T>(part);
+                hash_float_combine(seed, part);
+            }
+
+            hash_float_combine(seed, exp);
+
+            return seed;
+        }
+
+#if !defined(NDNBOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
+        template <class T>
+        inline std::size_t float_hash_impl(T v, ...)
+        {
+            typedef NDNBOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
+            return float_hash_impl2(static_cast<type>(v));
+        }
+#endif
+    }
+}
+
+#if NDNBOOST_HASH_USE_FPCLASSIFY
+
+#include <ndnboost/config/no_tr1/cmath.hpp>
+
+namespace ndnboost
+{
+    namespace hash_detail
+    {
+        template <class T>
+        inline std::size_t float_hash_value(T v)
+        {
+#if defined(fpclassify)
+            switch (fpclassify(v))
+#elif NDNBOOST_HASH_CONFORMANT_FLOATS
+            switch (std::fpclassify(v))
+#else
+            using namespace std;
+            switch (fpclassify(v))
+#endif
+            {
+            case FP_ZERO:
+                return 0;
+            case FP_INFINITE:
+                return (std::size_t)(v > 0 ? -1 : -2);
+            case FP_NAN:
+                return (std::size_t)(-3);
+            case FP_NORMAL:
+            case FP_SUBNORMAL:
+                return float_hash_impl(v, 0);
+            default:
+                NDNBOOST_ASSERT(0);
+                return 0;
+            }
+        }
+    }
+}
+
+#else // !NDNBOOST_HASH_USE_FPCLASSIFY
+
+namespace ndnboost
+{
+    namespace hash_detail
+    {
+        template <class T>
+        inline bool is_zero(T v)
+        {
+#if !defined(__GNUC__)
+            return v == 0;
+#else
+            // GCC's '-Wfloat-equal' will complain about comparing
+            // v to 0, but because it disables warnings for system
+            // headers it won't complain if you use std::equal_to to
+            // compare with 0. Resulting in this silliness:
+            return std::equal_to<T>()(v, 0);
+#endif
+        }
+
+        template <class T>
+        inline std::size_t float_hash_value(T v)
+        {
+            return ndnboost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
+        }
+    }
+}
+
+#endif // NDNBOOST_HASH_USE_FPCLASSIFY
+
+#undef NDNBOOST_HASH_USE_FPCLASSIFY
+
+#if defined(NDNBOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/ndnboost/functional/hash/detail/limits.hpp b/include/ndnboost/functional/hash/detail/limits.hpp
new file mode 100644
index 0000000..f25b3be
--- /dev/null
+++ b/include/ndnboost/functional/hash/detail/limits.hpp
@@ -0,0 +1,61 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+//
+// On some platforms std::limits gives incorrect values for long double.
+// This tries to work around them.
+
+#if !defined(NDNBOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
+#define NDNBOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/limits.hpp>
+
+// On OpenBSD, numeric_limits is not reliable for long doubles, but
+// the macros defined in <float.h> are and support long double when STLport
+// doesn't.
+
+#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
+#include <float.h>
+#endif
+
+namespace ndnboost
+{
+    namespace hash_detail
+    {
+        template <class T>
+        struct limits : std::numeric_limits<T> {};
+
+#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
+        template <>
+        struct limits<long double>
+             : std::numeric_limits<long double>
+        {
+            static long double epsilon() {
+                return LDBL_EPSILON;
+            }
+
+            static long double (max)() {
+                return LDBL_MAX;
+            }
+
+            static long double (min)() {
+                return LDBL_MIN;
+            }
+
+            NDNBOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
+            NDNBOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
+            NDNBOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
+#if defined(_STLP_NO_LONG_DOUBLE)
+            NDNBOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
+#endif
+        };
+#endif // __OpenBSD__
+    }
+}
+
+#endif
diff --git a/include/ndnboost/functional/hash/extensions.hpp b/include/ndnboost/functional/hash/extensions.hpp
new file mode 100644
index 0000000..b079137
--- /dev/null
+++ b/include/ndnboost/functional/hash/extensions.hpp
@@ -0,0 +1,379 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+//  Based on Peter Dimov's proposal
+//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+//  issue 6.18. 
+
+// This implements the extensions to the standard.
+// It's undocumented, so you shouldn't use it....
+
+#if !defined(NDNBOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
+#define NDNBOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
+
+#include <ndnboost/functional/hash/hash.hpp>
+#include <ndnboost/detail/container_fwd.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/preprocessor/repetition/repeat_from_to.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_ARRAY)
+#   include <array>
+#endif
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_TUPLE)
+#   include <tuple>
+#endif
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_MEMORY)
+#   include <memory>
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#if defined(NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+#include <ndnboost/type_traits/is_array.hpp>
+#endif
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+#include <ndnboost/type_traits/is_const.hpp>
+#endif
+
+namespace ndnboost
+{
+    template <class A, class B>
+    std::size_t hash_value(std::pair<A, B> const&);
+    template <class T, class A>
+    std::size_t hash_value(std::vector<T, A> const&);
+    template <class T, class A>
+    std::size_t hash_value(std::list<T, A> const& v);
+    template <class T, class A>
+    std::size_t hash_value(std::deque<T, A> const& v);
+    template <class K, class C, class A>
+    std::size_t hash_value(std::set<K, C, A> const& v);
+    template <class K, class C, class A>
+    std::size_t hash_value(std::multiset<K, C, A> const& v);
+    template <class K, class T, class C, class A>
+    std::size_t hash_value(std::map<K, T, C, A> const& v);
+    template <class K, class T, class C, class A>
+    std::size_t hash_value(std::multimap<K, T, C, A> const& v);
+
+    template <class T>
+    std::size_t hash_value(std::complex<T> const&);
+
+    template <class A, class B>
+    std::size_t hash_value(std::pair<A, B> const& v)
+    {
+        std::size_t seed = 0;
+        ndnboost::hash_combine(seed, v.first);
+        ndnboost::hash_combine(seed, v.second);
+        return seed;
+    }
+
+    template <class T, class A>
+    std::size_t hash_value(std::vector<T, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class T, class A>
+    std::size_t hash_value(std::list<T, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class T, class A>
+    std::size_t hash_value(std::deque<T, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class K, class C, class A>
+    std::size_t hash_value(std::set<K, C, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class K, class C, class A>
+    std::size_t hash_value(std::multiset<K, C, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class K, class T, class C, class A>
+    std::size_t hash_value(std::map<K, T, C, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class K, class T, class C, class A>
+    std::size_t hash_value(std::multimap<K, T, C, A> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+
+    template <class T>
+    std::size_t hash_value(std::complex<T> const& v)
+    {
+        ndnboost::hash<T> hasher;
+        std::size_t seed = hasher(v.imag());
+        seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
+        return seed;
+    }
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_ARRAY)
+    template <class T, std::size_t N>
+    std::size_t hash_value(std::array<T, N> const& v)
+    {
+        return ndnboost::hash_range(v.begin(), v.end());
+    }
+#endif
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_TUPLE)
+    namespace hash_detail {
+        template <std::size_t I, typename T>
+        inline typename ndnboost::enable_if_c<(I == std::tuple_size<T>::value),
+                void>::type
+            hash_combine_tuple(std::size_t&, T const&)
+        {
+        }
+
+        template <std::size_t I, typename T>
+        inline typename ndnboost::enable_if_c<(I < std::tuple_size<T>::value),
+                void>::type
+            hash_combine_tuple(std::size_t& seed, T const& v)
+        {
+            ndnboost::hash_combine(seed, std::get<I>(v));
+            ndnboost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
+        }
+
+        template <typename T>
+        inline std::size_t hash_tuple(T const& v)
+        {
+            std::size_t seed = 0;
+            ndnboost::hash_detail::hash_combine_tuple<0>(seed, v);
+            return seed;
+        }
+    }
+
+#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
+    template <typename... T>
+    inline std::size_t hash_value(std::tuple<T...> const& v)
+    {
+        return ndnboost::hash_detail::hash_tuple(v);
+    }
+#else
+
+    inline std::size_t hash_value(std::tuple<> const& v)
+    {
+        return ndnboost::hash_detail::hash_tuple(v);
+    }
+
+#   define NDNBOOST_HASH_TUPLE_F(z, n, _)                                      \
+    template<                                                               \
+        NDNBOOST_PP_ENUM_PARAMS_Z(z, n, typename A)                            \
+    >                                                                       \
+    inline std::size_t hash_value(std::tuple<                               \
+        NDNBOOST_PP_ENUM_PARAMS_Z(z, n, A)                                     \
+    > const& v)                                                             \
+    {                                                                       \
+        return ndnboost::hash_detail::hash_tuple(v);                           \
+    }
+
+    NDNBOOST_PP_REPEAT_FROM_TO(1, 11, NDNBOOST_HASH_TUPLE_F, _)
+#   undef NDNBOOST_HASH_TUPLE_F
+#endif
+
+#endif
+
+#if !defined(NDNBOOST_NO_CXX11_SMART_PTR)
+    template <typename T>
+    inline std::size_t hash_value(std::shared_ptr<T> const& x) {
+        return ndnboost::hash_value(x.get());
+    }
+
+    template <typename T, typename Deleter>
+    inline std::size_t hash_value(std::unique_ptr<T, Deleter> const& x) {
+        return ndnboost::hash_value(x.get());
+    }
+#endif
+
+    //
+    // call_hash_impl
+    //
+
+    // On compilers without function template ordering, this deals with arrays.
+
+#if defined(NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+    namespace hash_detail
+    {
+        template <bool IsArray>
+        struct call_hash_impl
+        {
+            template <class T>
+            struct inner
+            {
+                static std::size_t call(T const& v)
+                {
+                    using namespace ndnboost;
+                    return hash_value(v);
+                }
+            };
+        };
+
+        template <>
+        struct call_hash_impl<true>
+        {
+            template <class Array>
+            struct inner
+            {
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+                static std::size_t call(Array const& v)
+#else
+                static std::size_t call(Array& v)
+#endif
+                {
+                    const int size = sizeof(v) / sizeof(*v);
+                    return ndnboost::hash_range(v, v + size);
+                }
+            };
+        };
+
+        template <class T>
+        struct call_hash
+            : public call_hash_impl<ndnboost::is_array<T>::value>
+                ::NDNBOOST_NESTED_TEMPLATE inner<T>
+        {
+        };
+    }
+#endif // NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+    //
+    // ndnboost::hash
+    //
+
+
+#if !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+    template <class T> struct hash
+        : std::unary_function<T, std::size_t>
+    {
+#if !defined(NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+        std::size_t operator()(T const& val) const
+        {
+            return hash_value(val);
+        }
+#else
+        std::size_t operator()(T const& val) const
+        {
+            return hash_detail::call_hash<T>::call(val);
+        }
+#endif
+    };
+
+#if NDNBOOST_WORKAROUND(__DMC__, <= 0x848)
+    template <class T, unsigned int n> struct hash<T[n]>
+        : std::unary_function<T[n], std::size_t>
+    {
+        std::size_t operator()(const T* val) const
+        {
+            return ndnboost::hash_range(val, val+n);
+        }
+    };
+#endif
+
+#else // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+    // On compilers without partial specialization, ndnboost::hash<T>
+    // has already been declared to deal with pointers, so just
+    // need to supply the non-pointer version of hash_impl.
+
+    namespace hash_detail
+    {
+        template <bool IsPointer>
+        struct hash_impl;
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+
+        template <>
+        struct hash_impl<false>
+        {
+            template <class T>
+            struct inner
+                : std::unary_function<T, std::size_t>
+            {
+#if !defined(NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+                std::size_t operator()(T const& val) const
+                {
+                    return hash_value(val);
+                }
+#else
+                std::size_t operator()(T const& val) const
+                {
+                    return hash_detail::call_hash<T>::call(val);
+                }
+#endif
+            };
+        };
+
+#else // Visual C++ 6.5
+
+        // Visual C++ 6.5 has problems with nested member functions and
+        // applying const to const types in templates. So we get this:
+
+        template <bool IsConst>
+        struct hash_impl_msvc
+        {
+            template <class T>
+            struct inner
+                : public std::unary_function<T, std::size_t>
+            {
+                std::size_t operator()(T const& val) const
+                {
+                    return hash_detail::call_hash<T const>::call(val);
+                }
+
+                std::size_t operator()(T& val) const
+                {
+                    return hash_detail::call_hash<T>::call(val);
+                }
+            };
+        };
+
+        template <>
+        struct hash_impl_msvc<true>
+        {
+            template <class T>
+            struct inner
+                : public std::unary_function<T, std::size_t>
+            {
+                std::size_t operator()(T& val) const
+                {
+                    return hash_detail::call_hash<T>::call(val);
+                }
+            };
+        };
+        
+        template <class T>
+        struct hash_impl_msvc2
+            : public hash_impl_msvc<ndnboost::is_const<T>::value>
+                    ::NDNBOOST_NESTED_TEMPLATE inner<T> {};
+        
+        template <>
+        struct hash_impl<false>
+        {
+            template <class T>
+            struct inner : public hash_impl_msvc2<T> {};
+        };
+
+#endif // Visual C++ 6.5
+    }
+#endif  // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+}
+
+#endif
diff --git a/include/ndnboost/functional/hash/hash.hpp b/include/ndnboost/functional/hash/hash.hpp
new file mode 100644
index 0000000..7428567
--- /dev/null
+++ b/include/ndnboost/functional/hash/hash.hpp
@@ -0,0 +1,530 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+//  Based on Peter Dimov's proposal
+//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+//  issue 6.18. 
+
+#if !defined(NDNBOOST_FUNCTIONAL_HASH_HASH_HPP)
+#define NDNBOOST_FUNCTIONAL_HASH_HASH_HPP
+
+#include <ndnboost/functional/hash/hash_fwd.hpp>
+#include <functional>
+#include <ndnboost/functional/hash/detail/hash_float.hpp>
+#include <string>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/type_traits/is_enum.hpp>
+#include <ndnboost/type_traits/is_integral.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+
+#if defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#include <ndnboost/type_traits/is_pointer.hpp>
+#endif
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_TYPEINDEX)
+#include <typeindex>
+#endif
+
+#if NDNBOOST_WORKAROUND(__GNUC__, < 3) \
+    && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
+#define NDNBOOST_HASH_CHAR_TRAITS string_char_traits
+#else
+#define NDNBOOST_HASH_CHAR_TRAITS char_traits
+#endif
+
+namespace ndnboost
+{
+    namespace hash_detail
+    {
+        struct enable_hash_value { typedef std::size_t type; };
+
+        template <typename T> struct basic_numbers {};
+        template <typename T> struct long_numbers;
+        template <typename T> struct ulong_numbers;
+        template <typename T> struct float_numbers {};
+
+        template <> struct basic_numbers<bool> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<char> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<unsigned char> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<signed char> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<short> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<unsigned short> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<int> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<unsigned int> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<long> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct basic_numbers<unsigned long> :
+            ndnboost::hash_detail::enable_hash_value {};
+
+#if !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
+        template <> struct basic_numbers<wchar_t> :
+            ndnboost::hash_detail::enable_hash_value {};
+#endif
+
+        // long_numbers is defined like this to allow for separate
+        // specialization for long_long and int128_type, in case
+        // they conflict.
+        template <typename T> struct long_numbers2 {};
+        template <typename T> struct ulong_numbers2 {};
+        template <typename T> struct long_numbers : long_numbers2<T> {};
+        template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
+
+#if !defined(NDNBOOST_NO_LONG_LONG)
+        template <> struct long_numbers<ndnboost::long_long_type> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct ulong_numbers<ndnboost::ulong_long_type> :
+            ndnboost::hash_detail::enable_hash_value {};
+#endif
+
+#if defined(NDNBOOST_HAS_INT128)
+        template <> struct long_numbers2<ndnboost::int128_type> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct ulong_numbers2<ndnboost::uint128_type> :
+            ndnboost::hash_detail::enable_hash_value {};
+#endif
+
+        template <> struct float_numbers<float> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct float_numbers<double> :
+            ndnboost::hash_detail::enable_hash_value {};
+        template <> struct float_numbers<long double> :
+            ndnboost::hash_detail::enable_hash_value {};
+    }
+
+    template <typename T>
+    typename ndnboost::hash_detail::basic_numbers<T>::type hash_value(T);
+    template <typename T>
+    typename ndnboost::hash_detail::long_numbers<T>::type hash_value(T);
+    template <typename T>
+    typename ndnboost::hash_detail::ulong_numbers<T>::type hash_value(T);
+
+    template <typename T>
+    typename ndnboost::enable_if<ndnboost::is_enum<T>, std::size_t>::type
+        hash_value(T);
+
+#if !NDNBOOST_WORKAROUND(__DMC__, <= 0x848)
+    template <class T> std::size_t hash_value(T* const&);
+#else
+    template <class T> std::size_t hash_value(T*);
+#endif
+
+#if !defined(NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+    template< class T, unsigned N >
+    std::size_t hash_value(const T (&x)[N]);
+
+    template< class T, unsigned N >
+    std::size_t hash_value(T (&x)[N]);
+#endif
+
+    template <class Ch, class A>
+    std::size_t hash_value(
+        std::basic_string<Ch, std::NDNBOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
+
+    template <typename T>
+    typename ndnboost::hash_detail::float_numbers<T>::type hash_value(T);
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_TYPEINDEX)
+    std::size_t hash_value(std::type_index);
+#endif
+
+    // Implementation
+
+    namespace hash_detail
+    {
+        template <class T>
+        inline std::size_t hash_value_signed(T val)
+        {
+             const int size_t_bits = std::numeric_limits<std::size_t>::digits;
+             // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
+             const int length = (std::numeric_limits<T>::digits - 1)
+                 / size_t_bits;
+
+             std::size_t seed = 0;
+             T positive = val < 0 ? -1 - val : val;
+
+             // Hopefully, this loop can be unrolled.
+             for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
+             {
+                 seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
+             }
+             seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
+
+             return seed;
+        }
+
+        template <class T>
+        inline std::size_t hash_value_unsigned(T val)
+        {
+             const int size_t_bits = std::numeric_limits<std::size_t>::digits;
+             // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
+             const int length = (std::numeric_limits<T>::digits - 1)
+                 / size_t_bits;
+
+             std::size_t seed = 0;
+
+             // Hopefully, this loop can be unrolled.
+             for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
+             {
+                 seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
+             }
+             seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
+
+             return seed;
+        }
+    }
+
+    template <typename T>
+    typename ndnboost::hash_detail::basic_numbers<T>::type hash_value(T v)
+    {
+        return static_cast<std::size_t>(v);
+    }
+
+    template <typename T>
+    typename ndnboost::hash_detail::long_numbers<T>::type hash_value(T v)
+    {
+        return hash_detail::hash_value_signed(v);
+    }
+
+    template <typename T>
+    typename ndnboost::hash_detail::ulong_numbers<T>::type hash_value(T v)
+    {
+        return hash_detail::hash_value_unsigned(v);
+    }
+
+    template <typename T>
+    typename ndnboost::enable_if<ndnboost::is_enum<T>, std::size_t>::type
+        hash_value(T v)
+    {
+        return static_cast<std::size_t>(v);
+    }
+
+    // Implementation by Alberto Barbati and Dave Harris.
+#if !NDNBOOST_WORKAROUND(__DMC__, <= 0x848)
+    template <class T> std::size_t hash_value(T* const& v)
+#else
+    template <class T> std::size_t hash_value(T* v)
+#endif
+    {
+#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
+    // for some reason ptrdiff_t on OpenVMS compiler with
+    // 64 bit is not 64 bit !!!
+        std::size_t x = static_cast<std::size_t>(
+           reinterpret_cast<long long int>(v));
+#else
+        std::size_t x = static_cast<std::size_t>(
+           reinterpret_cast<std::ptrdiff_t>(v));
+#endif
+        return x + (x >> 3);
+    }
+
+#if defined(NDNBOOST_MSVC)
+#pragma warning(push)
+#if NDNBOOST_MSVC <= 1400
+#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
+                              // 'unsigned int', possible loss of data
+                              // A misguided attempt to detect 64-bit
+                              // incompatability.
+#endif
+#endif
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+    template <class T>
+    inline void hash_combine(std::size_t& seed, T& v)
+#else
+    template <class T>
+    inline void hash_combine(std::size_t& seed, T const& v)
+#endif
+    {
+        ndnboost::hash<T> hasher;
+        seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+    }
+
+#if defined(NDNBOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+    template <class It>
+    inline std::size_t hash_range(It first, It last)
+    {
+        std::size_t seed = 0;
+
+        for(; first != last; ++first)
+        {
+            hash_combine(seed, *first);
+        }
+
+        return seed;
+    }
+
+    template <class It>
+    inline void hash_range(std::size_t& seed, It first, It last)
+    {
+        for(; first != last; ++first)
+        {
+            hash_combine(seed, *first);
+        }
+    }
+
+#if NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x551))
+    template <class T>
+    inline std::size_t hash_range(T* first, T* last)
+    {
+        std::size_t seed = 0;
+
+        for(; first != last; ++first)
+        {
+            ndnboost::hash<T> hasher;
+            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+        }
+
+        return seed;
+    }
+
+    template <class T>
+    inline void hash_range(std::size_t& seed, T* first, T* last)
+    {
+        for(; first != last; ++first)
+        {
+            ndnboost::hash<T> hasher;
+            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+        }
+    }
+#endif
+
+#if !defined(NDNBOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+    template< class T, unsigned N >
+    inline std::size_t hash_value(const T (&x)[N])
+    {
+        return hash_range(x, x + N);
+    }
+
+    template< class T, unsigned N >
+    inline std::size_t hash_value(T (&x)[N])
+    {
+        return hash_range(x, x + N);
+    }
+#endif
+
+    template <class Ch, class A>
+    inline std::size_t hash_value(
+        std::basic_string<Ch, std::NDNBOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
+    {
+        return hash_range(v.begin(), v.end());
+    }
+
+    template <typename T>
+    typename ndnboost::hash_detail::float_numbers<T>::type hash_value(T v)
+    {
+        return ndnboost::hash_detail::float_hash_value(v);
+    }
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_TYPEINDEX)
+    inline std::size_t hash_value(std::type_index v)
+    {
+        return v.hash_code();
+    }
+#endif
+
+    //
+    // ndnboost::hash
+    //
+    
+    // Define the specializations required by the standard. The general purpose
+    // ndnboost::hash is defined later in extensions.hpp if
+    // NDNBOOST_HASH_NO_EXTENSIONS is not defined.
+    
+    // NDNBOOST_HASH_SPECIALIZE - define a specialization for a type which is
+    // passed by copy.
+    //
+    // NDNBOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
+    // passed by copy.
+    //
+    // These are undefined later.
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+#define NDNBOOST_HASH_SPECIALIZE(type) \
+    template <> struct hash<type> \
+         : public std::unary_function<type, std::size_t> \
+    { \
+        std::size_t operator()(type v) const \
+        { \
+            return ndnboost::hash_value(v); \
+        } \
+    };
+
+#define NDNBOOST_HASH_SPECIALIZE_REF(type) \
+    template <> struct hash<type> \
+         : public std::unary_function<type, std::size_t> \
+    { \
+        std::size_t operator()(type const& v) const \
+        { \
+            return ndnboost::hash_value(v); \
+        } \
+    };
+#else
+#define NDNBOOST_HASH_SPECIALIZE(type) \
+    template <> struct hash<type> \
+         : public std::unary_function<type, std::size_t> \
+    { \
+        std::size_t operator()(type v) const \
+        { \
+            return ndnboost::hash_value(v); \
+        } \
+    }; \
+    \
+    template <> struct hash<const type> \
+         : public std::unary_function<const type, std::size_t> \
+    { \
+        std::size_t operator()(const type v) const \
+        { \
+            return ndnboost::hash_value(v); \
+        } \
+    };
+
+#define NDNBOOST_HASH_SPECIALIZE_REF(type) \
+    template <> struct hash<type> \
+         : public std::unary_function<type, std::size_t> \
+    { \
+        std::size_t operator()(type const& v) const \
+        { \
+            return ndnboost::hash_value(v); \
+        } \
+    }; \
+    \
+    template <> struct hash<const type> \
+         : public std::unary_function<const type, std::size_t> \
+    { \
+        std::size_t operator()(type const& v) const \
+        { \
+            return ndnboost::hash_value(v); \
+        } \
+    };
+#endif
+
+    NDNBOOST_HASH_SPECIALIZE(bool)
+    NDNBOOST_HASH_SPECIALIZE(char)
+    NDNBOOST_HASH_SPECIALIZE(signed char)
+    NDNBOOST_HASH_SPECIALIZE(unsigned char)
+#if !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
+    NDNBOOST_HASH_SPECIALIZE(wchar_t)
+#endif
+    NDNBOOST_HASH_SPECIALIZE(short)
+    NDNBOOST_HASH_SPECIALIZE(unsigned short)
+    NDNBOOST_HASH_SPECIALIZE(int)
+    NDNBOOST_HASH_SPECIALIZE(unsigned int)
+    NDNBOOST_HASH_SPECIALIZE(long)
+    NDNBOOST_HASH_SPECIALIZE(unsigned long)
+
+    NDNBOOST_HASH_SPECIALIZE(float)
+    NDNBOOST_HASH_SPECIALIZE(double)
+    NDNBOOST_HASH_SPECIALIZE(long double)
+
+    NDNBOOST_HASH_SPECIALIZE_REF(std::string)
+#if !defined(NDNBOOST_NO_STD_WSTRING)
+    NDNBOOST_HASH_SPECIALIZE_REF(std::wstring)
+#endif
+
+#if !defined(NDNBOOST_NO_LONG_LONG)
+    NDNBOOST_HASH_SPECIALIZE(ndnboost::long_long_type)
+    NDNBOOST_HASH_SPECIALIZE(ndnboost::ulong_long_type)
+#endif
+
+#if defined(NDNBOOST_HAS_INT128)
+    NDNBOOST_HASH_SPECIALIZE(ndnboost::int128_type)
+    NDNBOOST_HASH_SPECIALIZE(ndnboost::uint128_type)
+#endif
+
+#if !defined(NDNBOOST_NO_CXX11_HDR_TYPEINDEX)
+    NDNBOOST_HASH_SPECIALIZE(std::type_index)
+#endif
+
+#undef NDNBOOST_HASH_SPECIALIZE
+#undef NDNBOOST_HASH_SPECIALIZE_REF
+
+// Specializing ndnboost::hash for pointers.
+
+#if !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+    template <class T>
+    struct hash<T*>
+        : public std::unary_function<T*, std::size_t>
+    {
+        std::size_t operator()(T* v) const
+        {
+#if !NDNBOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
+            return ndnboost::hash_value(v);
+#else
+            std::size_t x = static_cast<std::size_t>(
+                reinterpret_cast<std::ptrdiff_t>(v));
+
+            return x + (x >> 3);
+#endif
+        }
+    };
+
+#else
+
+    // For compilers without partial specialization, we define a
+    // ndnboost::hash for all remaining types. But hash_impl is only defined
+    // for pointers in 'extensions.hpp' - so when NDNBOOST_HASH_NO_EXTENSIONS
+    // is defined there will still be a compile error for types not supported
+    // in the standard.
+
+    namespace hash_detail
+    {
+        template <bool IsPointer>
+        struct hash_impl;
+
+        template <>
+        struct hash_impl<true>
+        {
+            template <class T>
+            struct inner
+                : public std::unary_function<T, std::size_t>
+            {
+                std::size_t operator()(T val) const
+                {
+#if !NDNBOOST_WORKAROUND(__SUNPRO_CC, <= 590)
+                    return ndnboost::hash_value(val);
+#else
+                    std::size_t x = static_cast<std::size_t>(
+                        reinterpret_cast<std::ptrdiff_t>(val));
+
+                    return x + (x >> 3);
+#endif
+                }
+            };
+        };
+    }
+
+    template <class T> struct hash
+        : public ndnboost::hash_detail::hash_impl<ndnboost::is_pointer<T>::value>
+            ::NDNBOOST_NESTED_TEMPLATE inner<T>
+    {
+    };
+
+#endif
+}
+
+#undef NDNBOOST_HASH_CHAR_TRAITS
+
+#endif // NDNBOOST_FUNCTIONAL_HASH_HASH_HPP
+
+// Include this outside of the include guards in case the file is included
+// twice - once with NDNBOOST_HASH_NO_EXTENSIONS defined, and then with it
+// undefined.
+
+#if !defined(NDNBOOST_HASH_NO_EXTENSIONS) \
+    && !defined(NDNBOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
+#include <ndnboost/functional/hash/extensions.hpp>
+#endif
diff --git a/include/ndnboost/integer/integer_mask.hpp b/include/ndnboost/integer/integer_mask.hpp
new file mode 100644
index 0000000..9583ea6
--- /dev/null
+++ b/include/ndnboost/integer/integer_mask.hpp
@@ -0,0 +1,126 @@
+//  Boost integer/integer_mask.hpp header file  ------------------------------//
+
+//  (C) Copyright Daryle Walker 2001.
+//  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)
+
+//  See http://www.boost.org for updates, documentation, and revision history. 
+
+#ifndef NDNBOOST_INTEGER_INTEGER_MASK_HPP
+#define NDNBOOST_INTEGER_INTEGER_MASK_HPP
+
+#include <ndnboost/integer_fwd.hpp>  // self include
+
+#include <ndnboost/config.hpp>   // for NDNBOOST_STATIC_CONSTANT
+#include <ndnboost/integer.hpp>  // for ndnboost::uint_t
+
+#include <climits>  // for UCHAR_MAX, etc.
+#include <cstddef>  // for std::size_t
+
+#include <ndnboost/limits.hpp>  // for std::numeric_limits
+
+//
+// We simply cannot include this header on gcc without getting copious warnings of the kind:
+//
+// ndnboost/integer/integer_mask.hpp:93:35: warning: use of C99 long long integer constant
+//
+// And yet there is no other reasonable implementation, so we declare this a system header
+// to suppress these warnings.
+//
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#pragma GCC system_header
+#endif
+
+namespace ndnboost
+{
+
+
+//  Specified single-bit mask class declaration  -----------------------------//
+//  (Lowest bit starts counting at 0.)
+
+template < std::size_t Bit >
+struct high_bit_mask_t
+{
+    typedef typename uint_t<(Bit + 1)>::least  least;
+    typedef typename uint_t<(Bit + 1)>::fast   fast;
+
+    NDNBOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << Bit) );
+    NDNBOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << Bit) );
+
+    NDNBOOST_STATIC_CONSTANT( std::size_t, bit_position = Bit );
+
+};  // ndnboost::high_bit_mask_t
+
+
+//  Specified bit-block mask class declaration  ------------------------------//
+//  Makes masks for the lowest N bits
+//  (Specializations are needed when N fills up a type.)
+
+template < std::size_t Bits >
+struct low_bits_mask_t
+{
+    typedef typename uint_t<Bits>::least  least;
+    typedef typename uint_t<Bits>::fast   fast;
+
+    NDNBOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
+    NDNBOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
+
+    NDNBOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
+
+};  // ndnboost::low_bits_mask_t
+
+
+#define NDNBOOST_LOW_BITS_MASK_SPECIALIZE( Type )                                  \
+  template <  >  struct low_bits_mask_t< std::numeric_limits<Type>::digits >  { \
+      typedef std::numeric_limits<Type>           limits_type;                  \
+      typedef uint_t<limits_type::digits>::least  least;                        \
+      typedef uint_t<limits_type::digits>::fast   fast;                         \
+      NDNBOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );              \
+      NDNBOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );            \
+      NDNBOOST_STATIC_CONSTANT( std::size_t, bit_count = limits_type::digits );    \
+  }
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4245)  // 'initializing' : conversion from 'int' to 'const ndnboost::low_bits_mask_t<8>::least', signed/unsigned mismatch
+#endif
+
+NDNBOOST_LOW_BITS_MASK_SPECIALIZE( unsigned char );
+
+#if USHRT_MAX > UCHAR_MAX
+NDNBOOST_LOW_BITS_MASK_SPECIALIZE( unsigned short );
+#endif
+
+#if UINT_MAX > USHRT_MAX
+NDNBOOST_LOW_BITS_MASK_SPECIALIZE( unsigned int );
+#endif
+
+#if ULONG_MAX > UINT_MAX
+NDNBOOST_LOW_BITS_MASK_SPECIALIZE( unsigned long );
+#endif
+
+#if defined(NDNBOOST_HAS_LONG_LONG)
+    #if ((defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)) ||\
+        (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX > ULONG_MAX)) ||\
+        (defined(ULONGLONG_MAX) && (ULONGLONG_MAX > ULONG_MAX)) ||\
+        (defined(_ULLONG_MAX) && (_ULLONG_MAX > ULONG_MAX)))
+    NDNBOOST_LOW_BITS_MASK_SPECIALIZE( ndnboost::ulong_long_type );
+    #endif
+#elif defined(NDNBOOST_HAS_MS_INT64)
+    #if 18446744073709551615ui64 > ULONG_MAX
+    NDNBOOST_LOW_BITS_MASK_SPECIALIZE( unsigned __int64 );
+    #endif
+#endif
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#undef NDNBOOST_LOW_BITS_MASK_SPECIALIZE
+
+
+}  // namespace ndnboost
+
+
+#endif  // NDNBOOST_INTEGER_INTEGER_MASK_HPP
diff --git a/include/ndnboost/io/detail/quoted_manip.hpp b/include/ndnboost/io/detail/quoted_manip.hpp
new file mode 100644
index 0000000..5279096
--- /dev/null
+++ b/include/ndnboost/io/detail/quoted_manip.hpp
@@ -0,0 +1,190 @@
+//  ndnboost/io/quoted_manip.hpp  ---------------------------------------------------------//
+
+//  Copyright Beman Dawes 2010
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  Library home page http://www.boost.org/libs/io
+
+//--------------------------------------------------------------------------------------// 
+
+#ifndef NDNBOOST_IO_QUOTED_MANIP
+#define NDNBOOST_IO_QUOTED_MANIP
+
+#include <iosfwd>
+#include <ios>
+#include <string>
+#include <iterator>
+#include <ndnboost/io/ios_state.hpp>
+
+namespace ndnboost
+{
+  namespace io
+  {
+    namespace detail { template <class String, class Char> struct quoted_proxy; }
+
+    //  ------------  public interface  ------------------------------------------------//
+
+    //  manipulator for const std::basic_string&
+    template <class Char, class Traits, class Alloc>
+      detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
+        quoted(const std::basic_string<Char, Traits, Alloc>& s,
+               Char escape='\\', Char delim='\"');
+
+    //  manipulator for non-const std::basic_string&
+    template <class Char, class Traits, class Alloc>
+      detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
+        quoted(std::basic_string<Char, Traits, Alloc>& s,
+               Char escape='\\', Char delim='\"');
+
+    //  manipulator for const C-string*
+    template <class Char>
+      detail::quoted_proxy<const Char*, Char>
+        quoted(const Char* s, Char escape='\\', Char delim='\"');
+
+    //  -----------  implementation details  -------------------------------------------//
+
+    namespace detail
+    {
+      //  proxy used as an argument pack 
+      template <class String, class Char>
+      struct quoted_proxy
+      {
+        String  string;
+        Char    escape;
+        Char    delim;
+
+        quoted_proxy(String s_, Char escape_, Char delim_)
+          : string(s_), escape(escape_), delim(delim_) {}
+      private:
+        // String may be a const type, so disable the assignment operator
+        quoted_proxy& operator=(const quoted_proxy&);  // = deleted
+      };
+
+      //  abstract away difference between proxies with const or non-const basic_strings
+      template <class Char, class Traits, class Alloc>
+      std::basic_ostream<Char, Traits>&
+      basic_string_inserter_imp(std::basic_ostream<Char, Traits>& os,
+        std::basic_string<Char, Traits, Alloc> const & string, Char escape, Char delim)
+      {
+        os << delim;
+        typename std::basic_string<Char, Traits, Alloc>::const_iterator
+          end_it = string.end();
+        for (typename std::basic_string<Char, Traits, Alloc>::const_iterator
+          it = string.begin();
+          it != end_it;
+          ++it )
+        {
+          if (*it == delim || *it == escape)
+            os << escape;
+          os << *it;
+        }
+        os << delim;
+        return os;
+      }
+
+      //  inserter for const std::basic_string& proxies
+      template <class Char, class Traits, class Alloc>
+      inline
+      std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, 
+        const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy)
+      {
+        return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
+      }
+
+      //  inserter for non-const std::basic_string& proxies
+      template <class Char, class Traits, class Alloc>
+      inline
+      std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, 
+        const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
+      {
+        return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
+      }
+ 
+      //  inserter for const C-string* proxies
+      template <class Char, class Traits>
+      std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, 
+        const quoted_proxy<const Char*, Char>& proxy)
+      {
+        os << proxy.delim;
+        for (const Char* it = proxy.string;
+          *it;
+          ++it )
+        {
+          if (*it == proxy.delim || *it == proxy.escape)
+            os << proxy.escape;
+          os << *it;
+        }
+        os << proxy.delim;
+        return os;
+      }
+
+      //  extractor for non-const std::basic_string& proxies
+      template <class Char, class Traits, class Alloc>
+      std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is, 
+        const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
+      {
+        proxy.string.clear();
+        Char c;
+        is >> c;
+        if (c != proxy.delim)
+        {
+          is.unget();
+          is >> proxy.string;
+          return is;
+        }
+        {
+          ndnboost::io::ios_flags_saver ifs(is);
+          is >> std::noskipws;
+          for (;;)  
+          {
+            is >> c;
+            if (!is.good())  // cope with I/O errors or end-of-file
+              break;
+            if (c == proxy.escape)
+            {
+              is >> c;
+              if (!is.good())  // cope with I/O errors or end-of-file
+                break;
+            }
+            else if (c == proxy.delim)
+              break;
+            proxy.string += c;
+          }
+        }
+        return is;
+      }
+
+    }  // namespace detail
+
+    //  manipulator implementation for const std::basic_string&
+    template <class Char, class Traits, class Alloc>
+    inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
+    quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
+    {
+      return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
+        (s, escape, delim);
+    }
+
+    //  manipulator implementation for non-const std::basic_string&
+    template <class Char, class Traits, class Alloc>
+    inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
+    quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
+    {
+      return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>
+        (s, escape, delim);
+    }
+
+    //  manipulator implementation for const C-string*
+    template <class Char>
+    inline detail::quoted_proxy<const Char*, Char>
+    quoted(const Char* s, Char escape, Char delim)
+    {
+      return detail::quoted_proxy<const Char*, Char> (s, escape, delim);
+    }
+
+  }  // namespace io
+}  // namespace ndnboost
+
+#endif // NDNBOOST_IO_QUOTED_MANIP
diff --git a/include/ndnboost/iostreams/categories.hpp b/include/ndnboost/iostreams/categories.hpp
new file mode 100644
index 0000000..b5a4255
--- /dev/null
+++ b/include/ndnboost/iostreams/categories.hpp
@@ -0,0 +1,175 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains category and mode tags for classifying filters, devices and 
+// standard stream and stream buffers types.
+
+#ifndef NDNBOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED 
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+namespace ndnboost { namespace iostreams {
+
+//------------------Tags for dispatch according to i/o mode-------------------//
+
+struct any_tag { };
+namespace detail { struct two_sequence : virtual any_tag { }; }
+namespace detail { struct random_access : virtual any_tag { }; }
+namespace detail { struct one_head : virtual any_tag { }; }
+namespace detail { struct two_head : virtual any_tag { }; }
+struct input : virtual any_tag { };
+struct output : virtual any_tag { };
+struct bidirectional : virtual input, virtual output, detail::two_sequence { };
+struct dual_use : virtual input, virtual output { }; // Pseudo-mode.
+struct input_seekable : virtual input, virtual detail::random_access { };
+struct output_seekable : virtual output, virtual detail::random_access { };
+struct seekable
+    : virtual input_seekable, 
+      virtual output_seekable,
+      detail::one_head
+    { };
+struct dual_seekable
+    : virtual input_seekable,
+      virtual output_seekable,
+      detail::two_head
+    { };  
+struct bidirectional_seekable
+    : input_seekable, output_seekable,
+      bidirectional, detail::two_head
+    { };
+
+//------------------Tags for use as i/o categories----------------------------//
+
+struct device_tag : virtual any_tag { };
+struct filter_tag : virtual any_tag { };
+
+    // 
+    // Tags for optional behavior.
+    //
+
+struct peekable_tag : virtual any_tag { };        // Devices.
+struct closable_tag : virtual any_tag { };
+struct flushable_tag : virtual any_tag { };
+struct localizable_tag : virtual any_tag { };
+struct optimally_buffered_tag : virtual any_tag { };
+struct direct_tag : virtual any_tag { };          // Devices.
+struct multichar_tag : virtual any_tag { };       // Filters.
+
+struct source_tag : device_tag, input { };
+struct sink_tag : device_tag, output { };
+struct bidirectional_device_tag : device_tag, bidirectional { };
+struct seekable_device_tag : virtual device_tag, seekable { };
+
+struct input_filter_tag : filter_tag, input { };
+struct output_filter_tag : filter_tag, output { };
+struct bidirectional_filter_tag : filter_tag, bidirectional { };
+struct seekable_filter_tag : filter_tag, seekable { };
+struct dual_use_filter_tag : filter_tag, dual_use { };
+
+struct multichar_input_filter_tag
+    : multichar_tag,
+      input_filter_tag
+    { };
+struct multichar_output_filter_tag
+    : multichar_tag,
+      output_filter_tag
+    { };
+struct multichar_bidirectional_filter_tag
+    : multichar_tag,
+      bidirectional_filter_tag
+    { };
+struct multichar_seekable_filter_tag
+    : multichar_tag,
+      seekable_filter_tag
+    { };
+struct multichar_dual_use_filter_tag 
+    : multichar_tag, 
+      dual_use_filter_tag
+    { };
+
+    //
+    // Tags for standard streams and streambufs.
+    //
+
+struct std_io_tag : virtual localizable_tag { };
+struct istream_tag
+    : virtual device_tag,
+      virtual peekable_tag,
+      virtual std_io_tag
+    { };
+struct ostream_tag
+    : virtual device_tag,
+      virtual std_io_tag
+    { };
+struct iostream_tag
+    : istream_tag,
+      ostream_tag
+    { };
+struct streambuf_tag
+    : device_tag,
+      peekable_tag,
+      std_io_tag
+    { };
+struct ifstream_tag
+    : input_seekable,
+      closable_tag,
+      istream_tag
+    { };
+struct ofstream_tag
+    : output_seekable,
+      closable_tag,
+      ostream_tag
+    { };
+struct fstream_tag
+    : seekable,
+      closable_tag,
+      iostream_tag
+    { };
+struct filebuf_tag
+    : seekable,
+      closable_tag,
+      streambuf_tag
+    { };
+struct istringstream_tag
+    : input_seekable,
+      istream_tag
+    { };
+struct ostringstream_tag
+    : output_seekable,
+      ostream_tag
+    { };
+struct stringstream_tag
+    : dual_seekable,
+      iostream_tag
+    { };
+struct stringbuf_tag
+    : dual_seekable,
+      streambuf_tag
+    { };
+struct generic_istream_tag 
+    : input_seekable,
+      istream_tag
+    { };
+struct generic_ostream_tag 
+    : output_seekable,
+      ostream_tag
+    { };
+struct generic_iostream_tag 
+    : seekable,
+      iostream_tag
+    { };
+struct generic_streambuf_tag 
+    : seekable,
+      streambuf_tag
+    { };
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/chain.hpp b/include/ndnboost/iostreams/chain.hpp
new file mode 100644
index 0000000..b0fac48
--- /dev/null
+++ b/include/ndnboost/iostreams/chain.hpp
@@ -0,0 +1,598 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/assert.hpp>
+#include <exception>
+#include <functional>                           // unary_function.
+#include <iterator>                             // advance.
+#include <list>
+#include <memory>                               // allocator, auto_ptr.
+#include <typeinfo>
+#include <stdexcept>                            // logic_error, out_of_range.
+#include <ndnboost/checked_delete.hpp>
+#include <ndnboost/config.hpp>                     // NDNBOOST_MSVC, template friends,
+#include <ndnboost/detail/workaround.hpp>          // NDNBOOST_NESTED_TEMPLATE 
+#include <ndnboost/iostreams/constants.hpp>
+#include <ndnboost/iostreams/detail/access_control.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/push.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp> // pubsync.
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/device/null.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/iostreams/traits.hpp>           // is_filter.
+#include <ndnboost/iostreams/stream_buffer.hpp>
+#include <ndnboost/next_prior.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type.hpp>
+#include <ndnboost/iostreams/detail/execute.hpp>   // VC6.5 requires this
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)        // #include order
+# include <ndnboost/mpl/int.hpp>
+#endif
+
+// Sometimes type_info objects must be compared by name. Borrowed from
+// Boost.Python and Boost.Function.
+#if (defined(__GNUC__) && __GNUC__ >= 3) || \
+     defined(_AIX) || \
+    (defined(__sgi) && defined(__host_mips)) || \
+    (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) \
+    /**/
+# include <cstring>
+# define NDNBOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) \
+     (std::strcmp((X).name(),(Y).name()) == 0)
+#else
+# define NDNBOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
+#endif
+
+// Deprecated
+#define NDNBOOST_IOSTREAMS_COMPONENT_TYPE(chain, index) \
+    chain.component_type( index ) \
+    /**/
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)
+# define NDNBOOST_IOSTREAMS_COMPONENT(chain, index, target) \
+    chain.component< target >( index ) \
+    /**/
+#else
+# define NDNBOOST_IOSTREAMS_COMPONENT(chain, index, target) \
+    chain.component( index, ::ndnboost::type< target >() ) \
+    /**/
+#endif
+
+namespace ndnboost { namespace iostreams {
+
+//--------------Definition of chain and wchain--------------------------------//
+
+namespace detail {
+
+template<typename Chain> class chain_client;
+
+//
+// Concept name: Chain.
+// Description: Represents a chain of stream buffers which provides access
+//     to the first buffer in the chain and sends notifications when the
+//     streambufs are added to or removed from chain.
+// Refines: Closable device with mode equal to typename Chain::mode.
+// Models: chain, converting_chain.
+// Example:
+//
+//    class chain {
+//    public:
+//        typedef xxx chain_type;
+//        typedef xxx client_type;
+//        typedef xxx mode;
+//        bool is_complete() const;                  // Ready for i/o.
+//        template<typename T>
+//        void push( const T& t,                     // Adds a stream buffer to
+//                   streamsize,                     // chain, based on t, with
+//                   streamsize );                   // given buffer and putback
+//                                                   // buffer sizes. Pass -1 to
+//                                                   // request default size.
+//    protected:
+//        void register_client(client_type* client); // Associate client.
+//        void notify();                             // Notify client.
+//    };
+//
+
+//
+// Description: Represents a chain of filters with an optional device at the
+//      end.
+// Template parameters:
+//      Self - A class deriving from the current instantiation of this template.
+//          This is an example of the Curiously Recurring Template Pattern.
+//      Ch - The character type.
+//      Tr - The character traits type.
+//      Alloc - The allocator type.
+//      Mode - A mode tag.
+//
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+class chain_base {
+public:
+    typedef Ch                                     char_type;
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+    typedef Alloc                                  allocator_type;
+    typedef Mode                                   mode;
+    struct category
+        : Mode,
+          device_tag
+        { };
+    typedef chain_client<Self>                     client_type;
+    friend class chain_client<Self>;
+private:
+    typedef linked_streambuf<Ch>                   streambuf_type;
+    typedef std::list<streambuf_type*>             list_type;
+    typedef chain_base<Self, Ch, Tr, Alloc, Mode>  my_type;
+protected:
+    chain_base() : pimpl_(new chain_impl) { }
+    chain_base(const chain_base& rhs): pimpl_(rhs.pimpl_) { }
+public:
+
+    // dual_use is a pseudo-mode to facilitate filter writing, 
+    // not a genuine mode.
+    NDNBOOST_STATIC_ASSERT((!is_convertible<mode, dual_use>::value));
+
+    //----------Buffer sizing-------------------------------------------------//
+
+    // Sets the size of the buffer created for the devices to be added to this
+    // chain. Does not affect the size of the buffer for devices already
+    // added.
+    void set_device_buffer_size(std::streamsize n) 
+        { pimpl_->device_buffer_size_ = n; }
+
+    // Sets the size of the buffer created for the filters to be added
+    // to this chain. Does not affect the size of the buffer for filters already
+    // added.
+    void set_filter_buffer_size(std::streamsize n) 
+        { pimpl_->filter_buffer_size_ = n; }
+
+    // Sets the size of the putback buffer for filters and devices to be added
+    // to this chain. Does not affect the size of the buffer for filters or
+    // devices already added.
+    void set_pback_size(std::streamsize n) 
+        { pimpl_->pback_size_ = n; }
+
+    //----------Device interface----------------------------------------------//
+
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek(stream_offset off, NDNBOOST_IOS::seekdir way);
+
+    //----------Direct component access---------------------------------------//
+
+    const std::type_info& component_type(int n) const
+    {
+        if (static_cast<size_type>(n) >= size())
+            ndnboost::throw_exception(std::out_of_range("bad chain offset"));
+        return (*ndnboost::next(list().begin(), n))->component_type();
+    }
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)
+    // Deprecated.
+    template<int N>
+    const std::type_info& component_type() const { return component_type(N); }
+
+    template<typename T>
+    T* component(int n) const { return component(n, ndnboost::type<T>()); }
+
+    // Deprecated.
+    template<int N, typename T> 
+    T* component() const { return component<T>(N); }
+#endif
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)
+    private:
+#endif
+    template<typename T>
+    T* component(int n, ndnboost::type<T>) const
+    {
+        if (static_cast<size_type>(n) >= size())
+            ndnboost::throw_exception(std::out_of_range("bad chain offset"));
+        streambuf_type* link = *ndnboost::next(list().begin(), n);
+        if (NDNBOOST_IOSTREAMS_COMPARE_TYPE_ID(link->component_type(), typeid(T)))
+            return static_cast<T*>(link->component_impl());
+        else
+            return 0;
+    }
+public:
+
+    //----------Container-like interface--------------------------------------//
+
+    typedef typename list_type::size_type size_type;
+    streambuf_type& front() { return *list().front(); }
+    NDNBOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl)
+    void pop();
+    bool empty() const { return list().empty(); }
+    size_type size() const { return list().size(); }
+    void reset();
+
+    //----------Additional i/o functions--------------------------------------//
+
+    // Returns true if this chain is non-empty and its final link
+    // is a source or sink, i.e., if it is ready to perform i/o.
+    bool is_complete() const;
+    bool auto_close() const;
+    void set_auto_close(bool close);
+    bool sync() { return front().NDNBOOST_IOSTREAMS_PUBSYNC() != -1; }
+    bool strict_sync();
+private:
+    template<typename T>
+    void push_impl(const T& t, std::streamsize buffer_size = -1, 
+                   std::streamsize pback_size = -1)
+    {
+        typedef typename iostreams::category_of<T>::type  category;
+        typedef typename unwrap_ios<T>::type              component_type;
+        typedef stream_buffer<
+                    component_type,
+                    NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type),
+                    Alloc, Mode
+                >                                         streambuf_t;
+        typedef typename list_type::iterator              iterator;
+        NDNBOOST_STATIC_ASSERT((is_convertible<category, Mode>::value));
+        if (is_complete())
+            ndnboost::throw_exception(std::logic_error("chain complete"));
+        streambuf_type* prev = !empty() ? list().back() : 0;
+        buffer_size =
+            buffer_size != -1 ?
+                buffer_size :
+                iostreams::optimal_buffer_size(t);
+        pback_size =
+            pback_size != -1 ?
+                pback_size :
+                pimpl_->pback_size_;
+        std::auto_ptr<streambuf_t>
+            buf(new streambuf_t(t, buffer_size, pback_size));
+        list().push_back(buf.get());
+        buf.release();
+        if (is_device<component_type>::value) {
+            pimpl_->flags_ |= f_complete | f_open;
+            for ( iterator first = list().begin(),
+                           last = list().end();
+                  first != last;
+                  ++first )
+            {
+                (*first)->set_needs_close();
+            }
+        }
+        if (prev) prev->set_next(list().back());
+        notify();
+    }
+
+    list_type& list() { return pimpl_->links_; }
+    const list_type& list() const { return pimpl_->links_; }
+    void register_client(client_type* client) { pimpl_->client_ = client; }
+    void notify() { if (pimpl_->client_) pimpl_->client_->notify(); }
+
+    //----------Nested classes------------------------------------------------//
+
+    static void close(streambuf_type* b, NDNBOOST_IOS::openmode m)
+    {
+        if (m == NDNBOOST_IOS::out && is_convertible<Mode, output>::value)
+            b->NDNBOOST_IOSTREAMS_PUBSYNC();
+        b->close(m);
+    }
+
+    static void set_next(streambuf_type* b, streambuf_type* next)
+    { b->set_next(next); }
+
+    static void set_auto_close(streambuf_type* b, bool close)
+    { b->set_auto_close(close); }
+
+    struct closer  : public std::unary_function<streambuf_type*, void>  {
+        closer(NDNBOOST_IOS::openmode m) : mode_(m) { }
+        void operator() (streambuf_type* b)
+        {
+            close(b, mode_);
+        }
+        NDNBOOST_IOS::openmode mode_;
+    };
+    friend struct closer;
+
+    enum flags {
+        f_complete = 1,
+        f_open = 2,
+        f_auto_close = 4
+    };
+
+    struct chain_impl {
+        chain_impl()
+            : client_(0), device_buffer_size_(default_device_buffer_size),
+              filter_buffer_size_(default_filter_buffer_size),
+              pback_size_(default_pback_buffer_size),
+              flags_(f_auto_close)
+            { }
+        ~chain_impl()
+            {
+                try { close(); } catch (...) { }
+                try { reset(); } catch (...) { }
+            }
+        void close()
+            {
+                if ((flags_ & f_open) != 0) {
+                    flags_ &= ~f_open;
+                    stream_buffer< basic_null_device<Ch, Mode> > null;
+                    if ((flags_ & f_complete) == 0) {
+                        null.open(basic_null_device<Ch, Mode>());
+                        set_next(links_.back(), &null);
+                    }
+                    links_.front()->NDNBOOST_IOSTREAMS_PUBSYNC();
+                    try {
+                        ndnboost::iostreams::detail::execute_foreach(
+                            links_.rbegin(), links_.rend(), 
+                            closer(NDNBOOST_IOS::in)
+                        );
+                    } catch (...) {
+                        try {
+                            ndnboost::iostreams::detail::execute_foreach(
+                                links_.begin(), links_.end(), 
+                                closer(NDNBOOST_IOS::out)
+                            );
+                        } catch (...) { }
+                        throw;
+                    }
+                    ndnboost::iostreams::detail::execute_foreach(
+                        links_.begin(), links_.end(), 
+                        closer(NDNBOOST_IOS::out)
+                    );
+                }
+            }
+        void reset()
+            {
+                typedef typename list_type::iterator iterator;
+                for ( iterator first = links_.begin(),
+                               last = links_.end();
+                      first != last;
+                      ++first )
+                {
+                    if ( (flags_ & f_complete) == 0 ||
+                         (flags_ & f_auto_close) == 0 )
+                    {
+                        set_auto_close(*first, false);
+                    }
+                    streambuf_type* buf = 0;
+                    std::swap(buf, *first);
+                    delete buf;
+                }
+                links_.clear();
+                flags_ &= ~f_complete;
+                flags_ &= ~f_open;
+            }
+        list_type        links_;
+        client_type*     client_;
+        std::streamsize  device_buffer_size_,
+                         filter_buffer_size_,
+                         pback_size_;
+        int              flags_;
+    };
+    friend struct chain_impl;
+
+    //----------Member data---------------------------------------------------//
+
+private:
+    shared_ptr<chain_impl> pimpl_;
+};
+
+} // End namespace detail.
+
+//
+// Macro: NDNBOOST_IOSTREAMS_DECL_CHAIN(name, category)
+// Description: Defines a template derived from chain_base appropriate for a
+//      particular i/o category. The template has the following parameters:
+//      Ch - The character type.
+//      Tr - The character traits type.
+//      Alloc - The allocator type.
+// Macro parameters:
+//      name_ - The name of the template to be defined.
+//      category_ - The i/o category of the template to be defined.
+//
+#define NDNBOOST_IOSTREAMS_DECL_CHAIN(name_, default_char_) \
+    template< typename Mode, typename Ch = default_char_, \
+              typename Tr = NDNBOOST_IOSTREAMS_CHAR_TRAITS(Ch), \
+              typename Alloc = std::allocator<Ch> > \
+    class name_ : public ndnboost::iostreams::detail::chain_base< \
+                            name_<Mode, Ch, Tr, Alloc>, \
+                            Ch, Tr, Alloc, Mode \
+                         > \
+    { \
+    public: \
+        struct category : device_tag, Mode { }; \
+        typedef Mode                                   mode; \
+    private: \
+        typedef ndnboost::iostreams::detail::chain_base< \
+                    name_<Mode, Ch, Tr, Alloc>, \
+                    Ch, Tr, Alloc, Mode \
+                >                                      base_type; \
+    public: \
+        typedef Ch                                     char_type; \
+        typedef Tr                                     traits_type; \
+        typedef typename traits_type::int_type         int_type; \
+        typedef typename traits_type::off_type         off_type; \
+        name_() { } \
+        name_(const name_& rhs) : base_type(rhs) { } \
+        name_& operator=(const name_& rhs) \
+        { base_type::operator=(rhs); return *this; } \
+    }; \
+    /**/
+NDNBOOST_IOSTREAMS_DECL_CHAIN(chain, char)
+NDNBOOST_IOSTREAMS_DECL_CHAIN(wchain, wchar_t)
+#undef NDNBOOST_IOSTREAMS_DECL_CHAIN
+
+//--------------Definition of chain_client------------------------------------//
+
+namespace detail {
+
+//
+// Template name: chain_client
+// Description: Class whose instances provide access to an underlying chain
+//      using an interface similar to the chains.
+// Subclasses: the various stream and stream buffer templates.
+//
+template<typename Chain>
+class chain_client {
+public:
+    typedef Chain                             chain_type;
+    typedef typename chain_type::char_type    char_type;
+    typedef typename chain_type::traits_type  traits_type;
+    typedef typename chain_type::size_type    size_type;
+    typedef typename chain_type::mode         mode;
+
+    chain_client(chain_type* chn = 0) : chain_(chn ) { }
+    chain_client(chain_client* client) : chain_(client->chain_) { }
+    virtual ~chain_client() { }
+
+    const std::type_info& component_type(int n) const
+    { return chain_->component_type(n); }
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310)
+    // Deprecated.
+    template<int N>
+    const std::type_info& component_type() const
+    { return chain_->NDNBOOST_NESTED_TEMPLATE component_type<N>(); }
+
+    template<typename T>
+    T* component(int n) const
+    { return chain_->NDNBOOST_NESTED_TEMPLATE component<T>(n); }
+
+    // Deprecated.
+    template<int N, typename T>
+    T* component() const
+    { return chain_->NDNBOOST_NESTED_TEMPLATE component<N, T>(); }
+#else
+    template<typename T>
+    T* component(int n, ndnboost::type<T> t) const
+    { return chain_->component(n, t); }
+#endif
+
+    bool is_complete() const { return chain_->is_complete(); }
+    bool auto_close() const { return chain_->auto_close(); }
+    void set_auto_close(bool close) { chain_->set_auto_close(close); }
+    bool strict_sync() { return chain_->strict_sync(); }
+    void set_device_buffer_size(std::streamsize n)
+        { chain_->set_device_buffer_size(n); }
+    void set_filter_buffer_size(std::streamsize n)
+        { chain_->set_filter_buffer_size(n); }
+    void set_pback_size(std::streamsize n) { chain_->set_pback_size(n); }
+    NDNBOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl)
+    void pop() { chain_->pop(); }
+    bool empty() const { return chain_->empty(); }
+    size_type size() { return chain_->size(); }
+    void reset() { chain_->reset(); }
+
+    // Returns a copy of the underlying chain.
+    chain_type filters() { return *chain_; }
+    chain_type filters() const { return *chain_; }
+protected:
+    template<typename T>
+    void push_impl(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS())
+    { chain_->push(t NDNBOOST_IOSTREAMS_PUSH_ARGS()); }
+    chain_type& ref() { return *chain_; }
+    void set_chain(chain_type* c)
+    { chain_ = c; chain_->register_client(this); }
+#if !defined(NDNBOOST_NO_MEMBER_TEMPLATE_FRIENDS) && \
+    (!NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600))
+    template<typename S, typename C, typename T, typename A, typename M>
+    friend class chain_base;
+#else
+    public:
+#endif
+    virtual void notify() { }
+private:
+    chain_type* chain_;
+};
+
+//--------------Implementation of chain_base----------------------------------//
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+inline std::streamsize chain_base<Self, Ch, Tr, Alloc, Mode>::read
+    (char_type* s, std::streamsize n)
+{ return iostreams::read(*list().front(), s, n); }
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+inline std::streamsize chain_base<Self, Ch, Tr, Alloc, Mode>::write
+    (const char_type* s, std::streamsize n)
+{ return iostreams::write(*list().front(), s, n); }
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+inline std::streampos chain_base<Self, Ch, Tr, Alloc, Mode>::seek
+    (stream_offset off, NDNBOOST_IOS::seekdir way)
+{ return iostreams::seek(*list().front(), off, way); }
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+void chain_base<Self, Ch, Tr, Alloc, Mode>::reset()
+{
+    using namespace std;
+    pimpl_->close();
+    pimpl_->reset();
+}
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+bool chain_base<Self, Ch, Tr, Alloc, Mode>::is_complete() const
+{
+    return (pimpl_->flags_ & f_complete) != 0;
+}
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+bool chain_base<Self, Ch, Tr, Alloc, Mode>::auto_close() const
+{
+    return (pimpl_->flags_ & f_auto_close) != 0;
+}
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+void chain_base<Self, Ch, Tr, Alloc, Mode>::set_auto_close(bool close)
+{
+    pimpl_->flags_ =
+        (pimpl_->flags_ & ~f_auto_close) |
+        (close ? f_auto_close : 0);
+}
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+bool chain_base<Self, Ch, Tr, Alloc, Mode>::strict_sync()
+{
+    typedef typename list_type::iterator iterator;
+    bool result = true;
+    for ( iterator first = list().begin(),
+                   last = list().end();
+          first != last;
+          ++first )
+    {
+        bool s = (*first)->strict_sync();
+        result = result && s;
+    }
+    return result;
+}
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+void chain_base<Self, Ch, Tr, Alloc, Mode>::pop()
+{
+    NDNBOOST_ASSERT(!empty());
+    if (auto_close())
+        pimpl_->close();
+    streambuf_type* buf = 0;
+    std::swap(buf, list().back());
+    buf->set_auto_close(false);
+    buf->set_next(0);
+    delete buf;
+    list().pop_back();
+    pimpl_->flags_ &= ~f_complete;
+    if (auto_close() || list().empty())
+        pimpl_->flags_ &= ~f_open;
+}
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/char_traits.hpp b/include/ndnboost/iostreams/char_traits.hpp
new file mode 100644
index 0000000..97513f2
--- /dev/null
+++ b/include/ndnboost/iostreams/char_traits.hpp
@@ -0,0 +1,73 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif 
+
+#include <ndnboost/config.hpp>
+#include <cstddef>
+#include <cstdio>  // EOF.
+#include <string>  // std::char_traits.
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+# include <cwchar>
+#endif
+
+#ifdef NDNBOOST_NO_STDC_NAMESPACE
+namespace std { using ::wint_t; }
+#endif
+
+namespace ndnboost { namespace iostreams {
+
+// Dinkumware that comes with QNX Momentics 6.3.0, 4.0.2, incorrectly defines
+// the EOF and WEOF macros to not std:: qualify the wint_t type (and so does
+// Sun C++ 5.8 + STLport 4). Fix by placing the def in this scope.
+// NOTE: Use NDNBOOST_WORKAROUND?
+#if (defined(__QNX__) && defined(NDNBOOST_DINKUMWARE_STDLIB))  \
+    || defined(__SUNPRO_CC)
+using ::std::wint_t;
+#endif
+
+const int WOULD_BLOCK = (int) (EOF - 1);
+
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+const std::wint_t WWOULD_BLOCK = (std::wint_t) (WEOF - 1);
+#endif
+
+template<typename Ch>
+struct char_traits;
+
+template<>
+struct char_traits<char> : NDNBOOST_IOSTREAMS_CHAR_TRAITS(char) {
+    static char newline() { return '\n'; }
+    static int good() { return '\n'; }
+    static int would_block() { return WOULD_BLOCK; }
+    static bool is_good(int c) { return c != EOF && c != WOULD_BLOCK; }
+    static bool is_eof(int c) { return c == EOF; }
+    static bool would_block(int c) { return c == WOULD_BLOCK; }
+};
+
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+template<>
+struct char_traits<wchar_t> : std::char_traits<wchar_t> {
+    static wchar_t newline() { return L'\n'; }
+    static std::wint_t good() { return L'\n'; }
+    static std::wint_t would_block() { return WWOULD_BLOCK; }
+    static bool is_good(std::wint_t c) { return c != WEOF && c != WWOULD_BLOCK; }
+    static bool is_eof(std::wint_t c) { return c == WEOF; }
+    static bool would_block(std::wint_t c) { return c == WWOULD_BLOCK; }
+};
+#endif
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/checked_operations.hpp b/include/ndnboost/iostreams/checked_operations.hpp
new file mode 100644
index 0000000..2a27065
--- /dev/null
+++ b/include/ndnboost/iostreams/checked_operations.hpp
@@ -0,0 +1,158 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains implementations of get, read, put, write and seek which
+// check a device's mode at runtime instead of compile time.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
+
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/error.hpp>
+#include <ndnboost/iostreams/detail/config/unreachable_return.hpp>
+#include <ndnboost/iostreams/get.hpp>
+#include <ndnboost/iostreams/put.hpp>
+#include <ndnboost/iostreams/read.hpp>
+#include <ndnboost/iostreams/seek.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/write.hpp>
+#include <ndnboost/throw_exception.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T> 
+struct read_write_if_impl;
+
+template<typename T> 
+struct seek_if_impl;
+
+} // End namespace detail.
+
+template<typename T>
+typename int_type_of<T>::type get_if(T& t)
+{ 
+    typedef typename detail::dispatch<T, input, output>::type tag;
+    return detail::read_write_if_impl<tag>::get(t);
+}
+
+template<typename T>
+inline std::streamsize
+read_if(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+{ 
+    typedef typename detail::dispatch<T, input, output>::type tag;
+    return detail::read_write_if_impl<tag>::read(t, s, n);
+}
+
+template<typename T>
+bool put_if(T& t, typename char_type_of<T>::type c)
+{ 
+    typedef typename detail::dispatch<T, output, input>::type tag;
+    return detail::read_write_if_impl<tag>::put(t, c);
+}
+
+template<typename T>
+inline std::streamsize write_if
+    (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+{ 
+    typedef typename detail::dispatch<T, output, input>::type tag;
+    return detail::read_write_if_impl<tag>::write(t, s, n);
+}
+
+template<typename T>
+inline std::streampos
+seek_if( T& t, stream_offset off, NDNBOOST_IOS::seekdir way, 
+         NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+{ 
+    using namespace detail;
+    typedef typename dispatch<T, random_access, any_tag>::type tag;
+    return seek_if_impl<tag>::seek(t, off, way, which);
+}
+
+namespace detail {
+
+//------------------Specializations of read_write_if_impl---------------------//
+
+template<>
+struct read_write_if_impl<input> {
+    template<typename T>
+    static typename int_type_of<T>::type get(T& t)
+    { return iostreams::get(t); }
+
+    template<typename T>
+    static std::streamsize
+    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+    { return iostreams::read(t, s, n); }
+
+    template<typename T>
+    static bool put(T&, typename char_type_of<T>::type)
+    { ndnboost::throw_exception(cant_write());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(false) }
+
+    template<typename T>
+    static std::streamsize 
+    write(T&, const typename char_type_of<T>::type*, std::streamsize)
+    { ndnboost::throw_exception(cant_write());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+};
+
+template<>
+struct read_write_if_impl<output> {
+    template<typename T>
+    static typename int_type_of<T>::type get(T&)
+    { ndnboost::throw_exception(cant_read());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+
+    template<typename T>
+    static std::streamsize
+    read(T&, typename char_type_of<T>::type*, std::streamsize)
+    { ndnboost::throw_exception(cant_read());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+
+    template<typename T>
+    static bool put(T& t, typename char_type_of<T>::type c)
+    { return iostreams::put(t, c); }
+
+    template<typename T>
+    static std::streamsize 
+    write( T& t, const typename char_type_of<T>::type* s, 
+           std::streamsize n )
+    { return iostreams::write(t, s, n); }
+};
+
+//------------------Specializations of seek_if_impl---------------------------//
+
+template<>
+struct seek_if_impl<random_access> {
+    template<typename T>
+    static std::streampos 
+    seek( T& t, stream_offset off, NDNBOOST_IOS::seekdir way, 
+          NDNBOOST_IOS::openmode which )
+    { return iostreams::seek(t, off, way, which); }
+};
+
+template<>
+struct seek_if_impl<any_tag> {
+    template<typename T>
+    static std::streampos 
+    seek(T&, stream_offset, NDNBOOST_IOS::seekdir, NDNBOOST_IOS::openmode)
+    { ndnboost::throw_exception(cant_seek());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(std::streampos()) }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/close.hpp b/include/ndnboost/iostreams/close.hpp
new file mode 100644
index 0000000..5dde459
--- /dev/null
+++ b/include/ndnboost/iostreams/close.hpp
@@ -0,0 +1,259 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/flush.hpp>
+#include <ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp> // NDNBOOST_IOS
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/identity.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/is_integral.hpp>
+#include <ndnboost/type_traits/remove_cv.hpp>
+#include <ndnboost/type_traits/remove_reference.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template<typename T>
+void close(T& t);
+
+template<typename T>
+void close(T& t, NDNBOOST_IOS::openmode which);
+
+template<typename T, typename Sink>
+void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which);
+    
+namespace detail {
+
+template<typename T>
+void close_all(T& t)
+{ 
+    try {
+        ndnboost::iostreams::close(t, NDNBOOST_IOS::in);
+    } catch (...) {
+        try {
+            ndnboost::iostreams::close(t, NDNBOOST_IOS::out);
+        } catch (...) { }
+        throw;
+    }
+    ndnboost::iostreams::close(t, NDNBOOST_IOS::out);
+}
+
+template<typename T, typename Sink>
+void close_all(T& t, Sink& snk)
+{ 
+    try {
+        ndnboost::iostreams::close(t, snk, NDNBOOST_IOS::in);
+    } catch (...) {
+        try {
+            ndnboost::iostreams::close(t, snk, NDNBOOST_IOS::out);
+        } catch (...) { }
+        throw;
+    }
+    ndnboost::iostreams::close(t, snk, NDNBOOST_IOS::out);
+}
+
+} // End namespace detail. 
+
+} } // End namespaces iostreams, boost.
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //-----------------------------------//
+# include <ndnboost/iostreams/detail/vc6/close.hpp>
+#else // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //--------------------------//
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct close_impl;
+
+} // End namespace detail.
+
+template<typename T>
+void close(T& t) { detail::close_all(t); }
+
+template<typename T>
+void close(T& t, NDNBOOST_IOS::openmode which)
+{ 
+#ifdef NDNBOOST_IOSTREAMS_STRICT
+    NDNBOOST_ASSERT(which == NDNBOOST_IOS::in || which == NDNBOOST_IOS::out);
+#else
+    if (which == (NDNBOOST_IOS::in | NDNBOOST_IOS::out)) {
+        detail::close_all(t);
+        return;
+    }
+#endif
+    detail::close_impl<T>::close(detail::unwrap(t), which); 
+}
+
+template<typename T, typename Sink>
+void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+{ 
+#ifdef NDNBOOST_IOSTREAMS_STRICT
+    NDNBOOST_ASSERT(which == NDNBOOST_IOS::in || which == NDNBOOST_IOS::out);
+#else
+    if (which == (NDNBOOST_IOS::in | NDNBOOST_IOS::out)) {
+        detail::close_all(t, snk);
+        return;
+    }
+#endif
+    detail::close_impl<T>::close(detail::unwrap(t), snk, which); 
+}
+
+namespace detail {
+
+//------------------Definition of close_impl----------------------------------//
+
+struct close_boost_stream { };
+struct close_filtering_stream { };
+
+template<typename T>
+struct close_tag {
+    typedef typename category_of<T>::type             category;
+    typedef typename detail::unwrapped_type<T>::type  unwrapped;
+    typedef typename
+            iostreams::select<
+                mpl::not_< is_convertible<category, closable_tag> >,
+                any_tag,
+                mpl::or_<
+                    is_boost_stream<unwrapped>,
+                    is_boost_stream_buffer<unwrapped>
+                >,
+                close_boost_stream,
+                mpl::or_<
+                    is_filtering_stream<unwrapped>,
+                    is_filtering_streambuf<unwrapped>
+                >,
+                close_filtering_stream,
+                mpl::or_<
+                    is_convertible<category, two_sequence>,
+                    is_convertible<category, dual_use>
+                >,
+                two_sequence,
+                else_,
+                closable_tag
+            >::type type;
+};
+
+template<typename T>
+struct close_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          close_impl<NDNBOOST_DEDUCED_TYPENAME close_tag<T>::type>
+      >::type
+    { };
+
+template<>
+struct close_impl<any_tag> {
+    template<typename T>
+    static void close(T& t, NDNBOOST_IOS::openmode which)
+    {
+        if (which == NDNBOOST_IOS::out)
+            iostreams::flush(t);
+    }
+
+    template<typename T, typename Sink>
+    static void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+    {
+        if (which == NDNBOOST_IOS::out) {
+            non_blocking_adapter<Sink> nb(snk);
+            iostreams::flush(t, nb);
+        }
+    }
+};
+
+template<>
+struct close_impl<close_boost_stream> {
+    template<typename T>
+    static void close(T& t)
+    {
+        t.close();
+    }
+    template<typename T>
+    static void close(T& t, NDNBOOST_IOS::openmode which)
+    {
+        if (which == NDNBOOST_IOS::out)
+            t.close();
+    }
+};
+
+template<>
+struct close_impl<close_filtering_stream> {
+    template<typename T>
+    static void close(T& t, NDNBOOST_IOS::openmode which)
+    {
+        typedef typename category_of<T>::type category;
+        const bool in =  is_convertible<category, input>::value &&
+                        !is_convertible<category, output>::value;
+        if (in == (which == NDNBOOST_IOS::in) && t.is_complete())
+            t.pop();
+    }
+};
+
+template<>
+struct close_impl<closable_tag> {
+    template<typename T>
+    static void close(T& t, NDNBOOST_IOS::openmode which)
+    {
+        typedef typename category_of<T>::type category;
+        const bool in =  is_convertible<category, input>::value &&
+                        !is_convertible<category, output>::value;
+        if (in == (which == NDNBOOST_IOS::in))
+            t.close();
+    }
+    template<typename T, typename Sink>
+    static void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+    {
+        typedef typename category_of<T>::type category;
+        const bool in =  is_convertible<category, input>::value &&
+                        !is_convertible<category, output>::value;
+        if (in == (which == NDNBOOST_IOS::in)) {
+            non_blocking_adapter<Sink> nb(snk);
+            t.close(nb);
+        }
+    }
+};
+
+template<>
+struct close_impl<two_sequence> {
+    template<typename T>
+    static void close(T& t, NDNBOOST_IOS::openmode which) { t.close(which); }
+    template<typename T, typename Sink>
+    static void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+    {
+        non_blocking_adapter<Sink> nb(snk);
+        t.close(nb, which);
+    }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //-------------------------//
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/code_converter.hpp b/include/ndnboost/iostreams/code_converter.hpp
new file mode 100644
index 0000000..e2c29d0
--- /dev/null
+++ b/include/ndnboost/iostreams/code_converter.hpp
@@ -0,0 +1,425 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains machinery for performing code conversion.
+
+#ifndef NDNBOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#if defined(NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS) || \
+    defined(NDNBOOST_IOSTREAMS_NO_LOCALE) \
+    /**/
+# error code conversion not supported on this platform
+#endif
+
+#include <algorithm>                       // max.
+#include <cstring>                         // memcpy.
+#include <exception>
+#include <ndnboost/config.hpp>                // DEDUCED_TYPENAME, 
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/constants.hpp>   // default_filter_buffer_size.
+#include <ndnboost/iostreams/detail/adapter/concept_adapter.hpp>
+#include <ndnboost/iostreams/detail/adapter/direct_adapter.hpp>
+#include <ndnboost/iostreams/detail/buffer.hpp>
+#include <ndnboost/iostreams/detail/call_traits.hpp>
+#include <ndnboost/iostreams/detail/codecvt_holder.hpp>
+#include <ndnboost/iostreams/detail/codecvt_helper.hpp>
+#include <ndnboost/iostreams/detail/double_object.hpp>
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/forward.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp> // failure, openmode, int types.
+#include <ndnboost/iostreams/detail/optional.hpp>
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // Borland 5.x
+
+namespace ndnboost { namespace iostreams {
+
+struct code_conversion_error : NDNBOOST_IOSTREAMS_FAILURE {
+    code_conversion_error() 
+        : NDNBOOST_IOSTREAMS_FAILURE("code conversion error")
+        { }
+};
+
+namespace detail {
+
+//--------------Definition of strncpy_if_same---------------------------------//
+
+// Helper template for strncpy_if_same, below.
+template<bool B>
+struct strncpy_if_same_impl;
+
+template<>
+struct strncpy_if_same_impl<true> {
+    template<typename Ch>
+    static Ch* copy(Ch* tgt, const Ch* src, std::streamsize n)
+    { return NDNBOOST_IOSTREAMS_CHAR_TRAITS(Ch)::copy(tgt, src, n); }
+};
+
+template<>
+struct strncpy_if_same_impl<false> {
+    template<typename Src, typename Tgt>
+    static Tgt* copy(Tgt* tgt, const Src*, std::streamsize) { return tgt; }
+};
+
+template<typename Src, typename Tgt>
+Tgt* strncpy_if_same(Tgt* tgt, const Src* src, std::streamsize n)
+{
+    typedef strncpy_if_same_impl<is_same<Src, Tgt>::value> impl;
+    return impl::copy(tgt, src, n);
+}
+
+//--------------Definition of conversion_buffer-------------------------------//
+
+// Buffer and conversion state for reading.
+template<typename Codecvt, typename Alloc>
+class conversion_buffer 
+    : public buffer<
+                 NDNBOOST_DEDUCED_TYPENAME detail::codecvt_extern<Codecvt>::type,
+                 Alloc
+             > 
+{
+public:
+    typedef typename Codecvt::state_type state_type;
+    conversion_buffer() 
+        : buffer<
+              NDNBOOST_DEDUCED_TYPENAME detail::codecvt_extern<Codecvt>::type,
+              Alloc
+          >(0) 
+    { 
+        reset(); 
+    }
+    state_type& state() { return state_; }
+    void reset() 
+    { 
+        if (this->size()) 
+            this->set(0, 0);
+        state_ = state_type(); 
+    }
+private:
+    state_type state_;
+};
+
+//--------------Definition of converter_impl----------------------------------//
+
+// Contains member data, open/is_open/close and buffer management functions.
+template<typename Device, typename Codecvt, typename Alloc>
+struct code_converter_impl {
+    typedef typename codecvt_extern<Codecvt>::type          extern_type;
+    typedef typename category_of<Device>::type              device_category;
+    typedef is_convertible<device_category, input>          can_read;
+    typedef is_convertible<device_category, output>         can_write;
+    typedef is_convertible<device_category, bidirectional>  is_bidir;
+    typedef typename 
+            iostreams::select<  // Disambiguation for Tru64.
+                is_bidir, bidirectional,
+                can_read, input,
+                can_write, output
+            >::type                                         mode;      
+    typedef typename
+            mpl::if_<
+                is_direct<Device>,
+                direct_adapter<Device>,
+                Device
+            >::type                                         device_type;
+    typedef optional< concept_adapter<device_type> >        storage_type;
+    typedef is_convertible<device_category, two_sequence>   is_double;
+    typedef conversion_buffer<Codecvt, Alloc>               buffer_type;
+
+    code_converter_impl() : cvt_(), flags_(0) { }
+
+    ~code_converter_impl()
+    { 
+        try { 
+            if (flags_ & f_open) close(); 
+        } catch (...) { /* */ } 
+    }
+
+    template <class T>
+    void open(const T& dev, int buffer_size)
+    {
+        if (flags_ & f_open)
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("already open"));
+        if (buffer_size == -1)
+            buffer_size = default_filter_buffer_size;
+        int max_length = cvt_.get().max_length();
+        buffer_size = (std::max)(buffer_size, 2 * max_length);
+        if (can_read::value) {
+            buf_.first().resize(buffer_size);
+            buf_.first().set(0, 0);
+        }
+        if (can_write::value && !is_double::value) {
+            buf_.second().resize(buffer_size);
+            buf_.second().set(0, 0);
+        }
+        dev_.reset(concept_adapter<device_type>(dev));
+        flags_ = f_open;
+    }
+
+    void close()
+    {
+        detail::execute_all(
+            detail::call_member_close(*this, NDNBOOST_IOS::in),
+            detail::call_member_close(*this, NDNBOOST_IOS::out)
+        );
+    }
+
+    void close(NDNBOOST_IOS::openmode which)
+    {
+        if (which == NDNBOOST_IOS::in && (flags_ & f_input_closed) == 0) {
+            flags_ |= f_input_closed;
+            iostreams::close(dev(), NDNBOOST_IOS::in);
+        }
+        if (which == NDNBOOST_IOS::out && (flags_ & f_output_closed) == 0) {
+            flags_ |= f_output_closed;
+            detail::execute_all(
+                detail::flush_buffer(buf_.second(), dev(), can_write::value),
+                detail::call_close(dev(), NDNBOOST_IOS::out),
+                detail::call_reset(dev_),
+                detail::call_reset(buf_.first()),
+                detail::call_reset(buf_.second())
+            );
+        }
+    }
+
+    bool is_open() const { return (flags_ & f_open) != 0;}
+
+    device_type& dev() { return **dev_; }
+
+    enum flag_type {
+        f_open             = 1,
+        f_input_closed     = f_open << 1,
+        f_output_closed    = f_input_closed << 1
+    };
+
+    codecvt_holder<Codecvt>  cvt_;
+    storage_type             dev_;
+    double_object<
+        buffer_type, 
+        is_double
+    >                        buf_;
+    int                      flags_;
+};
+
+} // End namespace detail.
+
+//--------------Definition of converter---------------------------------------//
+
+#define NDNBOOST_IOSTREAMS_CONVERTER_PARAMS() , int buffer_size = -1
+#define NDNBOOST_IOSTREAMS_CONVERTER_ARGS() , buffer_size
+
+template<typename Device, typename Codecvt, typename Alloc>
+struct code_converter_base {
+    typedef detail::code_converter_impl<
+                Device, Codecvt, Alloc
+            > impl_type;
+    code_converter_base() : pimpl_(new impl_type) { }
+    shared_ptr<impl_type> pimpl_;
+};
+
+template< typename Device, 
+          typename Codecvt = detail::default_codecvt, 
+          typename Alloc = std::allocator<char> >
+class code_converter 
+    : protected code_converter_base<Device, Codecvt, Alloc>
+{
+private:
+    typedef detail::code_converter_impl<
+                Device, Codecvt, Alloc
+            >                                                       impl_type;
+    typedef typename impl_type::device_type                         device_type;
+    typedef typename impl_type::buffer_type                         buffer_type;
+    typedef typename detail::codecvt_holder<Codecvt>::codecvt_type  codecvt_type;
+    typedef typename detail::codecvt_intern<Codecvt>::type          intern_type;
+    typedef typename detail::codecvt_extern<Codecvt>::type          extern_type;
+    typedef typename detail::codecvt_state<Codecvt>::type           state_type;
+public:
+    typedef intern_type                                             char_type;    
+    struct category 
+        : impl_type::mode, device_tag, closable_tag, localizable_tag
+        { };
+    NDNBOOST_STATIC_ASSERT((
+        is_same<
+            extern_type, 
+            NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+        >::value
+    ));
+public:
+    code_converter() { }
+#if NDNBOOST_WORKAROUND(__GNUC__, < 3)
+    code_converter(code_converter& rhs) 
+        : code_converter_base<Device, Codecvt, Alloc>(rhs)
+        { }
+    code_converter(const code_converter& rhs) 
+        : code_converter_base<Device, Codecvt, Alloc>(rhs)
+        { }
+#endif
+    NDNBOOST_IOSTREAMS_FORWARD( code_converter, open_impl, Device,
+                             NDNBOOST_IOSTREAMS_CONVERTER_PARAMS, 
+                             NDNBOOST_IOSTREAMS_CONVERTER_ARGS )
+
+        // fstream-like interface.
+
+    bool is_open() const { return this->pimpl_->is_open(); }
+    void close(NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+    { impl().close(which); }
+
+        // Device interface.
+
+    std::streamsize read(char_type*, std::streamsize);
+    std::streamsize write(const char_type*, std::streamsize);
+    void imbue(const std::locale& loc) { impl().cvt_.imbue(loc); }
+
+        // Direct device access.
+
+    Device& operator*() { return detail::unwrap_direct(dev()); }
+    Device* operator->() { return &detail::unwrap_direct(dev()); }
+private:
+    template<typename T> // Used for forwarding.
+    void open_impl(const T& t NDNBOOST_IOSTREAMS_CONVERTER_PARAMS()) 
+    { 
+        impl().open(t NDNBOOST_IOSTREAMS_CONVERTER_ARGS()); 
+    }
+
+    const codecvt_type& cvt() { return impl().cvt_.get(); }
+    device_type& dev() { return impl().dev(); }
+    buffer_type& in() { return impl().buf_.first(); }
+    buffer_type& out() { return impl().buf_.second(); }
+    impl_type& impl() { return *this->pimpl_; }
+};
+
+//--------------Implementation of converter-----------------------------------//
+
+// Implementation note: if end of stream contains a partial character,
+// it is ignored.
+template<typename Device, typename Codevt, typename Alloc>
+std::streamsize code_converter<Device, Codevt, Alloc>::read
+    (char_type* s, std::streamsize n)
+{
+    const extern_type*   next;        // Next external char.
+    intern_type*         nint;        // Next internal char.
+    std::streamsize      total = 0;   // Characters read.
+    int                  status = iostreams::char_traits<char>::good();
+    bool                 partial = false;
+    buffer_type&         buf = in();
+
+    do {
+
+        // Fill buffer.
+        if (buf.ptr() == buf.eptr() || partial) {
+            status = buf.fill(dev());
+            if (buf.ptr() == buf.eptr())
+                break;
+            partial = false;
+        }
+
+        // Convert.
+        std::codecvt_base::result result =
+            cvt().in( buf.state(),
+                      buf.ptr(), buf.eptr(), next,
+                      s + total, s + n, nint );
+        buf.ptr() += next - buf.ptr();
+        total = static_cast<std::streamsize>(nint - s);
+
+        switch (result) {
+        case std::codecvt_base::partial:
+            partial = true;
+            break;
+        case std::codecvt_base::ok:
+            break;
+        case std::codecvt_base::noconv:
+            {
+                std::streamsize amt = 
+                    std::min<std::streamsize>(next - buf.ptr(), n - total);
+                detail::strncpy_if_same(s + total, buf.ptr(), amt);
+                total += amt;
+            }
+            break;
+        case std::codecvt_base::error:
+        default:
+            buf.state() = state_type();
+            ndnboost::throw_exception(code_conversion_error());
+        }
+
+    } while (total < n && status != EOF && status != WOULD_BLOCK);
+
+    return total == 0 && status == EOF ? -1 : total;
+}
+
+template<typename Device, typename Codevt, typename Alloc>
+std::streamsize code_converter<Device, Codevt, Alloc>::write
+    (const char_type* s, std::streamsize n)
+{
+    buffer_type&        buf = out();
+    extern_type*        next;              // Next external char.
+    const intern_type*  nint;              // Next internal char.
+    std::streamsize     total = 0;         // Characters written.
+    bool                partial = false;
+
+    while (total < n) {
+
+        // Empty buffer.
+        if (buf.eptr() == buf.end() || partial) {
+            if (!buf.flush(dev()))
+                break;
+            partial = false;
+        }
+       
+        // Convert.
+        std::codecvt_base::result result =
+            cvt().out( buf.state(),
+                       s + total, s + n, nint,
+                       buf.eptr(), buf.end(), next );
+        int progress = (int) (next - buf.eptr());
+        buf.eptr() += progress;
+
+        switch (result) {
+        case std::codecvt_base::partial:
+            partial = true;
+            NDNBOOST_FALLTHROUGH;
+        case std::codecvt_base::ok:
+            total = static_cast<std::streamsize>(nint - s);
+            break;
+        case std::codecvt_base::noconv:
+            {
+                std::streamsize amt = 
+                    std::min<std::streamsize>( nint - total - s, 
+                                               buf.end() - buf.eptr() );
+                detail::strncpy_if_same(buf.eptr(), s + total, amt);
+                total += amt;
+            }
+            break;
+        case std::codecvt_base::error:
+        default:
+            buf.state() = state_type();
+            ndnboost::throw_exception(code_conversion_error());
+        }
+    }
+    return total;
+}
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // Borland 5.x
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/combine.hpp b/include/ndnboost/iostreams/combine.hpp
new file mode 100644
index 0000000..8ffcf63
--- /dev/null
+++ b/include/ndnboost/iostreams/combine.hpp
@@ -0,0 +1,260 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// To do: add support for random-access.
+
+#ifndef NDNBOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp> // NO_STD_LOCALE, DEDUCED_TYPENAME.
+#ifndef NDNBOOST_NO_STD_LOCALE
+# include <locale>
+#endif
+#include <ndnboost/iostreams/detail/ios.hpp>   
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>       
+#include <ndnboost/iostreams/traits.hpp>         
+#include <ndnboost/iostreams/operations.hpp>        
+#include <ndnboost/mpl/if.hpp>    
+#include <ndnboost/static_assert.hpp>  
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/is_same.hpp> 
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+//
+// Template name: combined_device.
+// Description: Model of Device defined in terms of a Source/Sink pair.
+// Template parameters:
+//      Source - A model of Source, with the same char_type and traits_type
+//          as Sink.
+//      Sink - A model of Sink, with the same char_type and traits_type
+//          as Source.
+//
+template<typename Source, typename Sink>
+class combined_device {
+private:
+    typedef typename category_of<Source>::type  in_category;
+    typedef typename category_of<Sink>::type    out_category;
+    typedef typename char_type_of<Sink>::type   sink_char_type;
+public:
+    typedef typename char_type_of<Source>::type char_type;
+    struct category
+        : bidirectional, 
+          device_tag, 
+          closable_tag, 
+          localizable_tag
+        { };
+    NDNBOOST_STATIC_ASSERT(is_device<Source>::value);
+    NDNBOOST_STATIC_ASSERT(is_device<Sink>::value);
+    NDNBOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
+    NDNBOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
+    NDNBOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::value));
+    combined_device(const Source& src, const Sink& snk);
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    void close(NDNBOOST_IOS::openmode);
+    #ifndef NDNBOOST_NO_STD_LOCALE
+        void imbue(const std::locale& loc);
+    #endif
+private:
+    Source  src_;
+    Sink    sink_;
+};
+
+//
+// Template name: combined_filter.
+// Description: Model of Device defined in terms of a Source/Sink pair.
+// Template parameters:
+//      InputFilter - A model of InputFilter, with the same char_type as 
+//          OutputFilter.
+//      OutputFilter - A model of OutputFilter, with the same char_type as 
+//          InputFilter.
+//
+template<typename InputFilter, typename OutputFilter>
+class combined_filter {
+private:
+    typedef typename category_of<InputFilter>::type    in_category;
+    typedef typename category_of<OutputFilter>::type   out_category;
+    typedef typename char_type_of<OutputFilter>::type  output_char_type;
+public:
+    typedef typename char_type_of<InputFilter>::type   char_type;
+    struct category 
+        : multichar_bidirectional_filter_tag,
+          closable_tag, 
+          localizable_tag
+        { };
+    NDNBOOST_STATIC_ASSERT(is_filter<InputFilter>::value);
+    NDNBOOST_STATIC_ASSERT(is_filter<OutputFilter>::value);
+    NDNBOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
+    NDNBOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
+    NDNBOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
+    combined_filter(const InputFilter& in, const OutputFilter& out);
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    { return ndnboost::iostreams::read(in_, src, s, n); }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    { return ndnboost::iostreams::write(out_, snk, s, n); }
+
+    template<typename Sink>
+    void close(Sink& snk, NDNBOOST_IOS::openmode which)
+    {
+        if (which == NDNBOOST_IOS::in) {
+            if (is_convertible<in_category, dual_use>::value) {
+                iostreams::close(in_, snk, NDNBOOST_IOS::in);
+            } else {
+                detail::close_all(in_, snk);
+            }
+        }
+        if (which == NDNBOOST_IOS::out) {
+            if (is_convertible<out_category, dual_use>::value) {
+                iostreams::close(out_, snk, NDNBOOST_IOS::out);
+            } else {
+                detail::close_all(out_, snk);
+            }
+        }
+    }
+    #ifndef NDNBOOST_NO_STD_LOCALE
+        void imbue(const std::locale& loc);
+    #endif
+private:
+    InputFilter   in_;
+    OutputFilter  out_;
+};
+
+template<typename In, typename Out>
+struct combination_traits 
+    : mpl::if_<
+          is_device<In>,
+          combined_device<
+              typename wrapped_type<In>::type,
+              typename wrapped_type<Out>::type
+          >,
+          combined_filter<
+              typename wrapped_type<In>::type,
+              typename wrapped_type<Out>::type
+          >
+      >
+    { };
+
+} // End namespace detail.
+
+template<typename In, typename Out>
+struct combination : detail::combination_traits<In, Out>::type {
+    typedef typename detail::combination_traits<In, Out>::type  base_type;
+    typedef typename detail::wrapped_type<In>::type          in_type;
+    typedef typename detail::wrapped_type<Out>::type         out_type;
+    combination(const in_type& in, const out_type& out)
+        : base_type(in, out) { }
+};
+
+namespace detail {
+
+// Workaround for VC6 ETI bug.
+template<typename In, typename Out>
+struct combine_traits {
+    typedef combination<
+                NDNBOOST_DEDUCED_TYPENAME detail::unwrapped_type<In>::type, 
+                NDNBOOST_DEDUCED_TYPENAME detail::unwrapped_type<Out>::type
+            > type;
+};
+
+} // End namespace detail.
+
+//
+// Template name: combine.
+// Description: Takes a Source/Sink pair or InputFilter/OutputFilter pair and
+//      returns a Source or Filter which performs input using the first member
+//      of the pair and output using the second member of the pair.
+// Template parameters:
+//      In - A model of Source or InputFilter, with the same char_type as Out.
+//      Out - A model of Sink or OutputFilter, with the same char_type as In.
+//
+template<typename In, typename Out>
+typename detail::combine_traits<In, Out>::type
+combine(const In& in, const Out& out) 
+{ 
+    typedef typename detail::combine_traits<In, Out>::type return_type;
+    return return_type(in, out); 
+}
+
+//----------------------------------------------------------------------------//
+
+namespace detail {
+
+//--------------Implementation of combined_device-----------------------------//
+
+template<typename Source, typename Sink>
+inline combined_device<Source, Sink>::combined_device
+    (const Source& src, const Sink& snk)
+    : src_(src), sink_(snk) { }
+
+template<typename Source, typename Sink>
+inline std::streamsize
+combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
+{ return iostreams::read(src_, s, n); }
+
+template<typename Source, typename Sink>
+inline std::streamsize
+combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
+{ return iostreams::write(sink_, s, n); }
+
+template<typename Source, typename Sink>
+inline void
+combined_device<Source, Sink>::close(NDNBOOST_IOS::openmode which)
+{ 
+    if (which == NDNBOOST_IOS::in)
+        detail::close_all(src_); 
+    if (which == NDNBOOST_IOS::out)
+        detail::close_all(sink_); 
+}
+
+#ifndef NDNBOOST_NO_STD_LOCALE
+    template<typename Source, typename Sink>
+    void combined_device<Source, Sink>::imbue(const std::locale& loc)
+    {
+        iostreams::imbue(src_, loc);
+        iostreams::imbue(sink_, loc);
+    }
+#endif
+
+//--------------Implementation of filter_pair---------------------------------//
+
+template<typename InputFilter, typename OutputFilter>
+inline combined_filter<InputFilter, OutputFilter>::combined_filter
+    (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out)
+    { }
+
+#ifndef NDNBOOST_NO_STD_LOCALE
+    template<typename InputFilter, typename OutputFilter>
+    void combined_filter<InputFilter, OutputFilter>::imbue
+        (const std::locale& loc)
+    {
+        iostreams::imbue(in_, loc);
+        iostreams::imbue(out_, loc);
+    }
+#endif
+
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/compose.hpp b/include/ndnboost/iostreams/compose.hpp
new file mode 100644
index 0000000..8d55ddc
--- /dev/null
+++ b/include/ndnboost/iostreams/compose.hpp
@@ -0,0 +1,494 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Note: bidirectional streams are not supported.
+
+#ifndef NDNBOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <algorithm>          // min.
+#include <utility>            // pair.
+#include <ndnboost/config.hpp>   // DEDUCED_TYPENAME.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/adapter/direct_adapter.hpp>
+#include <ndnboost/iostreams/detail/call_traits.hpp>
+#include <ndnboost/iostreams/detail/enable_if_stream.hpp>
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/traits.hpp>      // mode_of, is_direct.
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/ref.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template< typename First, 
+          typename Second,
+          typename FirstMode = 
+              NDNBOOST_DEDUCED_TYPENAME mode_of<First>::type,
+          typename SecondMode = 
+              NDNBOOST_DEDUCED_TYPENAME mode_of<Second>::type >
+struct composite_mode
+    : select<
+          is_convertible<SecondMode, FirstMode>, FirstMode,
+          is_convertible<FirstMode, SecondMode>, SecondMode,
+          is_convertible<SecondMode, input>,     input,
+          else_,                                 output
+      >
+    { };
+
+//
+// Template name: composite_device.
+// Description: Provides a Device view of a Filter, Device pair.
+// Template parameters:
+//      Filter - A model of Filter.
+//      Device - An indirect model of Device.
+//
+template< typename Filter,
+          typename Device,
+          typename Mode =
+              NDNBOOST_DEDUCED_TYPENAME composite_mode<Filter, Device>::type >
+class composite_device {
+private:
+    typedef typename detail::param_type<Device>::type       param_type;
+    typedef typename mode_of<Filter>::type                  filter_mode;
+    typedef typename mode_of<Device>::type                  device_mode;
+    typedef typename
+            iostreams::select<  // Disambiguation for Tru64.
+                is_direct<Device>,  direct_adapter<Device>,
+                is_std_io<Device>,  Device&,
+                else_,              Device
+            >::type                                         value_type;
+    NDNBOOST_STATIC_ASSERT(is_filter<Filter>::value);
+    NDNBOOST_STATIC_ASSERT(is_device<Device>::value);
+public:
+    typedef typename char_type_of<Filter>::type             char_type;
+    struct category
+        : Mode,
+          device_tag,
+          closable_tag,
+          flushable_tag,
+          localizable_tag,
+          optimally_buffered_tag
+        { };
+    composite_device(const Filter& flt, param_type dev);
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way,
+                         NDNBOOST_IOS::openmode which =
+                             NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+
+    void close();
+    void close(NDNBOOST_IOS::openmode which);
+    bool flush();
+    std::streamsize optimal_buffer_size() const;
+
+    template<typename Locale> // Avoid dependency on <locale>
+    void imbue(const Locale& loc)
+    {
+        iostreams::imbue(filter_, loc);
+        iostreams::imbue(device_, loc);
+    }
+
+    Filter& first() { return filter_; }
+    Device& second() { return device_; }
+private:
+    Filter      filter_;
+    value_type  device_;
+};
+
+//
+// Template name: composite_device.
+// Description: Provides a Device view of a Filter, Device pair.
+// Template parameters:
+//      Filter - A model of Filter.
+//      Device - An indirect model of Device.
+//
+template< typename Filter1, 
+          typename Filter2,
+          typename Mode =
+              NDNBOOST_DEDUCED_TYPENAME composite_mode<Filter1, Filter2>::type >
+class composite_filter {
+private:
+    typedef reference_wrapper<Filter2>           filter_ref;
+    typedef typename mode_of<Filter1>::type      first_mode;
+    typedef typename mode_of<Filter2>::type      second_mode;
+
+    // A dual-use filter cannot be composed with a read-write filter
+    NDNBOOST_STATIC_ASSERT(
+        !(is_convertible<first_mode, dual_use>::value) ||
+        !(is_convertible<second_mode, input>::value) ||
+        !(is_convertible<second_mode, output>::value) ||
+         (is_convertible<second_mode, dual_use>::value)
+    );
+    NDNBOOST_STATIC_ASSERT(
+        !(is_convertible<second_mode, dual_use>::value) ||
+        !(is_convertible<first_mode, input>::value) ||
+        !(is_convertible<first_mode, output>::value) ||
+         (is_convertible<first_mode, dual_use>::value)
+    );
+    NDNBOOST_STATIC_ASSERT(is_filter<Filter1>::value);
+    NDNBOOST_STATIC_ASSERT(is_filter<Filter2>::value);
+public:
+    typedef typename char_type_of<Filter1>::type  char_type;
+    struct category
+        : Mode,
+          filter_tag,
+          multichar_tag,
+          closable_tag,
+          flushable_tag,
+          localizable_tag,
+          optimally_buffered_tag
+        { };
+    composite_filter(const Filter1& filter1, const Filter2& filter2)
+        : filter1_(filter1), filter2_(filter2)
+        { }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        composite_device<filter_ref, Source> cmp(ndnboost::ref(filter2_), src);
+        return iostreams::read(filter1_, cmp, s, n);
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        composite_device<filter_ref, Sink> cmp(ndnboost::ref(filter2_), snk);
+        return iostreams::write(filter1_, cmp, s, n);
+    }
+
+    template<typename Device>
+    std::streampos seek( Device& dev, stream_offset off, NDNBOOST_IOS::seekdir way,
+                         NDNBOOST_IOS::openmode which =
+                             NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+    {
+        composite_device<filter_ref, Device> cmp(ndnboost::ref(filter2_), dev);
+        return iostreams::seek(filter1_, cmp, off, way, which);
+    }
+
+    template<typename Device>
+    void close(Device& dev)
+    {
+        NDNBOOST_STATIC_ASSERT((!is_convertible<category, two_sequence>::value));
+        NDNBOOST_STATIC_ASSERT((!is_convertible<category, dual_use>::value));
+
+        // Create a new device by composing the second filter2_ with dev.
+        composite_device<filter_ref, Device> cmp(ndnboost::ref(filter2_), dev);
+
+        // Close input sequences in reverse order and output sequences in 
+        // forward order
+        if (!is_convertible<first_mode, dual_use>::value) {
+            detail::execute_all(
+                detail::call_close(filter2_, dev, NDNBOOST_IOS::in),
+                detail::call_close(filter1_, cmp, NDNBOOST_IOS::in),
+                detail::call_close(filter1_, cmp, NDNBOOST_IOS::out),
+                detail::call_close(filter2_, dev, NDNBOOST_IOS::out)
+            );
+        } else if (is_convertible<second_mode, input>::value) {
+            detail::execute_all(
+                detail::call_close(filter2_, dev, NDNBOOST_IOS::in),
+                detail::call_close(filter1_, cmp, NDNBOOST_IOS::in)
+            );
+        } else {
+            detail::execute_all(
+                detail::call_close(filter1_, cmp, NDNBOOST_IOS::out),
+                detail::call_close(filter2_, dev, NDNBOOST_IOS::out)
+            );
+        }
+    }
+
+    template<typename Device>
+    void close(Device& dev, NDNBOOST_IOS::openmode which)
+    {
+        NDNBOOST_STATIC_ASSERT(
+            (is_convertible<category, two_sequence>::value) ||
+            (is_convertible<category, dual_use>::value)
+        );
+
+        // Create a new device by composing the second filter2_ with dev.
+        composite_device<filter_ref, Device> cmp(ndnboost::ref(filter2_), dev);
+
+        // Close input sequences in reverse order
+        if ( which == NDNBOOST_IOS::in &&
+             ( !is_convertible<first_mode, dual_use>::value ||
+                is_convertible<second_mode, input>::value ) )
+        {
+            detail::execute_all(
+                detail::call_close(filter2_, dev, NDNBOOST_IOS::in),
+                detail::call_close(filter1_, cmp, NDNBOOST_IOS::in)
+            );
+        }
+
+        // Close output sequences in forward order
+        if ( which == NDNBOOST_IOS::out &&
+             ( !is_convertible<first_mode, dual_use>::value ||
+                is_convertible<second_mode, output>::value ) )
+        {
+            detail::execute_all(
+                detail::call_close(filter1_, cmp, NDNBOOST_IOS::out),
+                detail::call_close(filter2_, dev, NDNBOOST_IOS::out)
+            );
+        }
+    }
+
+    template<typename Device>
+    bool flush(Device& dev)
+    {
+        composite_device<Filter2, Device> cmp(filter2_, dev);
+        return iostreams::flush(filter1_, cmp);
+    }
+
+    std::streamsize optimal_buffer_size() const
+    {
+        std::streamsize first = iostreams::optimal_buffer_size(filter1_);
+        std::streamsize second = iostreams::optimal_buffer_size(filter2_);
+        return first < second ? second : first;
+    }
+
+    template<typename Locale> // Avoid dependency on <locale>
+    void imbue(const Locale& loc)
+    {   // To do: consider using RAII.
+        iostreams::imbue(filter1_, loc);
+        iostreams::imbue(filter2_, loc);
+    }
+
+    Filter1& first() { return filter1_; }
+    Filter2& second() { return filter2_; }
+private:
+    Filter1  filter1_;
+    Filter2  filter2_;
+};
+
+template<typename Filter, typename FilterOrDevice>
+struct composite_traits
+    : mpl::if_<
+          is_device<FilterOrDevice>,
+          composite_device<Filter, FilterOrDevice>,
+          composite_filter<Filter, FilterOrDevice>
+      >
+    { };
+
+} // End namespace detail.
+
+template<typename Filter, typename FilterOrDevice>
+struct composite : detail::composite_traits<Filter, FilterOrDevice>::type {
+    typedef typename detail::param_type<FilterOrDevice>::type param_type;
+    typedef typename detail::composite_traits<Filter, FilterOrDevice>::type base;
+    composite(const Filter& flt, param_type dev)
+        : base(flt, dev)
+        { }
+};
+
+//--------------Implementation of compose-------------------------------------//
+
+// Note: The following workarounds are patterned after resolve.hpp. It has not
+// yet been confirmed that they are necessary.
+
+#ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------//
+# ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
+
+template<typename Filter, typename FilterOrDevice>
+composite<Filter, FilterOrDevice>
+compose( const Filter& filter, const FilterOrDevice& fod
+         NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) )
+{ return composite<Filter, FilterOrDevice>(filter, fod); }
+
+template<typename Filter, typename Ch, typename Tr>
+composite< Filter, std::basic_streambuf<Ch, Tr> >
+compose(const Filter& filter, std::basic_streambuf<Ch, Tr>& sb)
+{ return composite< Filter, std::basic_streambuf<Ch, Tr> >(filter, sb); }
+
+template<typename Filter, typename Ch, typename Tr>
+composite< Filter, std::basic_istream<Ch, Tr> >
+compose(const Filter& filter, std::basic_istream<Ch, Tr>& is)
+{ return composite< Filter, std::basic_istream<Ch, Tr> >(filter, is); }
+
+template<typename Filter, typename Ch, typename Tr>
+composite< Filter, std::basic_ostream<Ch, Tr> >
+compose(const Filter& filter, std::basic_ostream<Ch, Tr>& os)
+{ return composite< Filter, std::basic_ostream<Ch, Tr> >(filter, os); }
+
+template<typename Filter, typename Ch, typename Tr>
+composite< Filter, std::basic_iostream<Ch, Tr> >
+compose(const Filter& filter, std::basic_iostream<Ch, Tr>& io)
+{ return composite< Filter, std::basic_iostream<Ch, Tr> >(filter, io); }
+
+# else // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
+
+template<typename Filter, typename FilterOrDevice>
+composite<Filter, FilterOrDevice>
+compose( const Filter& filter, const FilterOrDevice& fod
+         NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) )
+{ return composite<Filter, FilterOrDevice>(filter, fod); }
+
+template<typename Filter>
+composite<Filter, std::streambuf>
+compose(const Filter& filter, std::streambuf& sb)
+{ return composite<Filter, std::streambuf>(filter, sb); }
+
+template<typename Filter>
+composite<Filter, std::istream>
+compose(const Filter& filter, std::istream& is)
+{ return composite<Filter, std::istream>(filter, is); }
+
+template<typename Filter>
+composite<Filter, std::ostream>
+compose(const Filter& filter, std::ostream& os)
+{ return composite<Filter, std::ostream>(filter, os); }
+
+template<typename Filter>
+composite<Filter, std::iostream>
+compose(const Filter& filter, std::iostream& io)
+{ return composite<Filter, std::iostream>(filter, io); }
+
+# endif // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
+#else // #ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
+
+template<typename Filter, typename Stream>
+composite<Filter, Stream>
+compose(const Filter& flt, const Stream& strm, mpl::true_)
+{   // Bad overload resolution.
+    return composite<Filter, Stream>(flt, const_cast<Stream&>(strm));
+}
+
+template<typename Filter, typename FilterOrDevice>
+composite<Filter, FilterOrDevice>
+compose(const Filter& flt, const FilterOrDevice& fod, mpl::false_)
+{ return composite<Filter, FilterOrDevice>(flt, fod); }
+
+template<typename Filter, typename FilterOrDevice>
+composite<Filter, FilterOrDevice>
+compose( const Filter& flt, const FilterOrDevice& fod
+         NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
+{ return compose(flt, fod, is_std_io<FilterOrDevice>()); }
+
+# if !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
+     !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) && \
+     !defined(__GNUC__) // ---------------------------------------------------//
+
+template<typename Filter, typename FilterOrDevice>
+composite<Filter, FilterOrDevice>
+compose (const Filter& filter, FilterOrDevice& fod)
+{ return composite<Filter, FilterOrDevice>(filter, fod); }
+
+# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------//
+#endif // #ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
+
+//----------------------------------------------------------------------------//
+
+namespace detail {
+
+//--------------Implementation of composite_device---------------------------//
+
+template<typename Filter, typename Device, typename Mode>
+composite_device<Filter, Device, Mode>::composite_device
+    (const Filter& flt, param_type dev)
+    : filter_(flt), device_(dev)
+    { }
+
+template<typename Filter, typename Device, typename Mode>
+inline std::streamsize composite_device<Filter, Device, Mode>::read
+    (char_type* s, std::streamsize n)
+{ return iostreams::read(filter_, device_, s, n); }
+
+template<typename Filter, typename Device, typename Mode>
+inline std::streamsize composite_device<Filter, Device, Mode>::write
+    (const char_type* s, std::streamsize n)
+{ return iostreams::write(filter_, device_, s, n); }
+
+template<typename Filter, typename Device, typename Mode>
+std::streampos composite_device<Filter, Device, Mode>::seek
+    (stream_offset off, NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which)
+{ return iostreams::seek(filter_, device_, off, way, which); }
+
+template<typename Filter, typename Device, typename Mode>
+void composite_device<Filter, Device, Mode>::close()
+{
+    NDNBOOST_STATIC_ASSERT((!is_convertible<Mode, two_sequence>::value));
+    NDNBOOST_STATIC_ASSERT(
+        !(is_convertible<filter_mode, dual_use>::value) ||
+        !(is_convertible<device_mode, input>::value) ||
+        !(is_convertible<device_mode, output>::value)
+    );
+
+    // Close input sequences in reverse order and output sequences 
+    // in forward order
+    if (!is_convertible<filter_mode, dual_use>::value) {
+        detail::execute_all(
+            detail::call_close(device_, NDNBOOST_IOS::in),
+            detail::call_close(filter_, device_, NDNBOOST_IOS::in),
+            detail::call_close(filter_, device_, NDNBOOST_IOS::out),
+            detail::call_close(device_, NDNBOOST_IOS::out)
+        );
+    } else if (is_convertible<device_mode, input>::value) {
+        detail::execute_all(
+            detail::call_close(device_, NDNBOOST_IOS::in),
+            detail::call_close(filter_, device_, NDNBOOST_IOS::in)
+        );
+    } else {
+        detail::execute_all(
+            detail::call_close(filter_, device_, NDNBOOST_IOS::out),
+            detail::call_close(device_, NDNBOOST_IOS::out)
+        );
+    }
+}
+
+template<typename Filter, typename Device, typename Mode>
+void composite_device<Filter, Device, Mode>::close(NDNBOOST_IOS::openmode which)
+{
+    NDNBOOST_STATIC_ASSERT((is_convertible<Mode, two_sequence>::value));
+    NDNBOOST_STATIC_ASSERT(!(is_convertible<filter_mode, dual_use>::value));
+
+    // Close input sequences in reverse order
+    if (which == NDNBOOST_IOS::in) {
+        detail::execute_all(
+            detail::call_close(device_, NDNBOOST_IOS::in),
+            detail::call_close(filter_, device_, NDNBOOST_IOS::in) 
+        );
+    }
+
+    // Close output sequences in forward order
+    if (which == NDNBOOST_IOS::out) {
+        detail::execute_all(
+            detail::call_close(filter_, device_, NDNBOOST_IOS::out),
+            detail::call_close(device_, NDNBOOST_IOS::out)
+        );
+    }
+}
+
+template<typename Filter, typename Device, typename Mode>
+bool composite_device<Filter, Device, Mode>::flush()
+{
+    bool r1 = iostreams::flush(filter_, device_);
+    bool r2 = iostreams::flush(device_);
+    return r1 && r2;
+}
+
+template<typename Filter, typename Device, typename Mode>
+std::streamsize
+composite_device<Filter, Device, Mode>::optimal_buffer_size() const
+{ return iostreams::optimal_buffer_size(device_); }
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/concepts.hpp b/include/ndnboost/iostreams/concepts.hpp
new file mode 100644
index 0000000..de734ec
--- /dev/null
+++ b/include/ndnboost/iostreams/concepts.hpp
@@ -0,0 +1,129 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // NDNBOOST_MSVC
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/default_arg.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // openmode.
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+//--------------Definitions of helper templates for device concepts-----------//
+
+template<typename Mode, typename Ch = NDNBOOST_IOSTREAMS_DEFAULT_ARG(char)>
+struct device {
+    typedef Ch char_type;
+    struct category
+        : Mode,
+          device_tag,
+          closable_tag,
+          localizable_tag
+        { };
+
+    void close()
+    {
+        using namespace detail;
+        NDNBOOST_STATIC_ASSERT((!is_convertible<Mode, two_sequence>::value));
+    }
+
+    void close(NDNBOOST_IOS::openmode)
+    {
+        using namespace detail;
+        NDNBOOST_STATIC_ASSERT((is_convertible<Mode, two_sequence>::value));
+    }
+
+    template<typename Locale>
+    void imbue(const Locale&) { }
+};
+
+template<typename Mode, typename Ch = NDNBOOST_IOSTREAMS_DEFAULT_ARG(wchar_t)>
+struct wdevice : device<Mode, Ch> { };
+
+typedef device<input>    source;
+typedef wdevice<input>   wsource;
+typedef device<output>   sink;
+typedef wdevice<output>  wsink;
+
+//--------------Definitions of helper templates for simple filter concepts----//
+
+template<typename Mode, typename Ch = NDNBOOST_IOSTREAMS_DEFAULT_ARG(char)>
+struct filter {
+    typedef Ch char_type;
+    struct category
+        : Mode,
+          filter_tag,
+          closable_tag,
+          localizable_tag
+        { };
+
+    template<typename Device>
+    void close(Device&)
+    {
+        using namespace detail;
+        NDNBOOST_STATIC_ASSERT((!is_convertible<Mode, two_sequence>::value));
+        NDNBOOST_STATIC_ASSERT((!is_convertible<Mode, dual_use>::value));
+    }
+
+    template<typename Device>
+    void close(Device&, NDNBOOST_IOS::openmode)
+    {
+        using namespace detail;
+        NDNBOOST_STATIC_ASSERT(
+            (is_convertible<Mode, two_sequence>::value) ||
+            (is_convertible<Mode, dual_use>::value)
+        );
+    }
+
+    template<typename Locale>
+    void imbue(const Locale&) { }
+};
+
+template<typename Mode, typename Ch = NDNBOOST_IOSTREAMS_DEFAULT_ARG(wchar_t)>
+struct wfilter : filter<Mode, Ch> { };
+
+typedef filter<input>      input_filter;
+typedef wfilter<input>     input_wfilter;
+typedef filter<output>     output_filter;
+typedef wfilter<output>    output_wfilter;
+typedef filter<seekable>   seekable_filter;
+typedef wfilter<seekable>  seekable_wfilter;
+typedef filter<dual_use>   dual_use_filter;
+typedef wfilter<dual_use>  dual_use_wfilter;
+        
+//------Definitions of helper templates for multi-character filter cncepts----//
+
+template<typename Mode, typename Ch = char>
+struct multichar_filter : filter<Mode, Ch> {
+    struct category : filter<Mode, Ch>::category, multichar_tag { };
+};
+
+template<typename Mode, typename Ch = wchar_t>
+struct multichar_wfilter : multichar_filter<Mode, Ch> { };
+
+typedef multichar_filter<input>      multichar_input_filter;
+typedef multichar_wfilter<input>     multichar_input_wfilter;
+typedef multichar_filter<output>     multichar_output_filter;
+typedef multichar_wfilter<output>    multichar_output_wfilter;
+typedef multichar_filter<dual_use>   multichar_dual_use_filter;
+typedef multichar_wfilter<dual_use>  multichar_dual_use_wfilter;
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/constants.hpp b/include/ndnboost/iostreams/constants.hpp
new file mode 100644
index 0000000..25393d5
--- /dev/null
+++ b/include/ndnboost/iostreams/constants.hpp
@@ -0,0 +1,42 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains constants used by library.
+
+#ifndef NDNBOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#ifndef NDNBOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE
+# define NDNBOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE 4096
+#endif
+
+#ifndef NDNBOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE
+# define NDNBOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE 128
+#endif
+
+#ifndef NDNBOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE
+# define NDNBOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE 4
+#endif
+
+#include <ndnboost/iostreams/detail/ios.hpp>  // streamsize.
+
+namespace ndnboost { namespace iostreams {
+
+const std::streamsize default_device_buffer_size = 
+    NDNBOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE; 
+const std::streamsize default_filter_buffer_size = 
+    NDNBOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE;
+const std::streamsize default_pback_buffer_size = 
+    NDNBOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE;
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/copy.hpp b/include/ndnboost/iostreams/copy.hpp
new file mode 100644
index 0000000..4211c5b
--- /dev/null
+++ b/include/ndnboost/iostreams/copy.hpp
@@ -0,0 +1,252 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains: The function template copy, which reads data from a Source 
+// and writes it to a Sink until the end of the sequence is reached, returning 
+// the number of characters transfered.
+
+// The implementation is complicated by the need to handle smart adapters
+// and direct devices.
+
+#ifndef NDNBOOST_IOSTREAMS_COPY_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_COPY_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>                 // Make sure ptrdiff_t is in std.
+#include <algorithm>                        // copy, min.
+#include <cstddef>                          // ptrdiff_t.
+#include <utility>                          // pair.
+#include <ndnboost/bind.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/chain.hpp>
+#include <ndnboost/iostreams/constants.hpp>
+#include <ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp>        
+#include <ndnboost/iostreams/detail/buffer.hpp>
+#include <ndnboost/iostreams/detail/enable_if_stream.hpp>  
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>   // failure, streamsize.                   
+#include <ndnboost/iostreams/detail/resolve.hpp>                   
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations.hpp>  // read, write, close.
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/static_assert.hpp>  
+#include <ndnboost/type_traits/is_same.hpp> 
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+    // The following four overloads of copy_impl() optimize 
+    // copying in the case that one or both of the two devices
+    // models Direct (see 
+    // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
+
+// Copy from a direct source to a direct sink
+template<typename Source, typename Sink>
+std::streamsize copy_impl( Source& src, Sink& snk, 
+                           std::streamsize /* buffer_size */,
+                           mpl::true_, mpl::true_ )
+{   
+    using namespace std;
+    typedef typename char_type_of<Source>::type  char_type;
+    typedef std::pair<char_type*, char_type*>    pair_type;
+    pair_type p1 = iostreams::input_sequence(src);
+    pair_type p2 = iostreams::output_sequence(snk);
+    std::streamsize total = 
+        static_cast<std::streamsize>(
+            (std::min)(p1.second - p1.first, p2.second - p2.first)
+        );
+    std::copy(p1.first, p1.first + total, p2.first);
+    return total;
+}
+
+// Copy from a direct source to an indirect sink
+template<typename Source, typename Sink>
+std::streamsize copy_impl( Source& src, Sink& snk, 
+                           std::streamsize /* buffer_size */,
+                           mpl::true_, mpl::false_ )
+{
+    using namespace std;
+    typedef typename char_type_of<Source>::type  char_type;
+    typedef std::pair<char_type*, char_type*>    pair_type;
+    pair_type p = iostreams::input_sequence(src);
+    std::streamsize size, total;
+    for ( total = 0, size = static_cast<std::streamsize>(p.second - p.first);
+          total < size; )
+    {
+        std::streamsize amt = 
+            iostreams::write(snk, p.first + total, size - total); 
+        total += amt;
+    }
+    return total;
+}
+
+// Copy from an indirect source to a direct sink
+template<typename Source, typename Sink>
+std::streamsize copy_impl( Source& src, Sink& snk, 
+                           std::streamsize buffer_size,
+                           mpl::false_, mpl::true_ )
+{
+    typedef typename char_type_of<Source>::type  char_type;
+    typedef std::pair<char_type*, char_type*>    pair_type;
+    detail::basic_buffer<char_type>  buf(buffer_size);
+    pair_type                        p = snk.output_sequence();
+    std::streamsize                  total = 0;
+    std::ptrdiff_t                   capacity = p.second - p.first;
+    while (true) {
+        std::streamsize amt = 
+            iostreams::read(
+                src, 
+                buf.data(),
+                buffer_size < capacity - total ?
+                    buffer_size :
+                    static_cast<std::streamsize>(capacity - total)
+            );
+        if (amt == -1)
+            break;
+        std::copy(buf.data(), buf.data() + amt, p.first + total);
+        total += amt;
+    }
+    return total;
+}
+
+// Copy from an indirect source to an indirect sink
+template<typename Source, typename Sink>
+std::streamsize copy_impl( Source& src, Sink& snk, 
+                           std::streamsize buffer_size,
+                           mpl::false_, mpl::false_ )
+{ 
+    typedef typename char_type_of<Source>::type char_type;
+    detail::basic_buffer<char_type>  buf(buffer_size);
+    non_blocking_adapter<Sink>       nb(snk);
+    std::streamsize                  total = 0;
+    bool                             done = false;
+    while (!done) {
+        std::streamsize amt;
+        done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1;
+        if (amt != -1) {
+            iostreams::write(nb, buf.data(), amt);
+            total += amt;
+        }
+    }
+    return total;
+}
+
+    // The following function object is used with 
+    // ndnboost::iostreams::detail::execute() in the primary 
+    // overload of copy_impl(), below
+
+// Function object that delegates to one of the above four 
+// overloads of compl_impl()
+template<typename Source, typename Sink>
+class copy_operation {
+public:
+    typedef std::streamsize result_type;
+    copy_operation(Source& src, Sink& snk, std::streamsize buffer_size)
+        : src_(src), snk_(snk), buffer_size_(buffer_size)
+        { }
+    std::streamsize operator()() 
+    {
+        return copy_impl( src_, snk_, buffer_size_, 
+                          is_direct<Source>(), is_direct<Sink>() );
+    }
+private:
+    copy_operation& operator=(const copy_operation&);
+    Source&          src_;
+    Sink&            snk_;
+    std::streamsize  buffer_size_;
+};
+
+// Primary overload of copy_impl. Delegates to one of the above four 
+// overloads of compl_impl(), depending on which of the two given 
+// devices, if any, models Direct (see 
+// http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
+template<typename Source, typename Sink>
+std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size)
+{
+    using namespace std;
+    typedef typename char_type_of<Source>::type  src_char;
+    typedef typename char_type_of<Sink>::type    snk_char;
+    NDNBOOST_STATIC_ASSERT((is_same<src_char, snk_char>::value));
+    return detail::execute_all(
+               copy_operation<Source, Sink>(src, snk, buffer_size),
+               detail::call_close_all(src),
+               detail::call_close_all(snk)
+           );
+}
+
+} // End namespace detail.
+                    
+//------------------Definition of copy----------------------------------------//
+
+// Overload of copy() for the case where neither the source nor the sink is
+// a standard stream or stream buffer
+template<typename Source, typename Sink>
+std::streamsize
+copy( const Source& src, const Sink& snk,
+      std::streamsize buffer_size = default_device_buffer_size
+      NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
+      NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) )
+{ 
+    typedef typename char_type_of<Source>::type char_type;
+    return detail::copy_impl( detail::resolve<input, char_type>(src), 
+                              detail::resolve<output, char_type>(snk), 
+                              buffer_size ); 
+}
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+
+// Overload of copy() for the case where the source, but not the sink, is
+// a standard stream or stream buffer
+template<typename Source, typename Sink>
+std::streamsize
+copy( Source& src, const Sink& snk,
+      std::streamsize buffer_size = default_device_buffer_size
+      NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
+      NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) ) 
+{ 
+    typedef typename char_type_of<Source>::type char_type;
+    return detail::copy_impl( detail::wrap(src), 
+                              detail::resolve<output, char_type>(snk), 
+                              buffer_size );
+}
+
+// Overload of copy() for the case where the sink, but not the source, is
+// a standard stream or stream buffer
+template<typename Source, typename Sink>
+std::streamsize
+copy( const Source& src, Sink& snk,
+      std::streamsize buffer_size = default_device_buffer_size
+      NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
+      NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) 
+{ 
+    typedef typename char_type_of<Source>::type char_type;
+    return detail::copy_impl( detail::resolve<input, char_type>(src), 
+                              detail::wrap(snk), buffer_size );
+}
+
+// Overload of copy() for the case where neither the source nor the sink is
+// a standard stream or stream buffer
+template<typename Source, typename Sink>
+std::streamsize
+copy( Source& src, Sink& snk,
+      std::streamsize buffer_size = default_device_buffer_size
+      NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
+      NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) 
+{ 
+    return detail::copy_impl(detail::wrap(src), detail::wrap(snk), buffer_size);
+}
+
+#endif // #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //-----------------------//
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_COPY_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/absolute_path.hpp b/include/ndnboost/iostreams/detail/absolute_path.hpp
new file mode 100644
index 0000000..40947ec
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/absolute_path.hpp
@@ -0,0 +1,46 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/detail/execute.hpp
+ * Date:        Thu Dec 06 13:21:54 MST 2007
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the function ndnboost::iostreams::detail::absolute_path, used for 
+ * debug output for mapped files.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED
+
+#include <string>
+#include <ndnboost/iostreams/detail/config/windows_posix.hpp>
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+# include <cctype>
+#endif
+#include <ndnboost/iostreams/detail/current_directory.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+// Resolves the given path relative to the current working directory
+inline std::string absolute_path(const std::string& path)
+{
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    return path.size() && (path[0] == '/' || path[0] == '\\') ||
+           path.size() > 1 && std::isalpha(path[0]) && path[1] == ':' ?
+               path :
+               current_directory() + '\\' + path;
+#else // #ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    return path.size() && (path[0] == '/') ?
+        path :
+        current_directory() + '/' + path;
+#endif // #ifdef NDNBOOST_IOSTREAMS_WINDOWS
+}
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/access_control.hpp b/include/ndnboost/iostreams/detail/access_control.hpp
new file mode 100644
index 0000000..f06afa5
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/access_control.hpp
@@ -0,0 +1,87 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the definition of the class template access_control, which
+// allows the type of inheritance from a provided base class to be specified 
+// using a template parameter.
+
+
+#ifndef NDNBOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/mpl/identity.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+struct protected_ { };  // Represents protected inheritance.
+struct public_ { };     // Represents public inheritance.
+
+
+namespace detail {
+
+    // Implements protected inheritance.
+    template<typename U>
+    struct prot_ : protected U 
+    { 
+        prot_() { }
+        template<typename V> prot_(V v) : U(v) { }
+    };
+
+    // Implements public inheritance.
+    template<typename U> struct pub_ : public U { 
+        pub_() { }
+        template<typename V> pub_(V v) : U(v) { }
+    };
+
+//
+// Used to deduce the base type for the template access_control.
+//
+template<typename T, typename Access>
+struct access_control_base {
+    typedef int                                 bad_access_specifier;
+    typedef typename 
+            iostreams::select<  // Disambiguation for Tru64
+                ::ndnboost::is_same<
+                    Access, protected_
+                >,                              prot_<T>,
+                ::ndnboost::is_same<
+                    Access, public_
+                >,                              pub_<T>,
+                else_,                          bad_access_specifier
+            >::type                             type;
+};
+
+} // End namespace detail.
+
+//
+// Template name: access_control.
+// Description: Allows the type of inheritance from a provided base class
+//      to be specified using an int template parameter.
+// Template parameters:
+//      Base - The class from which to inherit (indirectly.)
+//      Access - The type of access desired. Must be one of the 
+//          values access_base::prot or access_base::pub.
+//
+template< typename T, typename Access,
+          typename Base = // VC6 workaraound (Compiler Error C2516)
+              typename detail::access_control_base<T, Access>::type >
+struct access_control : public Base { 
+    access_control() { }
+    template<typename U> explicit access_control(U u) : Base(u) { }
+};
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/adapter/concept_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/concept_adapter.hpp
new file mode 100644
index 0000000..d182bee
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/concept_adapter.hpp
@@ -0,0 +1,287 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>                             // SFINAE.
+#include <ndnboost/iostreams/concepts.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp>
+#include <ndnboost/iostreams/detail/call_traits.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/error.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp>        // pubsync.
+#include <ndnboost/iostreams/detail/config/unreachable_return.hpp>
+#include <ndnboost/iostreams/device/null.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Category> struct device_wrapper_impl;
+template<typename Category> struct flt_wrapper_impl;
+
+template<typename T>
+class concept_adapter {
+private:
+    typedef typename detail::value_type<T>::type       value_type;
+    typedef typename dispatch<T, input, output>::type  input_tag;
+    typedef typename dispatch<T, output, input>::type  output_tag;
+    typedef typename
+            mpl::if_<
+                is_device<T>,
+                device_wrapper_impl<input_tag>,
+                flt_wrapper_impl<input_tag>
+            >::type                                    input_impl;
+    typedef typename
+            mpl::if_<
+                is_device<T>,
+                device_wrapper_impl<output_tag>,
+                flt_wrapper_impl<output_tag>
+            >::type                                    output_impl;
+    typedef typename
+            mpl::if_<
+                is_device<T>,
+                device_wrapper_impl<any_tag>,
+                flt_wrapper_impl<any_tag>
+            >::type                                    any_impl;
+public:
+    typedef typename char_type_of<T>::type             char_type;
+    typedef typename category_of<T>::type              category;
+
+    explicit concept_adapter(const reference_wrapper<T>& ref) : t_(ref.get())
+    { NDNBOOST_STATIC_ASSERT(is_std_io<T>::value); }
+    explicit concept_adapter(const T& t) : t_(t)
+    { NDNBOOST_STATIC_ASSERT(!is_std_io<T>::value); }
+
+    T& operator*() { return t_; }
+    T* operator->() { return &t_; }
+
+    std::streamsize read(char_type* s, std::streamsize n)
+    { return this->read(s, n, (basic_null_source<char_type>*) 0); }
+
+    template<typename Source>
+    std::streamsize read(char_type* s, std::streamsize n, Source* src)
+    { return input_impl::read(t_, src, s, n); }
+
+    std::streamsize write(const char_type* s, std::streamsize n)
+    { return this->write(s, n, (basic_null_sink<char_type>*) 0); }
+
+    template<typename Sink>
+    std::streamsize write(const char_type* s, std::streamsize n, Sink* snk)
+    { return output_impl::write(t_, snk, s, n); }
+
+    std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way,
+                         NDNBOOST_IOS::openmode which )
+    { 
+        return this->seek( off, way, which, 
+                           (basic_null_device<char_type, seekable>*) 0); 
+    }
+
+    template<typename Device>
+    std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way,
+                         NDNBOOST_IOS::openmode which, Device* dev )
+    { return any_impl::seek(t_, dev, off, way, which); }
+
+    void close(NDNBOOST_IOS::openmode which)
+    { this->close(which, (basic_null_device<char_type, seekable>*) 0); }
+
+    template<typename Device>
+    void close(NDNBOOST_IOS::openmode which, Device* dev)
+    { any_impl::close(t_, dev, which); }
+
+    template<typename Device>
+    bool flush( Device* dev )
+    {
+        bool result = any_impl::flush(t_, dev);
+        if (dev && dev->NDNBOOST_IOSTREAMS_PUBSYNC() == -1)
+            result = false;
+        return result;
+    }
+
+    template<typename Locale> // Avoid dependency on <locale>
+    void imbue(const Locale& loc) { iostreams::imbue(t_, loc); }
+
+    std::streamsize optimal_buffer_size() const
+    { return iostreams::optimal_buffer_size(t_); }
+public:
+    concept_adapter& operator=(const concept_adapter&);
+    value_type t_;
+};
+
+//------------------Specializations of device_wrapper_impl--------------------//
+
+template<>
+struct device_wrapper_impl<any_tag> {
+    template<typename Device, typename Dummy>
+    static std::streampos 
+    seek( Device& dev, Dummy*, stream_offset off, 
+          NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which )
+    { 
+        typedef typename category_of<Device>::type category;
+        return seek(dev, off, way, which, category()); 
+    }
+
+    template<typename Device>
+    static std::streampos 
+    seek( Device&, stream_offset, NDNBOOST_IOS::seekdir, 
+          NDNBOOST_IOS::openmode, any_tag )
+    { 
+        ndnboost::throw_exception(cant_seek());
+        NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0)
+    }
+
+    template<typename Device>
+    static std::streampos 
+    seek( Device& dev, stream_offset off, 
+          NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which, 
+          random_access )
+    { 
+        return iostreams::seek(dev, off, way, which); 
+    }
+
+    template<typename Device, typename Dummy>
+    static void close(Device& dev, Dummy*, NDNBOOST_IOS::openmode which)
+    { iostreams::close(dev, which); }
+
+    template<typename Device, typename Dummy>
+    static bool flush(Device& dev, Dummy*)
+    { return iostreams::flush(dev); }
+};
+
+
+template<>
+struct device_wrapper_impl<input> : device_wrapper_impl<any_tag>  {
+    template<typename Device, typename Dummy>
+    static std::streamsize
+    read( Device& dev, Dummy*, typename char_type_of<Device>::type* s,
+          std::streamsize n )
+    { return iostreams::read(dev, s, n); }
+
+    template<typename Device, typename Dummy>
+    static std::streamsize 
+    write( Device&, Dummy*, const typename char_type_of<Device>::type*,
+           std::streamsize )
+    { ndnboost::throw_exception(cant_write());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+};
+
+template<>
+struct device_wrapper_impl<output> {
+    template<typename Device, typename Dummy>
+    static std::streamsize
+    read(Device&, Dummy*, typename char_type_of<Device>::type*, std::streamsize)
+    { ndnboost::throw_exception(cant_read());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+
+    template<typename Device, typename Dummy>
+    static std::streamsize 
+    write( Device& dev, Dummy*, const typename char_type_of<Device>::type* s,
+           std::streamsize n )
+    { return iostreams::write(dev, s, n); }
+};
+
+//------------------Specializations of flt_wrapper_impl--------------------//
+
+template<>
+struct flt_wrapper_impl<any_tag> {
+    template<typename Filter, typename Device>
+    static std::streampos
+    seek( Filter& f, Device* dev, stream_offset off,
+          NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which )
+    {
+        typedef typename category_of<Filter>::type category;
+        return seek(f, dev, off, way, which, category());
+    }
+
+    template<typename Filter, typename Device>
+    static std::streampos
+    seek( Filter&, Device*, stream_offset,
+          NDNBOOST_IOS::seekdir, NDNBOOST_IOS::openmode, any_tag )
+    { ndnboost::throw_exception(cant_seek());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+
+    template<typename Filter, typename Device>
+    static std::streampos
+    seek( Filter& f, Device* dev, stream_offset off,
+          NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which,
+          random_access tag )
+    {
+        typedef typename category_of<Filter>::type category;
+        return seek(f, dev, off, way, which, tag, category());
+    }
+
+    template<typename Filter, typename Device>
+    static std::streampos
+    seek( Filter& f, Device* dev, stream_offset off,
+          NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode,
+          random_access, any_tag )
+    { return f.seek(*dev, off, way); }
+
+    template<typename Filter, typename Device>
+    static std::streampos
+    seek( Filter& f, Device* dev, stream_offset off,
+          NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which,
+          random_access, two_sequence )
+    { return f.seek(*dev, off, way, which);  }
+
+    template<typename Filter, typename Device>
+    static void close(Filter& f, Device* dev, NDNBOOST_IOS::openmode which)
+    { iostreams::close(f, *dev, which); }
+
+    template<typename Filter, typename Device>
+    static bool flush(Filter& f, Device* dev)
+    { return iostreams::flush(f, *dev); }
+};
+
+template<>
+struct flt_wrapper_impl<input> {
+    template<typename Filter, typename Source>
+    static std::streamsize
+    read( Filter& f, Source* src, typename char_type_of<Filter>::type* s,
+          std::streamsize n )
+    { return iostreams::read(f, *src, s, n); }
+
+    template<typename Filter, typename Sink>
+    static std::streamsize 
+    write( Filter&, Sink*, const typename char_type_of<Filter>::type*, 
+           std::streamsize )
+    { ndnboost::throw_exception(cant_write());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+};
+
+template<>
+struct flt_wrapper_impl<output> {
+    template<typename Filter, typename Source>
+    static std::streamsize
+    read(Filter&, Source*, typename char_type_of<Filter>::type*,std::streamsize)
+    { ndnboost::throw_exception(cant_read());
+      NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
+
+    template<typename Filter, typename Sink>
+    static std::streamsize 
+    write( Filter& f, Sink* snk, const typename char_type_of<Filter>::type* s,
+           std::streamsize n )
+    { return iostreams::write(f, *snk, s, n); }
+};
+
+//----------------------------------------------------------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/adapter/device_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/device_adapter.hpp
new file mode 100644
index 0000000..aa82c7a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/device_adapter.hpp
@@ -0,0 +1,67 @@
+/*
+ * Defines the class template ndnboost::iostreams::detail::device_adapter,
+ * a convenience base class for device adapters.
+ *
+ * File:        ndnboost/iostreams/detail/adapter/filter_adapter.hpp
+ * Date:        Mon Nov 26 14:35:48 MST 2007
+ * 
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED
+
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/call_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/static_assert.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename T>
+class device_adapter {
+private:
+    typedef typename detail::value_type<T>::type value_type;
+    typedef typename detail::param_type<T>::type param_type;
+public:
+    explicit device_adapter(param_type t) : t_(t) { }
+    T& component() { return t_; }
+
+    void close() 
+    {
+        detail::close_all(t_);
+    }
+
+    void close(NDNBOOST_IOS::openmode which) 
+    { 
+        iostreams::close(t_, which); 
+    }
+
+    bool flush() 
+    { 
+        return iostreams::flush(t_); 
+    }
+
+    template<typename Locale> // Avoid dependency on <locale>
+    void imbue(const Locale& loc) { iostreams::imbue(t_, loc); }
+
+    std::streamsize optimal_buffer_size() const 
+    { return iostreams::optimal_buffer_size(t_); }
+public:
+    value_type t_;
+};
+
+//----------------------------------------------------------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/adapter/direct_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/direct_adapter.hpp
new file mode 100644
index 0000000..99eebf9
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/direct_adapter.hpp
@@ -0,0 +1,281 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>       // SFINAE, MSVC, put ptrdiff_t in std.
+#include <algorithm>              // copy, min.
+#include <cstddef>                // ptrdiff_t.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/config/limits.hpp>        // forwarding.
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>  // locale.
+#include <ndnboost/iostreams/detail/double_object.hpp>
+#include <ndnboost/iostreams/detail/error.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // openmode, seekdir, int types.
+#include <ndnboost/iostreams/traits.hpp>      // mode_of, is_direct.
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/mpl/bool.hpp> 
+#include <ndnboost/mpl/or.hpp> 
+#include <ndnboost/preprocessor/iteration/local.hpp>
+#include <ndnboost/preprocessor/repetition/enum_binary_params.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // VC7.1
+
+namespace ndnboost { namespace iostreams { namespace detail {
+                    
+//------------------Definition of direct_adapter_base-------------------------//
+
+// Put all initialization in base class to faciliate forwarding.
+template<typename Direct>
+class direct_adapter_base {
+public:
+    typedef typename char_type_of<Direct>::type  char_type;
+    typedef typename mode_of<Direct>::type       mode_type;
+    struct category 
+        : mode_type,
+          device_tag,
+          closable_tag
+          #ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+          , localizable_tag
+          #endif
+        { };
+protected:
+    explicit direct_adapter_base(const Direct& d);
+    typedef is_convertible<category, two_sequence> is_double;
+    struct pointers {
+        char_type *beg, *ptr, *end;
+    };
+    void init_input(mpl::true_);
+    void init_input(mpl::false_) { }
+    void init_output(mpl::true_);
+    void init_output(mpl::false_) { }
+    double_object<pointers, is_double>  ptrs_;
+    Direct                              d_;
+};
+
+template<typename Direct>
+class direct_adapter : private direct_adapter_base<Direct> {
+private:
+    typedef direct_adapter_base<Direct>      base_type;
+    typedef typename base_type::pointers     pointers;
+    typedef typename base_type::is_double    is_double;
+    using base_type::ptrs_;
+    using base_type::d_;
+public:
+    typedef typename base_type::char_type    char_type;
+    typedef typename base_type::category     category;
+
+        // Constructors
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1310)
+    direct_adapter(const Direct& d) : base_type(d) { }   
+    direct_adapter(const direct_adapter& d) : base_type(d) { }
+# define NDNBOOST_PP_LOCAL_LIMITS (1, NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
+#else
+    template<typename U>
+    struct is_direct
+        : mpl::or_< 
+              is_same<U, direct_adapter<Direct> >, 
+              is_same<U, Direct> 
+          >
+        { };
+    template<typename U>
+    direct_adapter(const U& u) 
+        : base_type(forward(u, is_direct<U>()))
+        { }
+# define NDNBOOST_PP_LOCAL_LIMITS (2, NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
+#endif
+
+#define NDNBOOST_PP_LOCAL_MACRO(n) \
+    template<NDNBOOST_PP_ENUM_PARAMS(n, typename P)> \
+    direct_adapter(NDNBOOST_PP_ENUM_BINARY_PARAMS(n, const P, &p)) \
+        : base_type(Direct(NDNBOOST_PP_ENUM_PARAMS(n, p))) \
+        { } \
+    /**/
+#include NDNBOOST_PP_LOCAL_ITERATE()
+#undef NDNBOOST_PP_LOCAL_MACRO
+
+        // Device interface.
+
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek( stream_offset, NDNBOOST_IOS::seekdir,
+                         NDNBOOST_IOS::openmode = NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+    void close();
+    void close(NDNBOOST_IOS::openmode which);
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+    void imbue(const std::locale&);
+#endif
+
+        // Direct device access.
+
+    Direct& operator*() { return d_; }
+    Direct* operator->() { return &d_; }
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1310)
+private:
+    template<typename U>
+    static Direct forward(const U& u, mpl::true_) { return u; }
+    template<typename U>
+    static Direct forward(const U& u, mpl::false_) { return Direct(u); }
+#endif
+};
+
+//--------------Definition of wrap_direct and unwrap_direct-------------------//
+
+template<typename Device>
+struct wrap_direct_traits 
+    : mpl::if_<
+          is_direct<Device>,
+          direct_adapter<Device>,
+          Device
+      >
+    { };
+
+template<typename Device>
+typename wrap_direct_traits<Device>::type
+inline wrap_direct(Device dev) 
+{ 
+    typedef typename wrap_direct_traits<Device>::type type;
+    return type(dev); 
+}
+
+template<typename Device>
+inline Device& unwrap_direct(Device& d) { return d; }  
+
+template<typename Device>
+inline Device& unwrap_direct(direct_adapter<Device>& d) { return *d; }  
+
+//--------------Implementation of direct_adapter_base-------------------------//
+
+template<typename Direct>
+direct_adapter_base<Direct>::direct_adapter_base(const Direct& d) : d_(d)
+{
+    init_input(is_convertible<category, input>());
+    init_output(is_convertible<category, output>());
+}
+
+template<typename Direct>
+void direct_adapter_base<Direct>::init_input(mpl::true_) 
+{
+    std::pair<char_type*, char_type*> seq = iostreams::input_sequence(d_);
+    ptrs_.first().beg = seq.first;
+    ptrs_.first().ptr = seq.first;
+    ptrs_.first().end = seq.second;
+}
+
+template<typename Direct>
+void direct_adapter_base<Direct>::init_output(mpl::true_) 
+{
+    std::pair<char_type*, char_type*> seq = iostreams::output_sequence(d_);
+    ptrs_.second().beg = seq.first;
+    ptrs_.second().ptr = seq.first;
+    ptrs_.second().end = seq.second;
+}
+
+//--------------Implementation of direct_adapter------------------------------//
+
+template<typename Direct>
+inline std::streamsize direct_adapter<Direct>::read
+    (char_type* s, std::streamsize n)
+{
+    using namespace std;
+    pointers& get = ptrs_.first();
+    std::streamsize avail = 
+        static_cast<std::streamsize>(get.end - get.ptr);
+    std::streamsize result = (std::min)(n, avail);
+    std::copy(get.ptr, get.ptr + result, s);
+    get.ptr += result;
+    return result != 0 ? result : -1;
+}
+
+template<typename Direct>
+inline std::streamsize direct_adapter<Direct>::write
+    (const char_type* s, std::streamsize n)
+{
+    using namespace std;
+    pointers& put = ptrs_.second();
+    if (n > static_cast<std::streamsize>(put.end - put.ptr))
+        ndnboost::throw_exception(write_area_exhausted());
+    std::copy(s, s + n, put.ptr);
+    put.ptr += n;
+    return n;
+}
+
+template<typename Direct>
+inline std::streampos direct_adapter<Direct>::seek
+    ( stream_offset off, NDNBOOST_IOS::seekdir way, 
+      NDNBOOST_IOS::openmode which )
+{
+    using namespace std;
+    pointers& get = ptrs_.first();
+    pointers& put = ptrs_.second();
+    if (way == NDNBOOST_IOS::cur && get.ptr != put.ptr)
+       ndnboost::throw_exception(bad_seek());
+    ptrdiff_t next = 0;
+    if ((which & NDNBOOST_IOS::in) || !is_double::value) {
+        if (way == NDNBOOST_IOS::beg)
+            next = off; 
+        else if (way == NDNBOOST_IOS::cur)
+            next = get.ptr - get.beg + off; 
+        else
+            next = get.end - get.beg + off; 
+        if (next >= 0 && next <= get.end - get.beg)
+            get.ptr = get.beg + next;
+        else
+            ndnboost::throw_exception(bad_seek());
+    }
+    if ((which & NDNBOOST_IOS::out) && is_double::value) {
+        if (way == NDNBOOST_IOS::beg)
+            next = off; 
+        else if (way == NDNBOOST_IOS::cur)
+            next = put.ptr - put.beg + off; 
+        else
+            next = put.end - put.beg + off; 
+        if (next >= 0 && next <= put.end - put.beg)
+            put.ptr = put.beg + next;
+        else
+            ndnboost::throw_exception(bad_seek());
+    }
+    return offset_to_position(next);
+}
+
+template<typename Direct>
+void direct_adapter<Direct>::close() 
+{ 
+    NDNBOOST_STATIC_ASSERT((!is_convertible<category, two_sequence>::value));
+    detail::close_all(d_);
+}
+
+template<typename Direct>
+void direct_adapter<Direct>::close(NDNBOOST_IOS::openmode which) 
+{ 
+    NDNBOOST_STATIC_ASSERT((is_convertible<category, two_sequence>::value));
+    ndnboost::iostreams::close(d_, which);
+}
+
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+    template<typename Direct>
+    void direct_adapter<Direct>::imbue(const std::locale& loc) 
+    { ndnboost::iostreams::imbue(d_, loc); }
+#endif
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/adapter/filter_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/filter_adapter.hpp
new file mode 100644
index 0000000..fec4c45
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/filter_adapter.hpp
@@ -0,0 +1,69 @@
+/*
+ * Defines the class template ndnboost::iostreams::detail::filter_adapter,
+ * a convenience base class for filter adapters.
+ *
+ * File:        ndnboost/iostreams/detail/adapter/filter_adapter.hpp
+ * Date:        Mon Nov 26 14:35:48 MST 2007
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED
+
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/call_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/static_assert.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename T>
+class filter_adapter {
+private:
+    typedef typename detail::value_type<T>::type value_type;
+    typedef typename detail::param_type<T>::type param_type;
+public:
+    explicit filter_adapter(param_type t) : t_(t) { }
+    T& component() { return t_; }
+
+    template<typename Device>
+    void close(Device& dev) 
+    { 
+        detail::close_all(t_, dev); 
+    }
+
+    template<typename Device>
+    void close(Device& dev, NDNBOOST_IOS::openmode which) 
+    { 
+        iostreams::close(t_, dev, which); 
+    }
+
+    template<typename Device>
+    void flush(Device& dev) 
+    { 
+        return iostreams::flush(t_, dev); 
+    }
+
+    template<typename Locale> // Avoid dependency on <locale>
+    void imbue(const Locale& loc) { iostreams::imbue(t_, loc); }
+
+    std::streamsize optimal_buffer_size() const 
+    { return iostreams::optimal_buffer_size(t_); }
+public:
+    value_type t_;
+};
+
+//----------------------------------------------------------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/adapter/mode_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/mode_adapter.hpp
new file mode 100644
index 0000000..46d5b64
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/mode_adapter.hpp
@@ -0,0 +1,123 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+// Contains the definition of the class template mode_adapter, which allows
+// a filter or device to function as if it has a different i/o mode than that
+// deduced by the metafunction mode_of.
+
+#include <ndnboost/config.hpp>                // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // openmode, seekdir, int types. 
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/operations.hpp> 
+#include <ndnboost/mpl/if.hpp> 
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Mode, typename T>
+class mode_adapter {
+private:
+    struct empty_base { };
+public:
+    typedef typename wrapped_type<T>::type  component_type;
+    typedef typename char_type_of<T>::type  char_type;
+    struct category 
+        : Mode, 
+          device_tag,
+          mpl::if_<is_filter<T>, filter_tag, device_tag>,
+          mpl::if_<is_filter<T>, multichar_tag, empty_base>,
+          #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+              closable_tag, // VC6 can't see member close()!
+          #endif
+          localizable_tag
+        { };
+    explicit mode_adapter(const component_type& t) : t_(t) { }
+
+        // Device member functions.
+
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way,
+                         NDNBOOST_IOS::openmode which = 
+                             NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+    void close();
+    void close(NDNBOOST_IOS::openmode which);
+#endif
+
+        // Filter member functions.
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    { return iostreams::read(t_, src, s, n); }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    { return iostreams::write(t_, snk, s, n); }
+
+    template<typename Device>
+    std::streampos seek(Device& dev, stream_offset off, NDNBOOST_IOS::seekdir way)
+    { return iostreams::seek(t_, dev, off, way); }
+
+    template<typename Device>
+    std::streampos seek( Device& dev, stream_offset off, 
+                         NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which  )
+    { return iostreams::seek(t_, dev, off, way, which); }
+
+    template<typename Device>
+    void close(Device& dev)
+    { detail::close_all(t_, dev); }
+
+    template<typename Device>
+    void close(Device& dev, NDNBOOST_IOS::openmode which)
+    { iostreams::close(t_, dev, which); }
+
+    template<typename Locale>
+    void imbue(const Locale& loc)
+    { iostreams::imbue(t_, loc); }
+private:
+    component_type t_;
+};
+                    
+//------------------Implementation of mode_adapter----------------------------//
+
+template<typename Mode, typename T>
+std::streamsize mode_adapter<Mode, T>::read
+    (char_type* s, std::streamsize n)
+{ return ndnboost::iostreams::read(t_, s, n); }
+
+template<typename Mode, typename T>
+std::streamsize mode_adapter<Mode, T>::write
+    (const char_type* s, std::streamsize n)
+{ return ndnboost::iostreams::write(t_, s, n); }
+
+template<typename Mode, typename T>
+std::streampos mode_adapter<Mode, T>::seek
+    (stream_offset off, NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which)
+{ return ndnboost::iostreams::seek(t_, off, way, which); }
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+    template<typename Mode, typename T>
+    void mode_adapter<Mode, T>::close() 
+    { detail::close_all(t_); }
+
+    template<typename Mode, typename T>
+    void mode_adapter<Mode, T>::close(NDNBOOST_IOS::openmode which) 
+    { iostreams::close(t_, which); }
+#endif
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED //-----//
diff --git a/include/ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp
new file mode 100644
index 0000000..1ba070c
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp
@@ -0,0 +1,59 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED
+
+#include <ndnboost/iostreams/detail/ios.hpp>  // streamsize, seekdir, openmode.
+#include <ndnboost/iostreams/read.hpp>
+#include <ndnboost/iostreams/seek.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/write.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template<typename Device>
+class non_blocking_adapter {
+public:
+    typedef typename char_type_of<Device>::type char_type;
+    struct category
+        : mode_of<Device>::type, device_tag
+        { };
+    explicit non_blocking_adapter(Device& dev) : device_(dev) { }
+    std::streamsize read(char_type* s, std::streamsize n)
+    { 
+        std::streamsize result = 0;
+        while (result < n) {
+            std::streamsize amt = iostreams::read(device_, s, n);
+            if (amt == -1)
+                break;
+            result += amt;
+        }
+        return result != 0 ? result : -1;
+    }
+    std::streamsize write(const char_type* s, std::streamsize n)
+    { 
+        std::streamsize result = 0;
+        while (result < n) {
+            std::streamsize amt = 
+                iostreams::write(device_, s + result, n - result);
+            result += amt;
+        }
+        return result;    
+    }
+    std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way,
+                         NDNBOOST_IOS::openmode which = 
+                             NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+    { return iostreams::seek(device_, off, way, which); }
+public:
+    non_blocking_adapter& operator=(const non_blocking_adapter&);
+    Device& device_;
+};
+
+} } // End namespace iostreams.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/adapter/output_iterator_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/output_iterator_adapter.hpp
new file mode 100644
index 0000000..d9b6929
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/output_iterator_adapter.hpp
@@ -0,0 +1,41 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <algorithm>                      // copy.
+#include <iosfwd>                         // streamsize.
+#include <ndnboost/iostreams/categories.hpp> // tags.
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Mode, typename Ch, typename OutIt>
+class output_iterator_adapter {
+public:
+    NDNBOOST_STATIC_ASSERT((is_convertible<Mode, output>::value));
+    typedef Ch        char_type;
+    typedef sink_tag  category;
+    explicit output_iterator_adapter(OutIt out) : out_(out) { }
+    std::streamsize write(const char_type* s, std::streamsize n) 
+    { 
+        std::copy(s, s + n, out_); 
+        return n; 
+    }
+private:
+    OutIt out_;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED //-----//
diff --git a/include/ndnboost/iostreams/detail/adapter/range_adapter.hpp b/include/ndnboost/iostreams/detail/adapter/range_adapter.hpp
new file mode 100644
index 0000000..3789489
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/adapter/range_adapter.hpp
@@ -0,0 +1,187 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <algorithm>                             // min.
+#include <ndnboost/assert.hpp>
+#include <cstddef>                               // ptrdiff_t.
+#include <iosfwd>                                // streamsize, streamoff.
+#include <ndnboost/detail/iterator.hpp>             // ndnboost::iterator_traits.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/error.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+// Used for simulated tag dispatch.
+template<typename Traversal> struct range_adapter_impl;
+
+//
+// Template name: range_adapter
+// Description: Device based on an instance of ndnboost::iterator_range.
+// Template parameters:
+//     Mode - A mode tag.
+//     Range - An instance of iterator_range.
+//
+template<typename Mode, typename Range>
+class range_adapter {
+private:
+    typedef typename Range::iterator                  iterator;
+    typedef ndnboost::detail::iterator_traits<iterator>  iter_traits;
+    typedef typename iter_traits::iterator_category   iter_cat;
+public:
+    typedef typename Range::value_type                char_type;
+    struct category : Mode, device_tag { };
+    typedef typename
+            mpl::if_<
+                is_convertible<
+                    iter_cat,
+                    std::random_access_iterator_tag
+                >,
+                std::random_access_iterator_tag,
+                std::forward_iterator_tag
+            >::type                                   tag;
+    typedef range_adapter_impl<tag>                   impl;
+
+    explicit range_adapter(const Range& rng);
+    range_adapter(iterator first, iterator last);
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek(stream_offset off, NDNBOOST_IOS::seekdir way);
+private:
+    iterator first_, cur_, last_;
+};
+
+//------------------Implementation of range_adapter---------------------------//
+
+template<typename Mode, typename Range>
+range_adapter<Mode, Range>::range_adapter(const Range& rng)
+    : first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { }
+
+template<typename Mode, typename Range>
+range_adapter<Mode, Range>::range_adapter(iterator first, iterator last)
+    : first_(first), cur_(first), last_(last) { }
+
+template<typename Mode, typename Range>
+inline std::streamsize range_adapter<Mode, Range>::read
+    (char_type* s, std::streamsize n)
+{ return impl::read(cur_, last_, s, n); }
+
+template<typename Mode, typename Range>
+inline std::streamsize range_adapter<Mode, Range>::write
+    (const char_type* s, std::streamsize n)
+{ return impl::write(cur_, last_, s, n); }
+
+
+template<typename Mode, typename Range>
+std::streampos range_adapter<Mode, Range>::seek
+    (stream_offset off, NDNBOOST_IOS::seekdir way)
+{ 
+    impl::seek(first_, cur_, last_, off, way); 
+    return offset_to_position(cur_ - first_);
+}
+
+//------------------Implementation of range_adapter_impl----------------------//
+
+template<>
+struct range_adapter_impl<std::forward_iterator_tag> {
+    template<typename Iter, typename Ch>
+    static std::streamsize read
+        (Iter& cur, Iter& last, Ch* s,std::streamsize n)
+    {
+        std::streamsize rem = n; // No. of chars remaining.
+        while (cur != last && rem-- > 0) *s++ = *cur++;
+        return n - rem != 0 ? n - rem : -1;
+    }
+
+    template<typename Iter, typename Ch>
+    static std::streamsize write
+        (Iter& cur, Iter& last, const Ch* s, std::streamsize n)
+    {
+        while (cur != last && n-- > 0) *cur++ = *s++;
+        if (cur == last && n > 0)
+            ndnboost::throw_exception(write_area_exhausted());
+        return n;
+    }
+};
+
+template<>
+struct range_adapter_impl<std::random_access_iterator_tag> {
+    template<typename Iter, typename Ch>
+    static std::streamsize read
+        (Iter& cur, Iter& last, Ch* s,std::streamsize n)
+    {
+        std::streamsize result = 
+            (std::min)(static_cast<std::streamsize>(last - cur), n);
+        if (result)
+            std::copy(cur, cur + result, s);
+        cur += result;
+        return result != 0 ? result : -1;
+    }
+
+    template<typename Iter, typename Ch>
+    static std::streamsize write
+        (Iter& cur, Iter& last, const Ch* s, std::streamsize n)
+    {
+        std::streamsize count =
+            (std::min)(static_cast<std::streamsize>(last - cur), n);
+        std::copy(s, s + count, cur);
+        cur += count;
+        if (count < n) 
+            ndnboost::throw_exception(write_area_exhausted());
+        return n;
+    }
+
+    template<typename Iter>
+    static void seek
+        ( Iter& first, Iter& cur, Iter& last, stream_offset off,
+          NDNBOOST_IOS::seekdir way )
+    {
+        using namespace std;
+        switch (way) {
+        case NDNBOOST_IOS::beg:
+            if (off > last - first || off < 0)
+                ndnboost::throw_exception(bad_seek());
+            cur = first + off;
+            break;
+        case NDNBOOST_IOS::cur:
+            {
+                std::ptrdiff_t newoff = cur - first + off;
+                if (newoff > last - first || newoff < 0)
+                    ndnboost::throw_exception(bad_seek());
+                cur += off;
+                break;
+            }
+        case NDNBOOST_IOS::end:
+            if (last - first + off < 0 || off > 0)
+                ndnboost::throw_exception(bad_seek());
+            cur = last + off;
+            break;
+        default:
+            NDNBOOST_ASSERT(0);
+        }
+    }
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------//
diff --git a/include/ndnboost/iostreams/detail/add_facet.hpp b/include/ndnboost/iostreams/detail/add_facet.hpp
new file mode 100644
index 0000000..32aa534
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/add_facet.hpp
@@ -0,0 +1,49 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Borrowed from <ndnboost/archive/add_facet.hpp>
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // NDNBOOST_DINKUMWARE_STDLIB.
+#include <ndnboost/detail/workaround.hpp>
+
+//------------------Definition of add_facet-----------------------------------//
+
+// Does STLport uses old Dinkumware locale?
+#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && \
+    defined(_STLP_NO_OWN_IOSTREAMS) \
+    /**/
+#  if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
+#    define NDNBOOST_IOSTREMS_STLPORT_WITH_OLD_DINKUMWARE
+#  endif
+#endif
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<class Facet>
+inline std::locale add_facet(const std::locale &l, Facet * f)
+{
+    return
+        #if NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) || \
+            defined(NDNBOOST_IOSTREMS_STLPORT_WITH_OLD_DINKUMWARE) \
+            /**/
+            std::locale(std::_Addfac(l, f));
+        #else
+            // standard compatible
+            std::locale(l, f);
+        #endif
+}
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/bool_trait_def.hpp b/include/ndnboost/iostreams/detail/bool_trait_def.hpp
new file mode 100644
index 0000000..361fa23
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/bool_trait_def.hpp
@@ -0,0 +1,49 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED     
+
+#include <ndnboost/config.hpp> // NDNBOOST_STATIC_CONSTANT.
+#include <ndnboost/iostreams/detail/template_params.hpp>
+#include <ndnboost/mpl/aux_/lambda_support.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/preprocessor/cat.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+#include <ndnboost/type_traits/detail/yes_no_type.hpp>
+ 
+// 
+// Macro name: NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF
+// Description: Used to generate the traits classes is_istream, is_ostream,
+//      etc.
+//
+#if NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x582))
+# define NDNBOOST_IOSTREAMS_TRAIT_NAMESPACE(trait)
+#else
+# define NDNBOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) NDNBOOST_PP_CAT(trait, _impl_):: 
+#endif
+#define NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(trait, type, arity) \
+    namespace NDNBOOST_PP_CAT(trait, _impl_) { \
+      NDNBOOST_IOSTREAMS_TEMPLATE_PARAMS(arity, T) \
+      type_traits::yes_type helper \
+          (const volatile type NDNBOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)*); \
+      type_traits::no_type helper(...); \
+      template<typename T> \
+      struct impl { \
+           NDNBOOST_STATIC_CONSTANT(bool, value = \
+           (sizeof(NDNBOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) \
+              helper(static_cast<T*>(0))) == \
+                sizeof(type_traits::yes_type))); \
+      }; \
+    } \
+    template<typename T> \
+    struct trait \
+        : mpl::bool_<NDNBOOST_PP_CAT(trait, _impl_)::impl<T>::value> \
+    { NDNBOOST_MPL_AUX_LAMBDA_SUPPORT(1, trait, (T)) }; \
+    /**/
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/broken_overload_resolution/forward.hpp b/include/ndnboost/iostreams/detail/broken_overload_resolution/forward.hpp
new file mode 100644
index 0000000..a2081ad
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/broken_overload_resolution/forward.hpp
@@ -0,0 +1,31 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>                     // NDNBOOST_STATIC_CONSANT.
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Device, typename U>
+struct forward_impl {
+    NDNBOOST_STATIC_CONSTANT(bool, value =
+        ( !is_same< U, Device >::value &&
+          !is_same< U, reference_wrapper<Device> >::value ));
+};
+
+template<typename Device, typename U>
+struct forward
+    : mpl::bool_<forward_impl<Device, U>::value>
+    { };
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/broken_overload_resolution/stream.hpp b/include/ndnboost/iostreams/detail/broken_overload_resolution/stream.hpp
new file mode 100644
index 0000000..6485f1f
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/broken_overload_resolution/stream.hpp
@@ -0,0 +1,184 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED
+
+#include <ndnboost/iostreams/detail/broken_overload_resolution/forward.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template< typename Device,
+          typename Tr =
+              NDNBOOST_IOSTREAMS_CHAR_TRAITS(
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+              ),
+          typename Alloc =
+              std::allocator<
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+              > >
+struct stream : detail::stream_base<Device, Tr, Alloc> {
+public:
+    typedef typename char_type_of<Device>::type  char_type;
+    struct category 
+        : mode_of<Device>::type,
+          closable_tag,
+          detail::stream_traits<Device, Tr>::stream_tag
+        { };
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+private:
+    typedef typename
+            detail::stream_traits<
+                Device, Tr
+            >::stream_type                       stream_type;
+public:
+    stream() { }
+    template<typename U0>
+    stream(const U0& u0)
+    {
+        open_impl(detail::forward<Device, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    stream(const U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    stream(const U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1, u2);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    stream(U0& u0)
+    {
+        open_impl(detail::forward<Device, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    stream(U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    stream(U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1, u2);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0>
+    void open(const U0& u0)
+    {
+        open_impl(detail::forward<Device, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    void open(const U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    void open(const U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1, u2);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    void open(U0& u0)
+    {
+        open_impl(detail::forward<Device, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    void open(U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    void open(U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<Device, U0>(), u0, u1, u2);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    bool is_open() const { return this->member.is_open(); }
+    void close() { this->member.close(); }
+    bool auto_close() const { return this->member.auto_close(); }
+    void set_auto_close(bool close) { this->member.set_auto_close(close); }
+    bool strict_sync() { return this->member.strict_sync(); }
+    Device& operator*() { return *this->member; }
+    Device* operator->() { return &*this->member; }
+private:
+    template<typename U0>
+    void open_impl(mpl::false_, const U0& u0)
+    {
+        this->clear(); 
+        this->member.open(u0);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    void open_impl(mpl::false_, U0& u0)
+    {
+        this->clear(); 
+        this->member.open(detail::wrap(u0));
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0>
+    void open_impl(mpl::true_, const U0& u0)
+    {
+        this->clear(); 
+        this->member.open(Device(const_cast<U0&>(u0)));
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    void open_impl(mpl::true_, U0& u0)
+    {
+        this->clear(); 
+        this->member.open(Device(u0));
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0, typename U1>
+    void open_impl(mpl::false_, const U0& u0, const U1& u1)
+    {
+        this->clear(); 
+        this->member.open(u0, u1);
+    }
+    template<typename U0, typename U1>
+    void open_impl(mpl::true_, const U0& u0, const U1& u1)
+    {
+        this->clear(); 
+        this->member.open(Device(const_cast<U0&>(u0), u1));
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0, typename U1>
+    void open_impl(mpl::true_, U0& u0, const U1& u1)
+    {
+        this->clear(); 
+        this->member.open(Device(u0, u1));
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0, typename U1, typename U2>
+    void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2)
+    {
+        this->clear(); 
+        this->member.open(u0, u1, u2);
+    }
+    template<typename U0, typename U1, typename U2>
+    void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2)
+    {
+        this->clear(); 
+        this->member.open(Device(const_cast<U0&>(u0), u1, u2));
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0, typename U1, typename U2>
+    void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2)
+    {
+        this->clear(); 
+        this->member.open(Device(u0, u1, u2));
+    }
+#endif
+};
+
+} } // End namespaces iostreams, boost.
+
+#endif NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp b/include/ndnboost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp
new file mode 100644
index 0000000..149c1cb
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp
@@ -0,0 +1,189 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED
+
+#include <ndnboost/iostreams/detail/broken_overload_resolution/forward.hpp>
+#include <ndnboost/throw_exception.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template< typename T, 
+          typename Tr = 
+              NDNBOOST_IOSTREAMS_CHAR_TRAITS(
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type 
+              ),
+          typename Alloc = 
+              std::allocator<
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type 
+              >,
+          typename Mode = NDNBOOST_DEDUCED_TYPENAME mode_of<T>::type >
+class stream_buffer
+    : public detail::stream_buffer_traits<T, Tr, Alloc, Mode>::type
+{
+private:
+    NDNBOOST_STATIC_ASSERT((
+        is_convertible<
+            NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<T>::type, Mode
+        >::value
+    ));
+    typedef typename 
+            detail::stream_buffer_traits<
+                T, Tr, Alloc, Mode
+            >::type                           base_type;
+public:
+    typedef typename char_type_of<T>::type    char_type;
+    struct category 
+        : Mode,
+          closable_tag,
+          streambuf_tag
+        { };
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+    stream_buffer() { }
+    ~stream_buffer()
+    { 
+        try { 
+            if (this->is_open() && this->auto_close()) 
+                this->close(); 
+        } catch (...) { } 
+    }
+    template<typename U0>
+    stream_buffer(const U0& u0)
+    {
+        open_impl(detail::forward<T, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    stream_buffer(const U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    stream_buffer(const U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1, u2);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    stream_buffer(U0& u0)
+    {
+        open_impl(detail::forward<T, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    stream_buffer(U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    stream_buffer(U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1, u2);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0>
+    void open(const U0& u0)
+    {
+        open_impl(detail::forward<T, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    void open(const U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    void open(const U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1, u2);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    void open(U0& u0)
+    {
+        open_impl(detail::forward<T, U0>(), u0);
+    }
+    template<typename U0, typename U1>
+    void open(U0& u0, const U1& u1)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1);
+    }
+    template<typename U0, typename U1, typename U2>
+    void open(U0& u0, const U1& u1, const U2& u2)
+    {
+        open_impl(detail::forward<T, U0>(), u0, u1, u2);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    T& operator*() { return *this->component(); }
+    T* operator->() { return this->component(); }
+private:
+    template<typename U0>
+    void open_impl(mpl::false_, const U0& u0)
+    {
+        base_type::open(const_cast<U0&>(u0), -1, -1);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    void open_impl(mpl::false_, U0& u0)
+    {
+        base_type::open(detail::wrap(u0), -1, -1);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0>
+    void open_impl(mpl::true_, const U0& u0)
+    {
+        base_type::open(T(const_cast<U0&>(u0)), -1, -1);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0>
+    void open_impl(mpl::true_, U0& u0)
+    {
+        base_type::open(T(u0), -1, -1);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0, typename U1>
+    void open_impl(mpl::false_, const U0& u0, const U1& u1)
+    {
+        base_type::open(u0, u1, -1);
+    }
+    template<typename U0, typename U1>
+    void open_impl(mpl::true_, const U0& u0, const U1& u1)
+    {
+        base_type::open(T(const_cast<U0&>(u0), u1), -1, -1);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0, typename U1>
+    void open_impl(mpl::true_, U0& u0, const U1& u1)
+    {
+        base_type::open(T(u0, u1), -1, -1);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    template<typename U0, typename U1, typename U2>
+    void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2)
+    {
+        base_type::open(u0, u1, u2);
+    }
+    template<typename U0, typename U1, typename U2>
+    void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2)
+    {
+        base_type::open(T(const_cast<U0&>(u0), u1, u2), -1, -1);
+    }
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+    template<typename U0, typename U1, typename U2>
+    void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2)
+    {
+        base_type::open(T(u0, u1, u2), -1, -1);
+    }
+#endif // !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------//
+    void check_open()
+    {
+        if (this->is_open()) 
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("already open"));
+    }
+};
+
+} } // End namespaces iostreams, boost.
+
+#endif // NDNBOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/buffer.hpp b/include/ndnboost/iostreams/detail/buffer.hpp
new file mode 100644
index 0000000..beb5f6c
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/buffer.hpp
@@ -0,0 +1,200 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <algorithm>                           // swap.
+#include <memory>                              // allocator.
+#include <ndnboost/config.hpp>                    // member templates.
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>      // streamsize.
+#include <ndnboost/iostreams/read.hpp>
+#include <ndnboost/iostreams/traits.hpp>          // int_type_of.
+#include <ndnboost/iostreams/checked_operations.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+//----------------Buffers-----------------------------------------------------//
+
+//
+// Template name: buffer
+// Description: Character buffer.
+// Template parameters:
+//     Ch - The character type.
+//     Alloc - The Allocator type.
+//
+template< typename Ch,
+          typename Alloc = std::allocator<Ch> >
+class basic_buffer {
+private:
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+    typedef typename Alloc::template rebind<Ch>::other allocator_type;
+#else
+    typedef std::allocator<Ch> allocator_type;
+#endif
+public:
+    basic_buffer();
+    basic_buffer(int buffer_size);
+    ~basic_buffer();
+    void resize(int buffer_size);
+    Ch* begin() const { return buf_; }
+    Ch* end() const { return buf_ + size_; }
+    Ch* data() const { return buf_; }
+    std::streamsize size() const { return size_; }
+    void swap(basic_buffer& rhs);
+private:
+    // Disallow copying and assignment.
+    basic_buffer(const basic_buffer&);
+    basic_buffer& operator=(const basic_buffer&);
+    Ch*              buf_;
+    std::streamsize  size_;
+};
+
+template<typename Ch, typename Alloc>
+void swap(basic_buffer<Ch, Alloc>& lhs, basic_buffer<Ch, Alloc>& rhs)
+{ lhs.swap(rhs); }
+
+//
+// Template name: buffer
+// Description: Character buffer with two pointers accessible via ptr() and
+//      eptr().
+// Template parameters:
+//     Ch - A character type.
+//
+template< typename Ch,
+          typename Alloc = std::allocator<Ch> >
+class buffer : public basic_buffer<Ch, Alloc> {
+private:
+    typedef basic_buffer<Ch, Alloc> base;
+public:
+    typedef iostreams::char_traits<Ch> traits_type;
+    using base::resize; 
+    using base::data; 
+    using base::size;
+    typedef Ch* const const_pointer;
+    buffer(int buffer_size);
+    Ch* & ptr() { return ptr_; }
+    const_pointer& ptr() const { return ptr_; }
+    Ch* & eptr() { return eptr_; }
+    const_pointer& eptr() const { return eptr_; }
+    void set(std::streamsize ptr, std::streamsize end);
+    void swap(buffer& rhs);
+
+    // Returns an int_type as a status code.
+    template<typename Source>
+    typename int_type_of<Source>::type fill(Source& src) 
+    {
+        using namespace std;
+        std::streamsize keep;
+        if ((keep = static_cast<std::streamsize>(eptr_ - ptr_)) > 0)
+            traits_type::move(this->data(), ptr_, keep);
+        set(0, keep);
+        std::streamsize result = 
+            iostreams::read(src, this->data() + keep, this->size() - keep);
+        if (result != -1)
+            this->set(0, keep + result);
+        return result == -1 ?
+            traits_type::eof() :
+                result == 0 ?
+                    traits_type::would_block() :
+                    traits_type::good();
+
+    }
+
+    // Returns true if one or more characters were written.
+    template<typename Sink>
+    bool flush(Sink& dest) 
+    {
+        using namespace std;
+        std::streamsize amt = static_cast<std::streamsize>(eptr_ - ptr_);
+        std::streamsize result = iostreams::write_if(dest, ptr_, amt);
+        if (result < amt) {
+            traits_type::move( this->data(), 
+                               ptr_ + result, 
+                               amt - result );
+        }
+        this->set(0, amt - result);
+        return result != 0;
+    }
+private:
+    Ch *ptr_, *eptr_;
+};
+
+template<typename Ch, typename Alloc>
+void swap(buffer<Ch, Alloc>& lhs, buffer<Ch, Alloc>& rhs)
+{ lhs.swap(rhs); }
+
+//--------------Implementation of basic_buffer--------------------------------//
+
+template<typename Ch, typename Alloc>
+basic_buffer<Ch, Alloc>::basic_buffer() : buf_(0), size_(0) { }
+
+template<typename Ch, typename Alloc>
+basic_buffer<Ch, Alloc>::basic_buffer(int buffer_size)
+    : buf_(static_cast<Ch*>(allocator_type().allocate(buffer_size, 0))), 
+      size_(buffer_size) // Cast for SunPro 5.3.
+    { }
+
+template<typename Ch, typename Alloc>
+inline basic_buffer<Ch, Alloc>::~basic_buffer()
+{
+    if (buf_) {
+        allocator_type().deallocate(buf_,
+            static_cast<NDNBOOST_DEDUCED_TYPENAME Alloc::size_type>(size_));
+    }
+}
+
+template<typename Ch, typename Alloc>
+inline void basic_buffer<Ch, Alloc>::resize(int buffer_size)
+{
+    if (size_ != buffer_size) {
+        basic_buffer<Ch, Alloc> temp(buffer_size);
+        std::swap(size_, temp.size_);
+        std::swap(buf_, temp.buf_);
+    }
+}
+
+template<typename Ch, typename Alloc>
+void basic_buffer<Ch, Alloc>::swap(basic_buffer& rhs) 
+{ 
+    std::swap(buf_, rhs.buf_); 
+    std::swap(size_, rhs.size_); 
+}
+
+//--------------Implementation of buffer--------------------------------------//
+
+template<typename Ch, typename Alloc>
+buffer<Ch, Alloc>::buffer(int buffer_size)
+    : basic_buffer<Ch, Alloc>(buffer_size) { }
+
+template<typename Ch, typename Alloc>
+inline void buffer<Ch, Alloc>::set(std::streamsize ptr, std::streamsize end)
+{ 
+    ptr_ = data() + ptr; 
+    eptr_ = data() + end; 
+}
+
+template<typename Ch, typename Alloc>
+inline void buffer<Ch, Alloc>::swap(buffer& rhs) 
+{ 
+    base::swap(rhs); 
+    std::swap(ptr_, rhs.ptr_); 
+    std::swap(eptr_, rhs.eptr_); 
+}
+
+//----------------------------------------------------------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/call_traits.hpp b/include/ndnboost/iostreams/detail/call_traits.hpp
new file mode 100644
index 0000000..c917c1a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/call_traits.hpp
@@ -0,0 +1,32 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename T>
+struct param_type {
+    typedef typename mpl::if_<is_std_io<T>, T&, const T&>::type type;
+};
+
+template<typename T>
+struct value_type {
+    typedef typename mpl::if_<is_std_io<T>, T&, T>::type type;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED //-----------//
diff --git a/include/ndnboost/iostreams/detail/char_traits.hpp b/include/ndnboost/iostreams/detail/char_traits.hpp
new file mode 100644
index 0000000..97aaf28
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/char_traits.hpp
@@ -0,0 +1,63 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// Provides std::char_traits for libraries without templated streams. Should not
+// be confused with <ndnboost/iostreams/char_traits.hpp>, which defines the
+// template ndnboost::iostreams::char_traits.
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <iosfwd>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifdef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# include <ndnboost/config.hpp> // Make sure size_t is in std.
+# include <cstddef>
+# include <cstring>
+# include <cstdio>
+#endif
+
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
+# define NDNBOOST_IOSTREAMS_CHAR_TRAITS(ch) std::char_traits< ch >
+#else
+# define NDNBOOST_IOSTREAMS_CHAR_TRAITS(ch) ndnboost::iostreams::detail::char_traits
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+struct char_traits  {
+    typedef char            char_type;
+    typedef int             int_type;
+    typedef std::streampos  pos_type;
+    typedef std::streamoff  off_type;
+
+    // Note: this may not be not conforming, since it treats chars as unsigned,
+    // but is only used to test for equality.
+    static int compare(const char* lhs, const char* rhs, std::size_t n)
+    { return std::strncmp(lhs, rhs, n); }
+    static char* copy(char *dest, const char *src, std::size_t n)
+    { return static_cast<char*>(std::memcpy(dest, src, n)); }
+    static char* move(char *dest, const char *src, std::size_t n)
+    { return static_cast<char*>(std::memmove(dest, src, n)); }
+    static const char* find(const char* s, std::size_t n, const char& c)
+    { return (const char*) (const void*) std::memchr(s, c, n); }
+    static char to_char_type(const int& c) { return c; }
+    static int to_int_type(const char& c) { return c; }
+    static bool eq_int_type(const int& lhs, const int& rhs)
+    { return lhs == rhs; }
+    static int eof() { return EOF; }
+    static int not_eof(const int& c) { return c != EOF ? c : '\n'; }
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifdef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/codecvt_helper.hpp b/include/ndnboost/iostreams/detail/codecvt_helper.hpp
new file mode 100644
index 0000000..4b1a1c4
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/codecvt_helper.hpp
@@ -0,0 +1,237 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the definition of the template codecvt_helper, useful for
+// defining specializations of std::codecvt where state_type != mbstate_t.
+// Compensates for the fact that some standard library implementations 
+// do not derive the primiary codecvt template from locale::facet or 
+// provide the correct member types and functions.
+
+// Usage: 
+//
+// // In global namespace:
+// NDNBOOST_IOSTREAMS_CODECVT_SPEC(mystate)
+//
+// // In user namespace:
+// template<typename Intern, typename Extern>
+// struct mycodecvt : codecvt_helper<Intern, Extern, State> { ... };
+//
+// // Or:
+// struct mycodecvt : codecvt_helper<wchar_t, char, State> { ... };
+// 
+// Etc.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // Put size_t in std, NDNBOOST_MSVC, Dinkum.
+#include <ndnboost/detail/workaround.hpp>
+#include <algorithm>         // min.
+#include <cstddef>           // size_t.
+#include <locale>            // locale, codecvt_base, codecvt.
+#include <ndnboost/iostreams/detail/config/codecvt.hpp>
+
+//------------------Definition of traits--------------------------------------//
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) //-----------------------//
+
+template<typename T>
+struct codecvt_intern { typedef typename T::intern_type type; };
+
+template<typename T>
+struct codecvt_extern { typedef typename T::extern_type type; };
+
+#else // #if !NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) //--------------//
+
+template<typename T>
+struct codecvt_intern { typedef typename T::from_type type; };
+
+template<typename T>
+struct codecvt_extern { typedef typename T::to_type type; };
+
+#endif // #if !NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) //-------------//
+
+template<typename T>
+struct codecvt_state { typedef typename T::state_type type; };
+
+} } } // End namespaces detail, iostreams, boost.
+
+//------------------Definition of codecvt_impl--------------------------------//
+
+#if defined(NDNBOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
+    defined(NDNBOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \
+    defined(NDNBOOST_IOSTREAMS_NO_LOCALE) \
+    /**/
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Intern, typename Extern, typename State>
+struct codecvt_impl : std::locale::facet, std::codecvt_base {
+public:
+    typedef Intern  intern_type;
+    typedef Extern  extern_type;
+    typedef State   state_type;
+
+    codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { } 
+
+    std::codecvt_base::result
+    in( State& state, const Extern* first1, const Extern* last1,
+        const Extern*& next1, Intern* first2, Intern* last2,
+        Intern*& next2 ) const
+    {
+        return do_in(state, first1, last1, next1, first2, last2, next2);
+    }
+
+    std::codecvt_base::result
+    out( State& state, const Intern* first1, const Intern* last1,
+         const Intern*& next1, Extern* first2, Extern* last2,
+         Extern*& next2 ) const
+    {
+        return do_out(state, first1, last1, next1, first2, last2, next2);
+    }
+
+    std::codecvt_base::result
+    unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const
+    {
+        return do_unshift(state, first2, last2, next2);
+    }
+
+    bool always_noconv() const throw() { return do_always_noconv(); }
+
+    int max_length() const throw() { return do_max_length(); }
+
+    int encoding() const throw() { return do_encoding(); }
+
+    int length( NDNBOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state, 
+                const Extern* first1, const Extern* last1,
+                std::size_t len2 ) const throw()
+    {
+        return do_length(state, first1, last1, len2);
+    }
+protected:
+    std::codecvt_base::result
+    virtual do_in( State&, const Extern*, const Extern*, const Extern*&, 
+                   Intern*, Intern*, Intern*& ) const
+    {
+        return std::codecvt_base::noconv;
+    }
+
+    std::codecvt_base::result
+    virtual do_out( State&, const Intern*, const Intern*, const Intern*&, 
+                    Extern*, Extern*, Extern*& ) const
+    {
+        return std::codecvt_base::noconv;
+    }
+
+    std::codecvt_base::result
+    virtual do_unshift(State&, Extern*, Extern*, Extern*&) const
+    {
+        return std::codecvt_base::ok;
+    }
+
+    virtual bool do_always_noconv() const throw() { return true; }
+
+    virtual int do_max_length() const throw() { return 1; }
+
+    virtual int do_encoding() const throw() { return 1; }
+
+    virtual int do_length( NDNBOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State&, 
+                           const Extern* first1, const Extern* last1,
+                           std::size_t len2 ) const throw()
+    {
+        return (std::min)(static_cast<std::size_t>(last1 - first1), len2);
+    }
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // no primary codecvt definition, empty definition.
+
+//------------------Definition of NDNBOOST_IOSTREAMS_CODECVT_SPEC----------------//
+
+#if defined(NDNBOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
+    defined(NDNBOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \
+    /**/
+# ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#  define NDNBOOST_IOSTREAMS_CODECVT_SPEC(state) \
+    namespace std { \
+        template<typename Intern, typename Extern> \
+        class codecvt<Intern, Extern, state> \
+            : public ::ndnboost::iostreams::detail::codecvt_impl< \
+                         Intern, Extern, state \
+                     > \
+        { \
+        public: \
+            codecvt(std::size_t refs = 0) \
+                : ::ndnboost::iostreams::detail::codecvt_impl< \
+                      Intern, Extern, state \
+                  >(refs) \
+                { } \
+            static std::locale::id id; \
+        }; \
+        template<typename Intern, typename Extern> \
+        std::locale::id codecvt<Intern, Extern, state>::id; \
+    } \
+    /**/
+# else
+#  define NDNBOOST_IOSTREAMS_CODECVT_SPEC(state) \
+    namespace std { \
+        template<> \
+        class codecvt<wchar_t, char, state> \
+            : public ::ndnboost::iostreams::detail::codecvt_impl< \
+                         wchar_t, char, state \
+                     > \
+        { \
+        public: \
+            codecvt(std::size_t refs = 0) \
+                : ::ndnboost::iostreams::detail::codecvt_impl< \
+                      wchar_t, char, state \
+                  >(refs) \
+                { } \
+            static std::locale::id id; \
+        }; \
+        template<> \
+        std::locale::id codecvt<wchar_t, char, state>::id; \
+    } \
+    /**/
+# endif
+#else
+# define NDNBOOST_IOSTREAMS_CODECVT_SPEC(state)
+#endif // no primary codecvt definition, or empty definition.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+                    
+//------------------Definition of codecvt_helper------------------------------//
+
+template<typename Intern, typename Extern, typename State>
+struct codecvt_helper : std::codecvt<Intern, Extern, State> { 
+    typedef Intern  intern_type;
+    typedef Extern  extern_type;
+    typedef State   state_type;
+    codecvt_helper(std::size_t refs = 0) 
+    #if !defined(NDNBOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T)
+        : std::codecvt<Intern, Extern, State>(refs)
+    #else
+        : std::codecvt<Intern, Extern, State>()
+    #endif
+        { }
+#ifdef NDNBOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH
+    int max_length() const throw() { return do_max_length(); }
+protected:
+    virtual int do_max_length() const throw() { return 1; }
+#endif
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/codecvt_holder.hpp b/include/ndnboost/iostreams/detail/codecvt_holder.hpp
new file mode 100644
index 0000000..7b5e929
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/codecvt_holder.hpp
@@ -0,0 +1,63 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains machinery for performing code conversion.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <cwchar>            // mbstate_t.
+#include <locale>            // codecvt, locale.
+#include <ndnboost/config.hpp>  // HAS_MACRO_USE_FACET.
+#include <ndnboost/iostreams/detail/config/codecvt.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+struct default_codecvt { 
+    typedef wchar_t         intern_type, from_type;
+    typedef char            extern_type, to_type;
+    typedef std::mbstate_t  state_type;
+};
+
+template<typename Codecvt>
+struct codecvt_holder {
+    typedef Codecvt codecvt_type;
+    const codecvt_type& get() const { return codecvt_; }
+    void imbue(const std::locale&) { }
+    Codecvt codecvt_;
+};
+
+template<>
+struct codecvt_holder<default_codecvt> {
+    typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
+    codecvt_holder() { reset_codecvt(); }
+    const codecvt_type& get() const { return *codecvt_; }
+    void imbue(const std::locale& loc) 
+    { 
+        loc_ = loc;
+        reset_codecvt();
+    }
+    void reset_codecvt()
+    {
+        using namespace std;
+        #ifndef NDNBOOST_HAS_MACRO_USE_FACET
+            codecvt_ = & use_facet< codecvt_type >(loc_);
+        #else
+            codecvt_ = & _USE(loc_, codecvt_type);
+        #endif
+    }
+    std::locale loc_; // Prevent codecvt_ from being freed.
+    const codecvt_type* codecvt_;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/auto_link.hpp b/include/ndnboost/iostreams/detail/config/auto_link.hpp
new file mode 100644
index 0000000..da9f805
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/auto_link.hpp
@@ -0,0 +1,49 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from <ndnboost/config/auto_link.hpp> and from
+// http://www.boost.org/more/separate_compilation.html, by John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#if defined(NDNBOOST_EXTERNAL_LIB_NAME)
+# if defined(NDNBOOST_MSVC) \
+     || defined(__BORLANDC__) \
+     || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \
+     || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \
+     /**/
+#  pragma comment(lib, NDNBOOST_EXTERNAL_LIB_NAME)
+# endif
+# undef NDNBOOST_EXTERNAL_LIB_NAME
+#endif
+
+//------------------Enable automatic library variant selection----------------// 
+
+#if !defined(NDNBOOST_IOSTREAMS_SOURCE) && \
+    !defined(NDNBOOST_ALL_NO_LIB) && \
+    !defined(NDNBOOST_IOSTREAMS_NO_LIB) \
+    /**/
+
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it.
+# define NDNBOOST_LIB_NAME ndnboost_iostreams
+
+// If we're importing code from a dll, then tell auto_link.hpp about it.
+# if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_IOSTREAMS_DYN_LINK)
+#  define NDNBOOST_DYN_LINK
+# endif
+
+// And include the header that does the work.
+# include <ndnboost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/bzip2.hpp b/include/ndnboost/iostreams/detail/config/bzip2.hpp
new file mode 100644
index 0000000..c62ca61
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/bzip2.hpp
@@ -0,0 +1,48 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from <ndnboost/config/auto_link.hpp> and from
+// http://www.boost.org/more/separate_compilation.html, by John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#if defined(NDNBOOST_BZIP2_BINARY)
+# if defined(NDNBOOST_MSVC) || \
+     defined(__BORLANDC__) || \
+     (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) || \
+     (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \
+     /**/
+
+// Specify the name of the .lib file.
+#  pragma comment(lib, NDNBOOST_STRINGIZE(NDNBOOST_BZIP2_BINARY))
+# endif
+#else 
+# if !defined(NDNBOOST_IOSTREAMS_SOURCE) && \
+     !defined(NDNBOOST_ALL_NO_LIB) && \
+     !defined(NDNBOOST_IOSTREAMS_NO_LIB) \
+     /**/
+
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it.
+#  define NDNBOOST_LIB_NAME ndnboost_bzip2
+
+// If we're importing code from a dll, then tell auto_link.hpp about it.
+#  if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_IOSTREAMS_DYN_LINK)
+#   define NDNBOOST_DYN_LINK
+#  endif
+
+// And include the header that does the work.
+#  include <ndnboost/config/auto_link.hpp>
+# endif
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/codecvt.hpp b/include/ndnboost/iostreams/detail/config/codecvt.hpp
new file mode 100644
index 0000000..afa45b2
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/codecvt.hpp
@@ -0,0 +1,80 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <cstddef>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif       
+
+//------------------Support for codecvt with user-defined state types---------//
+
+#if defined(__MSL_CPP__) || defined(__LIBCOMO__) || \
+    NDNBOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \
+    /**/
+# define NDNBOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION
+#endif
+
+#if defined(__GLIBCPP__) || defined(__GLIBCXX__) || \
+    NDNBOOST_WORKAROUND(_STLPORT_VERSION, > 0x450) \
+    /**/
+# define NDNBOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION
+#endif
+
+//------------------Check for codecvt ctor taking a reference count-----------//
+
+#if NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3205)) || \
+    NDNBOOST_WORKAROUND(_STLPORT_VERSION, < 0x461) \
+    /**/
+# define NDNBOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T
+#endif
+
+//------------------Normalize codecvt::length---------------------------------//
+
+#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__) && \
+    (!defined(NDNBOOST_RWSTD_VER) || NDNBOOST_RWSTD_VER < 0x04010300) && \
+    (!defined(__MACH__) || !defined(__INTEL_COMPILER))
+    /**/
+# define NDNBOOST_IOSTREAMS_CODECVT_CV_QUALIFIER const
+#else
+# define NDNBOOST_IOSTREAMS_CODECVT_CV_QUALIFIER
+#endif
+
+//------------------Check for codecvt::max_length-----------------------------//
+
+#if NDNBOOST_WORKAROUND(_STLPORT_VERSION, < 0x461)
+# define NDNBOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH
+#endif
+                    
+//------------------Put mbstate_t and codecvt in std--------------------------//
+
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+# include <locale>
+#endif
+
+// From Robert Ramey's version of utf8_codecvt_facet.
+namespace std { 
+
+#if defined(__LIBCOMO__)
+    using ::mbstate_t;
+#elif defined(NDNBOOST_DINKUMWARE_STDLIB) && !defined(__BORLANDC__)
+    using ::mbstate_t;
+#elif defined(__SGI_STL_PORT)
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+    using ::codecvt;
+    using ::mbstate_t;
+#endif
+
+} // End namespace std.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/disable_warnings.hpp b/include/ndnboost/iostreams/detail/config/disable_warnings.hpp
new file mode 100644
index 0000000..0f65f00
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/disable_warnings.hpp
@@ -0,0 +1,30 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#include <ndnboost/config.hpp>             // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>  // NDNBOOST_WORKAROUND.
+
+#if defined(NDNBOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4127)    // Conditional expression is constant.
+# pragma warning(disable:4130)    // Logical operation on address of string constant.
+# pragma warning(disable:4224)    // Parameter previously defined as type.
+# pragma warning(disable:4244)    // Conversion: possible loss of data.
+# pragma warning(disable:4512)    // Assignment operator could not be generated.
+# pragma warning(disable:4706)    // Assignment within conditional expression.
+# if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, >= 1400)
+#  pragma warning(disable:6334)   // sizeof applied to an expression with an operator.
+# endif
+#else
+# if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600)
+#  pragma warn -8008     // Condition always true/false.
+#  pragma warn -8066     // Unreachable code.
+#  pragma warn -8071     // Conversion may lose significant digits.
+#  pragma warn -8072     // Suspicious pointer arithmetic.
+#  pragma warn -8080     // identifier declared but never used.
+# endif
+#endif
diff --git a/include/ndnboost/iostreams/detail/config/dyn_link.hpp b/include/ndnboost/iostreams/detail/config/dyn_link.hpp
new file mode 100644
index 0000000..e8d922f
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/dyn_link.hpp
@@ -0,0 +1,37 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from http://www.boost.org/more/separate_compilation.html, by
+// John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+//------------------Enable dynamic linking on windows-------------------------// 
+
+#ifdef NDNBOOST_HAS_DECLSPEC 
+# if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_IOSTREAMS_DYN_LINK)
+#  ifdef NDNBOOST_IOSTREAMS_SOURCE
+#   define NDNBOOST_IOSTREAMS_DECL __declspec(dllexport)
+#  else
+#   define NDNBOOST_IOSTREAMS_DECL __declspec(dllimport)
+#  endif  
+# endif  
+#endif 
+
+#ifndef NDNBOOST_IOSTREAMS_DECL
+# define NDNBOOST_IOSTREAMS_DECL
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/enable_warnings.hpp b/include/ndnboost/iostreams/detail/config/enable_warnings.hpp
new file mode 100644
index 0000000..3043c5e
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/enable_warnings.hpp
@@ -0,0 +1,18 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#if defined(NDNBOOST_MSVC)
+# pragma warning(pop)
+#else
+# if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600)
+#  pragma warn .8008     // Condition always true/false.
+#  pragma warn .8066     // Unreachable code.
+#  pragma warn .8071     // Conversion may lose significant digits.
+#  pragma warn .8072     // Suspicious pointer arithmetic.
+#  pragma warn .8080     // identifier declared but never used.
+# endif
+#endif
diff --git a/include/ndnboost/iostreams/detail/config/fpos.hpp b/include/ndnboost/iostreams/detail/config/fpos.hpp
new file mode 100644
index 0000000..ffb9656
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/fpos.hpp
@@ -0,0 +1,31 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/detail/execute.hpp
+ * Date:        Thu Dec 06 13:21:54 MST 2007
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the preprocessor symbol NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS for
+ * platforms that use the implementation of std::fpos from the Dinkumware 
+ * Standard Library.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+# if (defined(_YVALS) || defined(_CPPLIB_VER)) && !defined(__SGI_STL_PORT) && \
+     !defined(_STLPORT_VERSION) && !defined(__QNX__)
+     /**/
+#  define NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+# endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/gcc.hpp b/include/ndnboost/iostreams/detail/config/gcc.hpp
new file mode 100644
index 0000000..2685346
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/gcc.hpp
@@ -0,0 +1,27 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from <ndnboost/config/auto_link.hpp> and from
+// http://www.boost.org/more/separate_compilation.html, by John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp> // NDNBOOST_INTEL.
+
+#if defined(__GNUC__) && !defined(NDNBOOST_INTEL)
+# define NDNBOOST_IOSTREAMS_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
+# define NDNBOOST_IOSTREAMS_GCC_WORKAROUND_GUARD 1
+#else
+# define NDNBOOST_IOSTREAMS_GCC_WORKAROUND_GUARD 0
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/limits.hpp b/include/ndnboost/iostreams/detail/config/limits.hpp
new file mode 100644
index 0000000..cc83aec
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/limits.hpp
@@ -0,0 +1,19 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED
+
+#ifndef NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY
+# define NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY 3
+#endif
+
+#ifndef NDNBOOST_IOSTREAMS_MAX_EXECUTE_ARITY
+# define NDNBOOST_IOSTREAMS_MAX_EXECUTE_ARITY 5
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/overload_resolution.hpp b/include/ndnboost/iostreams/detail/config/overload_resolution.hpp
new file mode 100644
index 0000000..2f35c41
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/overload_resolution.hpp
@@ -0,0 +1,32 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from <ndnboost/config/auto_link.hpp> and from
+// http://www.boost.org/more/separate_compilation.html, by John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif             
+
+#include <ndnboost/config.hpp> // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/config/gcc.hpp>
+
+#if !defined(NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION)
+# if NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003) || \
+     NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600) || \
+     NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) || \
+     NDNBOOST_WORKAROUND(NDNBOOST_IOSTREAMS_GCC, <= 295) \
+     /**/
+#  define NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION
+# endif
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/rtl.hpp b/include/ndnboost/iostreams/detail/config/rtl.hpp
new file mode 100644
index 0000000..c39b814
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/rtl.hpp
@@ -0,0 +1,72 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * Defines preprocessor symbols expanding to the names of functions in the 
+ * C runtime library used to access file descriptors and to the type used
+ * to store file offsets for seeking.
+ * 
+ * File:        ndnboost/iostreams/detail/config/rtl.hpp
+ * Date:        Wed Dec 26 11:58:11 MST 2007
+ * 
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/iostreams/detail/config/windows_posix.hpp>
+
+// Handle open, close, read, and write
+#ifdef __BORLANDC__
+# define NDNBOOST_IOSTREAMS_RTL(x) NDNBOOST_JOIN(_rtl_, x)
+#elif defined NDNBOOST_IOSTREAMS_WINDOWS
+# define NDNBOOST_IOSTREAMS_RTL(x) NDNBOOST_JOIN(_, x)
+#else
+# define NDNBOOST_IOSTREAMS_RTL(x) ::x  // Distinguish from member function named x
+#endif
+#define NDNBOOST_IOSTREAMS_FD_OPEN   NDNBOOST_IOSTREAMS_RTL(open)
+#define NDNBOOST_IOSTREAMS_FD_CLOSE  NDNBOOST_IOSTREAMS_RTL(close)
+#define NDNBOOST_IOSTREAMS_FD_READ   NDNBOOST_IOSTREAMS_RTL(read)
+#define NDNBOOST_IOSTREAMS_FD_WRITE  NDNBOOST_IOSTREAMS_RTL(write)
+
+// Handle lseek, off_t, ftruncate, and stat
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+# if defined(NDNBOOST_MSVC) || defined(__MSVCRT__) // MSVC, MinGW
+#  define NDNBOOST_IOSTREAMS_FD_SEEK    _lseeki64
+#  define NDNBOOST_IOSTREAMS_FD_OFFSET  __int64
+# else                                          // Borland, Metrowerks, ...
+#  define NDNBOOST_IOSTREAMS_FD_SEEK    lseek  
+#  define NDNBOOST_IOSTREAMS_FD_OFFSET  long
+# endif
+#else // Non-windows
+# if defined(_LARGEFILE64_SOURCE) && !defined(__APPLE__) && \
+         (!defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64) || \
+     defined(_AIX) && !defined(_LARGE_FILES) || \
+     defined(NDNBOOST_IOSTREAMS_HAS_LARGE_FILE_EXTENSIONS)
+     /**/
+
+    /* Systems with transitional extensions for large file support */
+
+#  define NDNBOOST_IOSTREAMS_FD_SEEK      lseek64
+#  define NDNBOOST_IOSTREAMS_FD_TRUNCATE  ftruncate64
+#  define NDNBOOST_IOSTREAMS_FD_MMAP      mmap64
+#  define NDNBOOST_IOSTREAMS_FD_STAT      stat64
+#  define NDNBOOST_IOSTREAMS_FD_FSTAT     fstat64
+#  define NDNBOOST_IOSTREAMS_FD_OFFSET    off64_t
+# else
+#  define NDNBOOST_IOSTREAMS_FD_SEEK      lseek
+#  define NDNBOOST_IOSTREAMS_FD_TRUNCATE  ftruncate
+#  define NDNBOOST_IOSTREAMS_FD_MMAP      mmap
+#  define NDNBOOST_IOSTREAMS_FD_STAT      stat
+#  define NDNBOOST_IOSTREAMS_FD_FSTAT     fstat
+#  define NDNBOOST_IOSTREAMS_FD_OFFSET    off_t
+# endif
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/unreachable_return.hpp b/include/ndnboost/iostreams/detail/config/unreachable_return.hpp
new file mode 100644
index 0000000..1de856a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/unreachable_return.hpp
@@ -0,0 +1,25 @@
+// (C) Copyright 2010 Daniel James
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_UNREACHABLE_RETURN_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_UNREACHABLE_RETURN_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>
+
+// If Boost.Exception has NDNBOOST_ATTRIBUTE_NORETURN
+#if defined(_MSC_VER) || defined(__GNUC__)
+#define NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(x) \
+    NDNBOOST_UNREACHABLE_RETURN(x)
+#else
+#define NDNBOOST_IOSTREAMS_UNREACHABLE_RETURN(x) \
+    return x;
+#endif
+
+#endif
diff --git a/include/ndnboost/iostreams/detail/config/wide_streams.hpp b/include/ndnboost/iostreams/detail/config/wide_streams.hpp
new file mode 100644
index 0000000..92ead3b
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/wide_streams.hpp
@@ -0,0 +1,55 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from http://www.boost.org/more/separate_compilation.html, by
+// John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <cstddef>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif       
+
+//------------------Templated stream support----------------------------------//
+
+// From ndnboost/dynamic_bitset.hpp; thanks to Matthias Troyer for cray patch.
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# if defined(__STL_CONFIG_H) && \
+    !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \
+    /**/
+#  define NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# endif
+#endif // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+
+//------------------Wide stream support---------------------------------------//
+
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+# if defined(NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES) || \
+     defined (NDNBOOST_NO_STD_WSTREAMBUF) && \
+     ( !defined(__MSL_CPP__) || defined(_MSL_NO_WCHART_CPP_SUPPORT) ) \
+     /**/
+#  define NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+# endif
+#endif // #ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS   
+
+//------------------Locale support--------------------------------------------//
+
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+# if defined(NDNBOOST_NO_STD_LOCALE) || \
+     defined(__CYGWIN__) && \
+     ( !defined(__MSL_CPP__) || defined(_MSL_NO_WCHART_CPP_SUPPORT) ) \
+     /**/
+#  define NDNBOOST_IOSTREAMS_NO_LOCALE
+# endif
+#endif // #ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/windows_posix.hpp b/include/ndnboost/iostreams/detail/config/windows_posix.hpp
new file mode 100644
index 0000000..9fd9c45
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/windows_posix.hpp
@@ -0,0 +1,25 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2004-2007 Jonathan Turkanis
+// (C) Copyright 2002, 2003 Beman Dawes   Boost.Filesystem
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED
+
+//------------------From ndnboost/libs/filesystem/src/path_posix_windows.cpp-----//
+
+// NDNBOOST_IOSTREAMS_POSIX or NDNBOOST_IOSTREAMS_WINDOWS specify which API to use.
+#if !defined( NDNBOOST_IOSTREAMS_WINDOWS ) && !defined( NDNBOOST_IOSTREAMS_POSIX )
+# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \
+     !defined(__CYGWIN__) \
+     /**/
+#  define NDNBOOST_IOSTREAMS_WINDOWS
+# else
+#  define NDNBOOST_IOSTREAMS_POSIX
+# endif
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/config/zlib.hpp b/include/ndnboost/iostreams/detail/config/zlib.hpp
new file mode 100644
index 0000000..e3df50a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/config/zlib.hpp
@@ -0,0 +1,50 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Adapted from <ndnboost/config/auto_link.hpp> and from
+// http://www.boost.org/more/separate_compilation.html, by John Maddock.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp> // NDNBOOST_STRINGIZE.
+
+#if defined(NDNBOOST_ZLIB_BINARY)
+# if defined(NDNBOOST_MSVC) || \
+     defined(__BORLANDC__) || \
+     (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) || \
+     (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \
+     /**/
+
+// Specify the name of the .lib file.
+#  pragma comment(lib, NDNBOOST_STRINGIZE(NDNBOOST_ZLIB_BINARY))
+# endif
+#else 
+# if !defined(NDNBOOST_IOSTREAMS_SOURCE) && \
+     !defined(NDNBOOST_ALL_NO_LIB) && \
+     !defined(NDNBOOST_IOSTREAMS_NO_LIB) \
+     /**/
+
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it.
+#  define NDNBOOST_LIB_NAME ndnboost_zlib
+
+// If we're importing code from a dll, then tell auto_link.hpp about it.
+#  if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_IOSTREAMS_DYN_LINK)
+#   define NDNBOOST_DYN_LINK
+#  endif
+
+// And include the header that does the work.
+#  include <ndnboost/config/auto_link.hpp>
+# endif
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/counted_array.hpp b/include/ndnboost/iostreams/detail/counted_array.hpp
new file mode 100644
index 0000000..5305898
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/counted_array.hpp
@@ -0,0 +1,64 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED
+
+#include <algorithm>                               // min.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>          // streamsize.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Ch>
+class counted_array_source {
+public:
+    typedef Ch          char_type;
+    typedef source_tag  category;
+    counted_array_source(const Ch* buf, std::streamsize size) 
+        : buf_(buf), ptr_(0), end_(size)
+        { }
+    std::streamsize read(Ch* s, std::streamsize n)
+    {
+        std::streamsize result = (std::min)(n, end_ - ptr_);
+        NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy
+            (s, buf_ + ptr_, result);
+        ptr_ += result;
+        return result;
+    }
+    std::streamsize count() const { return ptr_; }
+private:
+    const Ch*        buf_;
+    std::streamsize  ptr_, end_;
+};
+
+template<typename Ch>
+struct counted_array_sink {
+public:
+    typedef Ch        char_type;
+    typedef sink_tag  category;
+    counted_array_sink(Ch* buf, std::streamsize size) 
+        : buf_(buf), ptr_(0), end_(size)
+        { }
+        std::streamsize write(const Ch* s, std::streamsize n)
+    {
+        std::streamsize result = (std::min)(n, end_ - ptr_);
+        NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy
+            (buf_ + ptr_, s, result);
+        ptr_ += result;
+        return result;
+    }
+    std::streamsize count() const { return ptr_; }
+private:
+    Ch*              buf_;
+    std::streamsize  ptr_, end_;
+};
+
+} } } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/current_directory.hpp b/include/ndnboost/iostreams/detail/current_directory.hpp
new file mode 100644
index 0000000..fda6950
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/current_directory.hpp
@@ -0,0 +1,65 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/detail/execute.hpp
+ * Date:        Thu Dec 06 13:21:54 MST 2007
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the function ndnboost::iostreams::detail::current_directory, used by 
+ * ndnboost::iostreams::detail::absolute_path.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED
+
+#include <ndnboost/config.hpp>  // make sure size_t is in std.
+#include <cstddef>           // size_t
+#include <string>
+#include <ndnboost/iostreams/detail/buffer.hpp>
+#include <ndnboost/iostreams/detail/config/windows_posix.hpp>
+#include <ndnboost/iostreams/detail/system_failure.hpp>
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+# define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers
+# include <windows.h>
+#else
+# include <unistd.h>        // sysconf.
+#endif
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+// Returns the current working directory
+inline std::string current_directory()
+{
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    DWORD               length;
+    basic_buffer<char>  buf(MAX_PATH);
+    while (true) {
+        length = ::GetCurrentDirectoryA(buf.size(), buf.data());
+        if (!length)
+            throw_system_failure("failed determining current directory");
+        if (length < static_cast<DWORD>(buf.size()))
+            break;
+        buf.resize(buf.size() * 2);
+    }
+    return std::string(buf.data(), length);
+#else // #ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    basic_buffer<char> buf(pathconf(".", _PC_PATH_MAX));
+    if (!getcwd(buf.data(), static_cast<size_t>(buf.size())))
+        throw_system_failure("failed determining current directory");
+    return std::string(buf.data());
+#endif // #ifdef NDNBOOST_IOSTREAMS_WINDOWS
+}
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/default_arg.hpp b/include/ndnboost/iostreams/detail/default_arg.hpp
new file mode 100644
index 0000000..c85aae6
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/default_arg.hpp
@@ -0,0 +1,25 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif            
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+# include <ndnboost/mpl/identity.hpp>
+# define NDNBOOST_IOSTREAMS_DEFAULT_ARG(arg) mpl::identity< arg >::type
+#else
+# define NDNBOOST_IOSTREAMS_DEFAULT_ARG(arg) arg
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/dispatch.hpp b/include/ndnboost/iostreams/detail/dispatch.hpp
new file mode 100644
index 0000000..fa7e926
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/dispatch.hpp
@@ -0,0 +1,41 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>                   // NDNBOOST_DEDUCED_TYPENAME. 
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/iostreams/traits.hpp>         // category_of. 
+#include <ndnboost/mpl/void.hpp>          
+#include <ndnboost/type_traits/is_convertible.hpp>         
+
+namespace ndnboost { namespace iostreams {namespace detail {
+    
+template< typename T, typename Tag1, typename Tag2,
+          typename Tag3 = mpl::void_, typename Tag4 = mpl::void_,
+          typename Tag5 = mpl::void_, typename Tag6 = mpl::void_,
+          typename Category = 
+              NDNBOOST_DEDUCED_TYPENAME category_of<T>::type >
+struct dispatch 
+    : iostreams::select<  // Disambiguation for Tru64.
+          is_convertible<Category, Tag1>, Tag1,
+          is_convertible<Category, Tag2>, Tag2,
+          is_convertible<Category, Tag3>, Tag3,
+          is_convertible<Category, Tag4>, Tag4,
+          is_convertible<Category, Tag5>, Tag5,
+          is_convertible<Category, Tag6>, Tag6
+      >
+    { };
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/double_object.hpp b/include/ndnboost/iostreams/detail/double_object.hpp
new file mode 100644
index 0000000..dd23f7a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/double_object.hpp
@@ -0,0 +1,114 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2004-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the definition of the class template 
+// ndnboost::iostreams::detail::double_object, which is similar to compressed pair
+// except that both members of the pair have the same type, and 
+// compression occurs only if requested using a boolean template
+// parameter.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <algorithm>              // swap.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/mpl/if.hpp>
+#if NDNBOOST_WORKAROUND(__MWERKS__, > 0x3003)
+# include <msl_utility>
+#else
+# include <ndnboost/call_traits.hpp>
+#endif
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename T>
+class single_object_holder {
+public:
+#if NDNBOOST_WORKAROUND(__MWERKS__, > 0x3003)
+    typedef Metrowerks::call_traits<T>             traits_type;
+#else
+    typedef ndnboost::call_traits<T>                  traits_type;
+#endif
+    typedef typename traits_type::param_type       param_type;
+    typedef typename traits_type::reference        reference;
+    typedef typename traits_type::const_reference  const_reference;
+    single_object_holder() { }
+    single_object_holder(param_type t) : first_(t) { }
+    reference first() { return first_; }
+    const_reference first() const { return first_; }
+    reference second() { return first_; }
+    const_reference second() const { return first_; }
+    void swap(single_object_holder& o)
+    { std::swap(first_, o.first_); }
+private:
+    T first_;
+};
+
+template<typename T>
+struct double_object_holder {
+public:
+#if NDNBOOST_WORKAROUND(__MWERKS__, > 0x3003)
+    typedef Metrowerks::call_traits<T>             traits_type;
+#else
+    typedef ndnboost::call_traits<T>                  traits_type;
+#endif
+    typedef typename traits_type::param_type       param_type;
+    typedef typename traits_type::reference        reference;
+    typedef typename traits_type::const_reference  const_reference;
+    double_object_holder() { }
+    double_object_holder(param_type t1, param_type t2)
+        : first_(t1), second_(t2) { }
+    reference first() { return first_; }
+    const_reference first() const { return first_; }
+    reference second() { return second_; }
+    const_reference second() const { return second_; }
+    void swap(double_object_holder& d)
+    { 
+        std::swap(first_, d.first_); 
+        std::swap(second_, d.second_); 
+    }
+private:
+    T first_, second_;
+};
+
+template<typename T, typename IsDouble>
+class double_object 
+    : public mpl::if_<
+                 IsDouble, 
+                 double_object_holder<T>, 
+                 single_object_holder<T>
+             >::type
+{
+private:
+    typedef typename 
+            mpl::if_<
+                IsDouble, 
+                double_object_holder<T>, 
+                single_object_holder<T>
+            >::type                                base_type;
+public:
+#if NDNBOOST_WORKAROUND(__MWERKS__, > 0x3003)
+    typedef Metrowerks::call_traits<T>             traits_type;
+#else
+    typedef ndnboost::call_traits<T>                  traits_type;
+#endif
+    typedef typename traits_type::param_type       param_type;
+    typedef typename traits_type::reference        reference;
+    typedef typename traits_type::const_reference  const_reference;
+    double_object() : base_type() {}
+    double_object(param_type t1, param_type t2)
+        : base_type(t1, t2) { }
+    bool is_double() const { return IsDouble::value; }
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/enable_if_stream.hpp b/include/ndnboost/iostreams/detail/enable_if_stream.hpp
new file mode 100644
index 0000000..a96dfe0
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/enable_if_stream.hpp
@@ -0,0 +1,32 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>                // NDNBOOST_NO_SFINAE.
+#include <ndnboost/utility/enable_if.hpp>                  
+#include <ndnboost/iostreams/traits_fwd.hpp>  // is_std_io.
+
+#if !defined(NDNBOOST_NO_SFINAE) && \
+    !NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x592))
+# define NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(T) \
+    , typename ndnboost::enable_if< ndnboost::iostreams::is_std_io<T> >::type* = 0 \
+    /**/
+# define NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T) \
+    , typename ndnboost::disable_if< ndnboost::iostreams::is_std_io<T> >::type* = 0 \
+    /**/
+#else 
+# define NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(T)
+# define NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T)
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/error.hpp b/include/ndnboost/iostreams/detail/error.hpp
new file mode 100644
index 0000000..0489190
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/error.hpp
@@ -0,0 +1,45 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+                 
+#include <ndnboost/iostreams/detail/ios.hpp>  // failure.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+inline NDNBOOST_IOSTREAMS_FAILURE cant_read() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("no read access"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE cant_write() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("no write access"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE cant_seek() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("no random access"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE bad_read() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("bad read"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE bad_putback() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("putback buffer full"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE bad_write() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("bad write"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE write_area_exhausted() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("write area exhausted"); }
+
+inline NDNBOOST_IOSTREAMS_FAILURE bad_seek() 
+{ return NDNBOOST_IOSTREAMS_FAILURE("bad seek"); }
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/execute.hpp b/include/ndnboost/iostreams/detail/execute.hpp
new file mode 100644
index 0000000..73240c8
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/execute.hpp
@@ -0,0 +1,135 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/detail/execute.hpp
+ * Date:        Thu Dec 06 13:21:54 MST 2007
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+
+ * Defines the overloaded function template 
+ * ndnboost::iostreams::detail::execute_all() and the function template 
+ * ndnboost::iostreams::detail::execute_foreach().
+ *
+ * execute_all() invokes a primary operation and performs a sequence of cleanup 
+ * operations, returning the result of the primary operation if no exceptions
+ * are thrown. If one of the operations throws an exception, performs the
+ * remaining operations and rethrows the initial exception.
+ *
+ * execute_foreach() is a variant of std::foreach which invokes a function 
+ * object for each item in a sequence, catching all execptions and rethrowing
+ * the first caught exception after the function object has been invoked on each
+ * item.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/config/limits.hpp>   // MAX_EXECUTE_ARITY
+#include <ndnboost/preprocessor/arithmetic/dec.hpp>
+#include <ndnboost/preprocessor/cat.hpp>
+#include <ndnboost/preprocessor/iteration/local.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+#include <ndnboost/preprocessor/repetition/enum_binary_params.hpp>
+#include <ndnboost/preprocessor/punctuation/comma_if.hpp>
+#include <ndnboost/utility/result_of.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+// Helper for class template execute_traits.
+template<typename Result>
+struct execute_traits_impl {
+    typedef Result result_type;
+    template<typename Op>
+    static Result execute(Op op) { return op(); }
+};
+
+// Specialization for void return. For simplicity, execute() returns int 
+// for operations returning void. This could be avoided with additional work.
+template<>
+struct execute_traits_impl<void> {
+    typedef int result_type;
+    template<typename Op>
+    static int execute(Op op) { op(); return 0; }
+};
+
+// Deduces the result type of Op and allows uniform treatment of operations 
+// returning void and non-void.
+template< typename Op, 
+          typename Result = // VC6.5 workaround.
+              #if !defined(NDNBOOST_NO_RESULT_OF) && \
+                  !NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x592))
+                  typename ndnboost::result_of<Op()>::type
+              #else
+                  NDNBOOST_DEDUCED_TYPENAME Op::result_type
+              #endif
+          >
+struct execute_traits 
+    : execute_traits_impl<Result>
+    { };
+
+// Implementation with no cleanup operations.
+template<typename Op>
+typename execute_traits<Op>::result_type 
+execute_all(Op op) 
+{ 
+    return execute_traits<Op>::execute(op);
+}
+
+// Implementation with one or more cleanup operations
+#define NDNBOOST_PP_LOCAL_MACRO(n) \
+   template<typename Op, NDNBOOST_PP_ENUM_PARAMS(n, typename C)> \
+   typename execute_traits<Op>::result_type \
+   execute_all(Op op, NDNBOOST_PP_ENUM_BINARY_PARAMS(n, C, c)) \
+   { \
+       typename execute_traits<Op>::result_type r; \
+       try { \
+           r = ndnboost::iostreams::detail::execute_all( \
+                   op NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+                   NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_PP_DEC(n), c) \
+               ); \
+       } catch (...) { \
+           try { \
+               NDNBOOST_PP_CAT(c, NDNBOOST_PP_DEC(n))(); \
+           } catch (...) { } \
+           throw; \
+       } \
+       NDNBOOST_PP_CAT(c, NDNBOOST_PP_DEC(n))(); \
+       return r; \
+   } \
+   /**/
+
+#define NDNBOOST_PP_LOCAL_LIMITS (1, NDNBOOST_IOSTREAMS_MAX_EXECUTE_ARITY)
+#include NDNBOOST_PP_LOCAL_ITERATE()
+#undef NDNBOOST_PP_LOCAL_MACRO
+
+template<class InIt, class Op>
+Op execute_foreach(InIt first, InIt last, Op op)
+{
+    if (first == last)
+        return op;
+    try {
+        op(*first);
+    } catch (...) {
+        try {
+            ++first;
+            ndnboost::iostreams::detail::execute_foreach(first, last, op);
+        } catch (...) { }
+        throw;
+    }
+    ++first;
+    return ndnboost::iostreams::detail::execute_foreach(first, last, op);
+}
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/file_handle.hpp b/include/ndnboost/iostreams/detail/file_handle.hpp
new file mode 100644
index 0000000..4f35d1d
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/file_handle.hpp
@@ -0,0 +1,32 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * File:        ndnboost/iostreams/detail/file_handle.hpp
+ * Date:        Sun Jun 22 14:23:12 MDT 2008
+ * Copyright:   2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the type ndnboost::iostreams::detail::file_handle, representing an
+ * operating system file handle.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_FILE_HANDLE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_FILE_HANDLE_HPP_INCLUDED
+
+#include <ndnboost/iostreams/detail/config/windows_posix.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    typedef void*  file_handle;  // A.k.a. HANDLE
+#else
+    typedef int    file_handle;
+#endif
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_FILE_HANDLE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/forward.hpp b/include/ndnboost/iostreams/detail/forward.hpp
new file mode 100644
index 0000000..a45b903
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/forward.hpp
@@ -0,0 +1,124 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED   
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif                  
+ 
+#include <ndnboost/config.hpp> // NDNBOOST_MSVC, NDNBOOST_NO_SFINAE
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/config/limits.hpp>
+#include <ndnboost/iostreams/detail/push_params.hpp>
+#include <ndnboost/preprocessor/arithmetic/dec.hpp>
+#include <ndnboost/preprocessor/arithmetic/inc.hpp>
+#include <ndnboost/preprocessor/punctuation/comma_if.hpp>
+#include <ndnboost/preprocessor/repetition/enum_binary_params.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+#include <ndnboost/preprocessor/repetition/repeat_from_to.hpp>
+#include <ndnboost/preprocessor/tuple/elem.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+//------Macros for defining forwarding constructors and open overloads--------//
+    
+//
+// Macro: NDNBOOST_IOSTREAMS_FORWARD(class, impl, device, params, args)
+// Description: Defines constructors and overloads of 'open' which construct
+//      a device using the specified argument list and pass it to the specified
+//      helper function
+//   class - The class name
+//   impl - The helper function
+//   device - The device type
+//   params - The list of formal parameters trailing the device parameter in
+//     the helper function's signature
+//   params - The list of arguments passed to the helper function, following the
+//     device argument
+//
+#define NDNBOOST_IOSTREAMS_FORWARD(class, impl, device, params, args) \
+    class(const device& t params()) \
+    { this->impl(::ndnboost::iostreams::detail::wrap(t) args()); } \
+    class(device& t params()) \
+    { this->impl(::ndnboost::iostreams::detail::wrap(t) args()); } \
+    class(const ::ndnboost::reference_wrapper<device>& ref params()) \
+    { this->impl(ref args()); } \
+    void open(const device& t params()) \
+    { this->impl(::ndnboost::iostreams::detail::wrap(t) args()); } \
+    void open(device& t params()) \
+    { this->impl(::ndnboost::iostreams::detail::wrap(t) args()); } \
+    void open(const ::ndnboost::reference_wrapper<device>& ref params()) \
+    { this->impl(ref args()); } \
+    NDNBOOST_PP_REPEAT_FROM_TO( \
+        1, NDNBOOST_PP_INC(NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY), \
+        NDNBOOST_IOSTREAMS_FORWARDING_CTOR, (class, impl, device) \
+    ) \
+    NDNBOOST_PP_REPEAT_FROM_TO( \
+        1, NDNBOOST_PP_INC(NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY), \
+        NDNBOOST_IOSTREAMS_FORWARDING_FN, (class, impl, device) \
+    ) \
+    /**/
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+# define NDNBOOST_IOSTREAMS_FORWARDING_CTOR_I(z, n, tuple) \
+    template< typename U100 NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+              NDNBOOST_PP_ENUM_PARAMS_Z(z, NDNBOOST_PP_DEC(n), typename U) > \
+    NDNBOOST_PP_TUPLE_ELEM(3, 0, tuple) \
+    ( U100& u100 NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+      NDNBOOST_PP_ENUM_BINARY_PARAMS_Z(z, NDNBOOST_PP_DEC(n), const U, &u) \
+      NDNBOOST_IOSTREAMS_DISABLE_IF_SAME(U100, NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple))) \
+    { this->NDNBOOST_PP_TUPLE_ELEM(3, 1, tuple) \
+      ( NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple) \
+        ( u100 NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+          NDNBOOST_PP_ENUM_PARAMS_Z(z, NDNBOOST_PP_DEC(n), u)) ); } \
+    /**/
+# define NDNBOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple) \
+    template< typename U100 NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+              NDNBOOST_PP_ENUM_PARAMS_Z(z, NDNBOOST_PP_DEC(n), typename U) > \
+    void open \
+    ( U100& u100 NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+      NDNBOOST_PP_ENUM_BINARY_PARAMS_Z(z, NDNBOOST_PP_DEC(n), const U, &u) \
+      NDNBOOST_IOSTREAMS_DISABLE_IF_SAME(U100, NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple))) \
+    { this->NDNBOOST_PP_TUPLE_ELEM(3, 1, tuple) \
+      ( u100 NDNBOOST_PP_COMMA_IF(NDNBOOST_PP_DEC(n)) \
+        NDNBOOST_PP_ENUM_PARAMS_Z(z, NDNBOOST_PP_DEC(n), u) ); } \
+    /**/
+#else
+# define NDNBOOST_IOSTREAMS_FORWARDING_CTOR_I(z, n, tuple)
+# define NDNBOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple)
+#endif
+#define NDNBOOST_IOSTREAMS_FORWARDING_CTOR(z, n, tuple) \
+    template<NDNBOOST_PP_ENUM_PARAMS_Z(z, n, typename U)> \
+    NDNBOOST_PP_TUPLE_ELEM(3, 0, tuple) \
+    (NDNBOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const U, &u) \
+      NDNBOOST_IOSTREAMS_DISABLE_IF_SAME(U0, NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple))) \
+    { this->NDNBOOST_PP_TUPLE_ELEM(3, 1, tuple) \
+      ( NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple) \
+        (NDNBOOST_PP_ENUM_PARAMS_Z(z, n, u)) ); } \
+    NDNBOOST_IOSTREAMS_FORWARDING_CTOR_I(z, n, tuple) \
+    /**/
+#define NDNBOOST_IOSTREAMS_FORWARDING_FN(z, n, tuple) \
+    template<NDNBOOST_PP_ENUM_PARAMS_Z(z, n, typename U)> \
+    void open(NDNBOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const U, &u) \
+      NDNBOOST_IOSTREAMS_DISABLE_IF_SAME(U0, NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple))) \
+    { this->NDNBOOST_PP_TUPLE_ELEM(3, 1, tuple) \
+      ( NDNBOOST_PP_TUPLE_ELEM(3, 2, tuple) \
+        (NDNBOOST_PP_ENUM_PARAMS_Z(z, n, u)) ); } \
+    NDNBOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple) \
+    /**/
+
+// Disable forwarding constructors if first parameter type is the same
+// as the device type
+#if !defined(NDNBOOST_NO_SFINAE) && \
+    !NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x592))
+# define NDNBOOST_IOSTREAMS_DISABLE_IF_SAME(device, param) \
+    , typename ndnboost::disable_if< ndnboost::is_same<device, param> >::type* = 0 \
+    /**/
+#else 
+# define NDNBOOST_IOSTREAMS_DISABLE_IF_SAME(device, param)
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/fstream.hpp b/include/ndnboost/iostreams/detail/fstream.hpp
new file mode 100644
index 0000000..50620a7
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/fstream.hpp
@@ -0,0 +1,33 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+                 
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# include <fstream>
+#else
+# include <fstream.h>
+#endif 
+
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# define NDNBOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::basic_ifstream<Ch, Tr>
+# define NDNBOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::basic_ofstream<Ch, Tr>
+# define NDNBOOST_IOSTREAMS_BASIC_FSTREAM(Ch, Tr) std::basic_fstream<Ch, Tr>
+# define NDNBOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::basic_filebuf<Ch>
+#else 
+# define NDNBOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::ifstream
+# define NDNBOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::ofstream
+# define NDNBOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::filebuf
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/functional.hpp b/include/ndnboost/iostreams/detail/functional.hpp
new file mode 100644
index 0000000..52a825e
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/functional.hpp
@@ -0,0 +1,189 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/detail/functional.hpp
+ * Date:        Sun Dec 09 05:38:03 MST 2007
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+
+ * Defines several function objects and object generators for use with 
+ * execute_all()
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/close.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp> // NDNBOOST_IOS
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+    // Function objects and object generators for invoking
+    // ndnboost::iostreams::close
+
+template<typename T>
+class device_close_operation {
+public:
+    typedef void result_type;
+    device_close_operation(T& t, NDNBOOST_IOS::openmode which) 
+        : t_(t), which_(which) 
+        { }
+    void operator()() const { ndnboost::iostreams::close(t_, which_); }
+private:
+    device_close_operation& operator=(const device_close_operation&);
+    T&                   t_;
+    NDNBOOST_IOS::openmode  which_;
+};
+
+template<typename T, typename Sink>
+class filter_close_operation {
+public:
+    typedef void result_type;
+    filter_close_operation(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+        : t_(t), snk_(snk), which_(which)
+        { }
+    void operator()() const { ndnboost::iostreams::close(t_, snk_, which_); }
+private:
+    filter_close_operation& operator=(const filter_close_operation&);
+    T&                   t_;
+    Sink&                snk_;
+    NDNBOOST_IOS::openmode  which_;
+};
+
+template<typename T>
+device_close_operation<T> 
+call_close(T& t, NDNBOOST_IOS::openmode which) 
+{ return device_close_operation<T>(t, which); }
+
+template<typename T, typename Sink>
+filter_close_operation<T, Sink> 
+call_close(T& t, Sink& snk, NDNBOOST_IOS::openmode which) 
+{ return filter_close_operation<T, Sink>(t, snk, which); }
+
+    // Function objects and object generators for invoking
+    // ndnboost::iostreams::detail::close_all
+
+template<typename T>
+class device_close_all_operation {
+public:
+    typedef void result_type;
+    device_close_all_operation(T& t) : t_(t) { }
+    void operator()() const { detail::close_all(t_); }
+private:
+    device_close_all_operation& operator=(const device_close_all_operation&);
+    T& t_;
+};
+
+template<typename T, typename Sink>
+class filter_close_all_operation {
+public:
+    typedef void result_type;
+    filter_close_all_operation(T& t, Sink& snk) : t_(t), snk_(snk) { }
+    void operator()() const { detail::close_all(t_, snk_); }
+private:
+    filter_close_all_operation& operator=(const filter_close_all_operation&);
+    T&     t_;
+    Sink&  snk_;
+};
+
+template<typename T>
+device_close_all_operation<T> call_close_all(T& t) 
+{ return device_close_all_operation<T>(t); }
+
+template<typename T, typename Sink>
+filter_close_all_operation<T, Sink> 
+call_close_all(T& t, Sink& snk) 
+{ return filter_close_all_operation<T, Sink>(t, snk); }
+
+    // Function object and object generator for invoking a
+    // member function void close(std::ios_base::openmode)
+
+template<typename T>
+class member_close_operation {
+public:
+    typedef void result_type;
+    member_close_operation(T& t, NDNBOOST_IOS::openmode which) 
+        : t_(t), which_(which) 
+        { }
+    void operator()() const { t_.close(which_); }
+private:
+    member_close_operation& operator=(const member_close_operation&);
+    T&                   t_;
+    NDNBOOST_IOS::openmode  which_;
+};
+
+template<typename T>
+member_close_operation<T> call_member_close(T& t, NDNBOOST_IOS::openmode which) 
+{ return member_close_operation<T>(t, which); }
+
+    // Function object and object generator for invoking a
+    // member function void reset()
+
+template<typename T>
+class reset_operation {
+public:
+    reset_operation(T& t) : t_(t) { }
+    void operator()() const { t_.reset(); }
+private:
+    reset_operation& operator=(const reset_operation&);
+    T& t_;
+};
+
+template<typename T>
+reset_operation<T> call_reset(T& t) { return reset_operation<T>(t); }
+
+    // Function object and object generator for clearing a flag
+
+template<typename T>
+class clear_flags_operation {
+public:
+    typedef void result_type;
+    clear_flags_operation(T& t) : t_(t) { }
+    void operator()() const { t_ = 0; }
+private:
+    clear_flags_operation& operator=(const clear_flags_operation&);
+    T& t_;
+};
+
+template<typename T>
+clear_flags_operation<T> clear_flags(T& t) 
+{ return clear_flags_operation<T>(t); }
+
+    // Function object and generator for flushing a buffer
+
+// Function object for use with execute_all()
+template<typename Buffer, typename Device>
+class flush_buffer_operation {
+public:
+    typedef void result_type;
+    flush_buffer_operation(Buffer& buf, Device& dev, bool flush)
+        : buf_(buf), dev_(dev), flush_(flush)
+        { }
+    void operator()() const
+    {
+        if (flush_) 
+            buf_.flush(dev_);
+    }
+private:
+    flush_buffer_operation& operator=(const flush_buffer_operation&);
+    Buffer&  buf_;
+    Device&  dev_;
+    bool     flush_;
+};
+
+template<typename Buffer, typename Device>
+flush_buffer_operation<Buffer, Device> 
+flush_buffer(Buffer& buf, Device& dev, bool flush)
+{ return flush_buffer_operation<Buffer, Device>(buf, dev, flush); }
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/ios.hpp b/include/ndnboost/iostreams/detail/ios.hpp
new file mode 100644
index 0000000..9d3cfc0
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/ios.hpp
@@ -0,0 +1,66 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+                 
+#include <ndnboost/config.hpp> // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# if !NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003)
+#  include <ios>
+# else
+#  include <istream>
+#  include <ostream>
+# endif
+#else 
+# include <exception>
+# include <iosfwd>
+#endif 
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
+# define NDNBOOST_IOSTREAMS_BASIC_IOS(ch, tr)  std::basic_ios< ch, tr >
+# if !NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003) && \
+     !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
+     !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) \
+     /**/
+
+#define NDNBOOST_IOS                std::ios
+#define NDNBOOST_IOSTREAMS_FAILURE  std::ios::failure
+
+# else
+
+#define NDNBOOST_IOS                std::ios_base
+#define NDNBOOST_IOSTREAMS_FAILURE  std::ios_base::failure
+
+# endif
+#else // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
+
+#define NDNBOOST_IOS                          std::ios
+#define NDNBOOST_IOSTREAMS_BASIC_IOS(ch, tr)  std::ios
+#define NDNBOOST_IOSTREAMS_FAILURE            ndnboost::iostreams::detail::failure
+
+class failure : std::exception {    
+public:
+    explicit failure(const std::string& what_arg) : what_(what_arg) { }
+    const char* what() const { return what_.c_str(); }
+private:
+    std::string what_;
+};
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------//
+
+} } } // End namespace failure, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/iostream.hpp b/include/ndnboost/iostreams/detail/iostream.hpp
new file mode 100644
index 0000000..26d21ab
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/iostream.hpp
@@ -0,0 +1,34 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+                 
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# include <istream>
+# include <ostream>
+#else
+# include <iostream.h>
+#endif
+
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# define NDNBOOST_IOSTREAMS_BASIC_ISTREAM(ch, tr) std::basic_istream< ch, tr >
+# define NDNBOOST_IOSTREAMS_BASIC_OSTREAM(ch, tr) std::basic_ostream< ch, tr >
+# define NDNBOOST_IOSTREAMS_BASIC_IOSTREAM(ch, tr) std::basic_iostream< ch, tr >
+#else
+# define NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::streambuf
+# define NDNBOOST_IOSTREAMS_BASIC_ISTREAM(ch, tr) std::istream
+# define NDNBOOST_IOSTREAMS_BASIC_OSTREAM(ch, tr) std::ostream
+# define NDNBOOST_IOSTREAMS_BASIC_IOSTREAM(ch, tr) std::iostream
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/is_dereferenceable.hpp b/include/ndnboost/iostreams/detail/is_dereferenceable.hpp
new file mode 100644
index 0000000..7ee8c58
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/is_dereferenceable.hpp
@@ -0,0 +1,85 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// (C) Copyright David Abrahams 2004.
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED
+
+# include <ndnboost/type_traits/detail/bool_trait_def.hpp>
+# include <ndnboost/type_traits/detail/template_arity_spec.hpp>
+# include <ndnboost/type_traits/remove_cv.hpp>
+# include <ndnboost/mpl/aux_/lambda_support.hpp>
+# include <ndnboost/mpl/bool.hpp>
+# include <ndnboost/detail/workaround.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail { 
+
+// is_dereferenceable<T> metafunction
+//
+// Requires: Given x of type T&, if the expression *x is well-formed
+// it must have complete type; otherwise, it must neither be ambiguous
+// nor violate access.
+
+// This namespace ensures that ADL doesn't mess things up.
+namespace is_dereferenceable_
+{
+  // a type returned from operator* when no increment is found in the
+  // type's own namespace
+  struct tag {};
+  
+  // any soaks up implicit conversions and makes the following
+  // operator* less-preferred than any other such operator that
+  // might be found via ADL.
+  struct any { template <class T> any(T const&); };
+
+  // This is a last-resort operator* for when none other is found
+  tag operator*(any const&);
+
+# if NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3202)) \
+    || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+#  define NDNBOOST_comma(a,b) (a)
+# else 
+  // In case an operator++ is found that returns void, we'll use ++x,0
+  tag operator,(tag,int);  
+#  define NDNBOOST_comma(a,b) (a,b)
+# endif 
+  
+  // two check overloads help us identify which operator++ was picked
+  char (& check_increment(tag) )[2];
+  
+  template <class T>
+  char check_increment(T const&);
+  
+  template <class T>
+  struct impl
+  {
+      static typename ndnboost::remove_cv<T>::type& x;
+
+      NDNBOOST_STATIC_CONSTANT(
+          bool
+        , value = sizeof(is_dereferenceable_::check_increment(NDNBOOST_comma(*x,0))) == 1
+      );
+  };
+}
+
+# undef NDNBOOST_comma
+
+template<typename T> 
+struct is_dereferenceable 
+    NDNBOOST_TT_AUX_BOOL_C_BASE(is_dereferenceable_::impl<T>::value)
+{ 
+    NDNBOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(is_dereferenceable_::impl<T>::value)
+    NDNBOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_dereferenceable,(T))
+};
+
+} } 
+
+NDNBOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::ndnboost::iostreams::detail::is_dereferenceable)
+
+} // End namespaces detail, iostreams, boost.
+
+#endif // NDNBOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/is_iterator_range.hpp b/include/ndnboost/iostreams/detail/is_iterator_range.hpp
new file mode 100644
index 0000000..3dcbcc5
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/is_iterator_range.hpp
@@ -0,0 +1,49 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED       
+ 
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/bool_trait_def.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { 
+
+# if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //---------------------------------//
+
+// We avoid dependence on Boost.Range by using a forward declaration.
+template<typename Iterator>
+class iterator_range;
+    
+namespace iostreams {
+
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iterator_range, ndnboost::iterator_range, 1)
+
+} // End namespace iostreams.
+
+# else // # if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) //-----------------------//
+
+namespace iostreams {    
+
+    template<typename T>
+    struct is_iterator_range {
+        NDNBOOST_STATIC_CONSTANT(bool, value = false);
+    };
+
+} // End namespace iostreams.
+
+# endif // # if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //----------------------//
+
+} // End namespace ndnboost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/newline.hpp b/include/ndnboost/iostreams/detail/newline.hpp
new file mode 100644
index 0000000..72a7d10
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/newline.hpp
@@ -0,0 +1,32 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Ch>
+struct newline;
+
+template<>
+struct newline<char> {
+    NDNBOOST_STATIC_CONSTANT(char, value = '\n');
+};
+
+template<>
+struct newline<wchar_t> {
+    NDNBOOST_STATIC_CONSTANT(wchar_t, value = L'\n');
+};
+
+} } } // End namespaces detaill, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/optional.hpp b/include/ndnboost/iostreams/detail/optional.hpp
new file mode 100644
index 0000000..3af910a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/optional.hpp
@@ -0,0 +1,114 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Recent changes to Boost.Optional involving assigment broke Boost.Iostreams,
+// in a way which could be remedied only by relying on the deprecated reset
+// functions; with VC6, even reset didn't work. Until this problem is 
+// understood, Iostreams will use a private version of optional with a smart 
+// pointer interface.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/assert.hpp>
+#include <ndnboost/mpl/int.hpp>
+#include <ndnboost/type_traits/aligned_storage.hpp>
+#include <ndnboost/type_traits/alignment_of.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+// Taken from <ndnboost/optional.hpp>.
+template<class T>
+class aligned_storage
+{
+    // Borland ICEs if unnamed unions are used for this!
+    union dummy_u
+    {
+        char data[ sizeof(T) ];
+        NDNBOOST_DEDUCED_TYPENAME type_with_alignment<
+          ::ndnboost::alignment_of<T>::value >::type aligner_;
+    } dummy_ ;
+
+  public:
+
+    void const* address() const { return &dummy_.data[0]; }
+    void      * address()       { return &dummy_.data[0]; }
+};
+
+template<typename T>
+class optional {
+public:
+    typedef T element_type;
+    optional() : initialized_(false) { }
+    optional(const T& t) : initialized_(false) { reset(t); }
+    ~optional() { reset(); }
+    T& operator*() 
+    { 
+        NDNBOOST_ASSERT(initialized_);
+        return *static_cast<T*>(address()); 
+    }
+    const T& operator*() const
+    { 
+        NDNBOOST_ASSERT(initialized_);
+        return *static_cast<const T*>(address()); 
+    }
+    T* operator->() 
+    { 
+        NDNBOOST_ASSERT(initialized_);
+        return static_cast<T*>(address()); 
+    }
+    const T* operator->() const
+    { 
+        NDNBOOST_ASSERT(initialized_);
+        return static_cast<const T*>(address()); 
+    }
+    T* get() 
+    { 
+        NDNBOOST_ASSERT(initialized_);
+        return static_cast<T*>(address()); 
+    }
+    const T* get() const
+    { 
+        NDNBOOST_ASSERT(initialized_);
+        return static_cast<const T*>(address()); 
+    }
+    void reset() 
+    {
+        if (initialized_) { 
+        #if NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x564)) || \
+            NDNBOOST_WORKAROUND(__IBMCPP__, NDNBOOST_TESTED_AT(600)) \
+            /**/
+            T* t = static_cast<T*>(address());
+            t->~T();
+        #else
+            static_cast<T*>(address())->T::~T();
+        #endif
+            initialized_ = false;
+        }
+    }
+    void reset(const T& t) 
+    {
+        reset();
+        new (address()) T(t); 
+        initialized_ = true;
+    }
+private:
+    optional(const optional&);
+    optional& operator=(const optional&);
+    void* address() { return &storage_; }
+    const void* address() const { return &storage_; }
+    aligned_storage<T>  storage_;
+    bool                initialized_;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/param_type.hpp b/include/ndnboost/iostreams/detail/param_type.hpp
new file mode 100644
index 0000000..15da495
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/param_type.hpp
@@ -0,0 +1,27 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename T>
+struct param_type {
+    typedef typename mpl::if_<is_std_io<T>, T&, const T&>::type type;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED //-----------//
diff --git a/include/ndnboost/iostreams/detail/path.hpp b/include/ndnboost/iostreams/detail/path.hpp
new file mode 100644
index 0000000..bafc980
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/path.hpp
@@ -0,0 +1,214 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * File:        ndnboost/iostreams/detail/path.hpp
+ * Date:        Sat Jun 21 21:24:05 MDT 2008
+ * Copyright:   2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the class ndnboost::iostreams::detail::path, for storing a 
+ * a std::string or std::wstring.
+ *
+ * This class allows interoperability with Boost.Filesystem without
+ * creating a dependence on Boost.Filesystem headers or implementation.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED
+
+#include <cstring>
+#include <string>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+# include <cwchar>
+#endif
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS //------------------------------------//
+
+class path {
+    template<typename T, typename V>
+    struct sfinae
+    {
+        typedef V type;
+    };
+public:
+
+    // Default constructor
+    path() : narrow_(), wide_(), is_wide_(false) { }
+
+    // Constructor taking a std::string
+    path(const std::string& p) : narrow_(p), wide_(), is_wide_(false) { }
+
+    // Constructor taking a C-style string
+    path(const char* p) : narrow_(p), wide_(), is_wide_(false) { }
+
+    // Constructor taking a ndnboost::filesystem2::path or
+    // ndnboost::filesystem2::wpath
+    template<typename Path>
+    explicit path(const Path& p, typename Path::external_string_type* = 0)
+    {
+        init(p.external_file_string());
+    }
+
+    // Constructor taking a ndnboost::filesystem3::path (boost filesystem v3)
+    template<typename Path>
+    explicit path(const Path& p, typename Path::codecvt_type* = 0)
+    {
+        init(p.native());
+    }
+
+    // Copy constructor
+    path(const path& p) 
+        : narrow_(p.narrow_), wide_(p.wide_), is_wide_(p.is_wide_) 
+        { }
+
+    // Assignment operator taking another path
+    path& operator=(const path& p)
+    {
+        narrow_ = p.narrow_;
+        wide_ = p.wide_;
+        is_wide_ = p.is_wide_;
+        return *this;
+    }
+
+    // Assignment operator taking a std::string
+    path& operator=(const std::string& p)
+    {
+        narrow_ = p;
+        wide_.clear();
+        is_wide_ = false;
+        return *this;
+    }
+
+    // Assignment operator taking a C-style string
+    path& operator=(const char* p)
+    {
+        narrow_.assign(p);
+        wide_.clear();
+        is_wide_ = false;
+        return *this;
+    }
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1400)
+    // Assignment operator taking a ndnboost::filesystem2::path or
+    // ndnboost::filesystem2::wpath
+    // (not on Visual C++ 7.1/8.0, as it seems to have problems with
+    // SFINAE functions with the same parameters, doesn't seem
+    // worth working around).
+    template<typename Path>
+    typename sfinae<typename Path::external_string_type, path&>::type
+        operator=(const Path& p)
+    {
+        init(p.external_file_string());
+        return *this;
+    }
+#endif
+
+    // Assignment operator taking a ndnboost::filesystem3::path
+    template<typename Path>
+    typename sfinae<typename Path::codecvt_type, path&>::type
+        operator=(const Path& p)
+    {
+        init(p.native());
+        return *this;
+    }
+
+    bool is_wide() const { return is_wide_; }
+
+    // Returns a representation of the underlying path as a std::string
+    // Requires: is_wide() returns false
+    const char* c_str() const { return narrow_.c_str(); }
+
+    // Returns a representation of the underlying path as a std::wstring
+    // Requires: is_wide() returns true
+    const wchar_t* c_wstr() const { return wide_.c_str(); }
+private:
+    
+    // For wide-character paths, use a ndnboost::filesystem::wpath instead of a
+    // std::wstring
+    path(const std::wstring&);
+    path& operator=(const std::wstring&);
+
+    void init(std::string const& file_path)
+    {
+        narrow_ = file_path;
+        wide_.clear();
+        is_wide_ = false;
+    }
+
+    void init(std::wstring const& file_path)
+    {
+        narrow_.clear();
+        wide_ = file_path;
+        is_wide_ = true;
+    }
+
+    std::string   narrow_;
+    std::wstring  wide_;
+    bool          is_wide_;
+};
+
+inline bool operator==(const path& lhs, const path& rhs)
+{
+    return lhs.is_wide() ?
+        rhs.is_wide() && std::wcscmp(lhs.c_wstr(), rhs.c_wstr()) == 0 :
+        !rhs.is_wide() && std::strcmp(lhs.c_str(), rhs.c_str()) == 0;
+}
+
+#else // #ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS //---------------------------//
+
+class path {
+public:
+    path() { }
+    path(const std::string& p) : path_(p) { }
+    path(const char* p) : path_(p) { }
+    template<typename Path>
+        path(const Path& p) : path_(p.external_file_string()) { }
+    path(const path& p) : path_(p.path_) { }
+    path& operator=(const path& other) 
+    {
+        path_ = other.path_;
+        return *this;
+    }
+    path& operator=(const std::string& p) 
+    {
+        path_ = p;
+        return *this;
+    }
+    path& operator=(const char* p) 
+    {
+        path_ = p;
+        return *this;
+    }
+    template<typename Path>
+        path& operator=(const Path& p)
+        {
+            path_ = p.external_file_string();
+            return *this;
+        }
+    bool is_wide() const { return false; }
+    const char* c_str() const { return path_.c_str(); }
+    const wchar_t* c_wstr() const { return 0; }
+private:
+    std::string path_;
+};
+
+inline bool operator==(const path& lhs, const path& rhs)
+{
+    return std::strcmp(lhs.c_str(), rhs.c_str()) == 0 ;
+}
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS //--------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/push.hpp b/include/ndnboost/iostreams/detail/push.hpp
new file mode 100644
index 0000000..5152d6a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/push.hpp
@@ -0,0 +1,154 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED 
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif                    
+ 
+#include <ndnboost/config.hpp> // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/adapter/range_adapter.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/enable_if_stream.hpp>   
+#include <ndnboost/iostreams/pipeline.hpp>   
+#include <ndnboost/iostreams/detail/push_params.hpp>   
+#include <ndnboost/iostreams/detail/resolve.hpp>
+#include <ndnboost/mpl/bool.hpp>   
+#include <ndnboost/preprocessor/cat.hpp> 
+#include <ndnboost/preprocessor/control/iif.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+//
+// Macro: NDNBOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name, mode, ch, helper).
+// Description: Defines overloads with name 'name' which forward to a function
+//      'helper' which takes a filter or devide by const reference.
+//
+#define NDNBOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name, mode, ch, helper) \
+    NDNBOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, 0, ?) \
+    /**/
+
+//
+// Macro: NDNBOOST_IOSTREAMS_DEFINE_PUSH(name, mode, ch, helper).
+// Description: Defines constructors which forward to a function
+//      'helper' which takes a filter or device by const reference.
+//
+#define NDNBOOST_IOSTREAMS_DEFINE_PUSH(name, mode, ch, helper) \
+    NDNBOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, 1, void) \
+    /**/
+
+//--------------------Definition of NDNBOOST_IOSTREAMS_DEFINE_PUSH_IMPL----------//
+          
+#define NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, arg, helper, has_return) \
+    this->helper( ::ndnboost::iostreams::detail::resolve<mode, ch>(arg) \
+                  NDNBOOST_IOSTREAMS_PUSH_ARGS() ); \
+    /**/
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) && \
+    !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600) \
+    /**/
+# ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+#  define NDNBOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \
+    template<typename CharType, typename TraitsType> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(::std::basic_streambuf<CharType, TraitsType>& sb NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \
+    template<typename CharType, typename TraitsType> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(::std::basic_istream<CharType, TraitsType>& is NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_STATIC_ASSERT((!is_convertible<mode, output>::value)); \
+      NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \
+    template<typename CharType, typename TraitsType> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(::std::basic_ostream<CharType, TraitsType>& os NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_STATIC_ASSERT((!is_convertible<mode, input>::value)); \
+      NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \
+    template<typename CharType, typename TraitsType> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(::std::basic_iostream<CharType, TraitsType>& io NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \
+    template<typename Iter> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(const iterator_range<Iter>& rng NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_PP_EXPR_IF(has_return, return) \
+    this->helper( ::ndnboost::iostreams::detail::range_adapter< \
+                      mode, iterator_range<Iter> \
+                  >(rng) \
+                  NDNBOOST_IOSTREAMS_PUSH_ARGS() ); } \
+    template<typename Pipeline, typename Concept> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(const ::ndnboost::iostreams::pipeline<Pipeline, Concept>& p) \
+    { p.push(*this); } \
+    template<typename T> \
+    NDNBOOST_PP_IIF(has_return, result, explicit) \
+    name(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS() NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) \
+    { this->helper( ::ndnboost::iostreams::detail::resolve<mode, ch>(t) \
+                    NDNBOOST_IOSTREAMS_PUSH_ARGS() ); } \
+    /**/
+# else // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+#  define NDNBOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(::std::streambuf& sb NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(::std::istream& is NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_STATIC_ASSERT((!is_convertible<mode, output>::value)); \
+      NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(::std::ostream& os NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_STATIC_ASSERT((!is_convertible<mode, input>::value)); \
+      NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(::std::iostream& io NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \
+    template<typename Iter> \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(const iterator_range<Iter>& rng NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { NDNBOOST_PP_EXPR_IF(has_return, return) \
+    this->helper( ::ndnboost::iostreams::detail::range_adapter< \
+                      mode, iterator_range<Iter> \
+                  >(rng) \
+                  NDNBOOST_IOSTREAMS_PUSH_ARGS() ); } \
+    template<typename Pipeline, typename Concept> \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(const ::ndnboost::iostreams::pipeline<Pipeline, Concept>& p) \
+    { p.push(*this); } \
+    template<typename T> \
+    NDNBOOST_PP_EXPR_IF(has_return, result) \
+    name(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS() NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) \
+    { this->helper( ::ndnboost::iostreams::detail::resolve<mode, ch>(t) \
+                    NDNBOOST_IOSTREAMS_PUSH_ARGS() ); } \
+    /**/
+# endif // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+#else // #if VC6, VC7.0, Borland 5.x
+# define NDNBOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \
+    template<typename T> \
+    void NDNBOOST_PP_CAT(name, _msvc_impl) \
+    ( ::ndnboost::mpl::true_, const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS() ) \
+    { t.push(*this); } \
+    template<typename T> \
+    void NDNBOOST_PP_CAT(name, _msvc_impl) \
+    ( ::ndnboost::mpl::false_, const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS() ) \
+    { this->helper( ::ndnboost::iostreams::detail::resolve<mode, ch>(t) \
+                    NDNBOOST_IOSTREAMS_PUSH_ARGS() ); } \
+    template<typename T> \
+    NDNBOOST_PP_IF(has_return, result, explicit) \
+    name(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+    { \
+        this->NDNBOOST_PP_CAT(name, _msvc_impl) \
+              ( ::ndnboost::iostreams::detail::is_pipeline<T>(), \
+                t NDNBOOST_IOSTREAMS_PUSH_ARGS() ); \
+    } \
+    /**/
+#endif // #if VC6, VC7.0, Borland 5.x
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/push_params.hpp b/include/ndnboost/iostreams/detail/push_params.hpp
new file mode 100644
index 0000000..bbb214c
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/push_params.hpp
@@ -0,0 +1,21 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED 
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif                    
+
+#define NDNBOOST_IOSTREAMS_PUSH_PARAMS() \
+    , std::streamsize buffer_size = -1 , std::streamsize pback_size = -1 \
+    /**/
+
+#define NDNBOOST_IOSTREAMS_PUSH_ARGS() , buffer_size, pback_size     
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/resolve.hpp b/include/ndnboost/iostreams/detail/resolve.hpp
new file mode 100644
index 0000000..1d0fa56
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/resolve.hpp
@@ -0,0 +1,235 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp> // partial spec, put size_t in std.
+#include <cstddef>          // std::size_t.
+#include <ndnboost/detail/is_incrementable.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/adapter/mode_adapter.hpp>
+#include <ndnboost/iostreams/detail/adapter/output_iterator_adapter.hpp>
+#include <ndnboost/iostreams/detail/adapter/range_adapter.hpp>
+#include <ndnboost/iostreams/detail/config/gcc.hpp>
+#include <ndnboost/iostreams/detail/config/overload_resolution.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/enable_if_stream.hpp>
+#include <ndnboost/iostreams/detail/is_dereferenceable.hpp>
+#include <ndnboost/iostreams/detail/is_iterator_range.hpp>
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/device/array.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/and.hpp>
+#include <ndnboost/mpl/bool.hpp> // true_.
+#include <ndnboost/mpl/if.hpp>
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+# include <ndnboost/range/iterator_range.hpp>
+#endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+#include <ndnboost/type_traits/is_array.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4224.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+//------------------Definition of resolve-------------------------------------//
+
+#ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------//
+
+template<typename Mode, typename Ch, typename T>
+struct resolve_traits {
+    typedef typename 
+            mpl::if_<
+                ndnboost::detail::is_incrementable<T>,
+                output_iterator_adapter<Mode, Ch, T>,
+                const T&
+            >::type type;
+};
+
+# ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type
+resolve( const T& t 
+         NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T)
+
+         // I suspect that the compilers which require this workaround may
+         // be correct, but I'm not sure why :(
+         #if NDNBOOST_WORKAROUND(NDNBOOST_INTEL_CXX_VERSION, NDNBOOST_TESTED_AT(810)) ||\
+             NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3205)) || \
+             NDNBOOST_WORKAROUND(NDNBOOST_IOSTREAMS_GCC, NDNBOOST_TESTED_AT(400)) ||\
+             NDNBOOST_WORKAROUND(__IBMCPP__, NDNBOOST_TESTED_AT(1110))
+             /**/
+         , typename disable_if< is_iterator_range<T> >::type* = 0
+         #endif
+         )
+{
+    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
+    return return_type(t);
+}
+
+template<typename Mode, typename Ch, typename Tr>
+mode_adapter< Mode, std::basic_streambuf<Ch, Tr> > 
+resolve(std::basic_streambuf<Ch, Tr>& sb)
+{ return mode_adapter< Mode, std::basic_streambuf<Ch, Tr> >(wrap(sb)); }
+
+template<typename Mode, typename Ch, typename Tr>
+mode_adapter< Mode, std::basic_istream<Ch, Tr> > 
+resolve(std::basic_istream<Ch, Tr>& is)
+{ return mode_adapter< Mode, std::basic_istream<Ch, Tr> >(wrap(is)); }
+
+template<typename Mode, typename Ch, typename Tr>
+mode_adapter< Mode, std::basic_ostream<Ch, Tr> > 
+resolve(std::basic_ostream<Ch, Tr>& os)
+{ return mode_adapter< Mode, std::basic_ostream<Ch, Tr> >(wrap(os)); }
+
+template<typename Mode, typename Ch, typename Tr>
+mode_adapter< Mode, std::basic_iostream<Ch, Tr> > 
+resolve(std::basic_iostream<Ch, Tr>& io)
+{ return mode_adapter< Mode, std::basic_iostream<Ch, Tr> >(wrap(io)); }
+
+template<typename Mode, typename Ch, std::size_t N>
+array_adapter<Mode, Ch> resolve(Ch (&array)[N])
+{ return array_adapter<Mode, Ch>(array); }
+
+#  if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+    template<typename Mode, typename Ch, typename Iter>
+    range_adapter< Mode, ndnboost::iterator_range<Iter> > 
+    resolve(const ndnboost::iterator_range<Iter>& rng)
+    { return range_adapter< Mode, ndnboost::iterator_range<Iter> >(rng); }
+#  endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+
+# else // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type
+resolve( const T& t 
+         NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T)
+         #if defined(__GNUC__)
+         , typename disable_if< is_iterator_range<T> >::type* = 0
+         #endif
+         )
+{
+    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
+    return return_type(t);
+}
+
+template<typename Mode, typename Ch>
+mode_adapter<Mode, std::streambuf> 
+resolve(std::streambuf& sb) 
+{ return mode_adapter<Mode, std::streambuf>(wrap(sb)); }
+
+template<typename Mode, typename Ch>
+mode_adapter<Mode, std::istream> 
+resolve(std::istream& is)
+{ return mode_adapter<Mode, std::istream>(wrap(is)); }
+
+template<typename Mode, typename Ch>
+mode_adapter<Mode, std::ostream> 
+resolve(std::ostream& os)
+{ return mode_adapter<Mode, std::ostream>(wrap(os)); }
+
+template<typename Mode, typename Ch>
+mode_adapter<Mode, std::iostream> 
+resolve(std::iostream& io)
+{ return mode_adapter<Mode, std::iostream>(wrap(io)); }
+
+template<typename Mode, typename Ch, std::size_t N>
+array_adapter<Mode, Ch> resolve(Ch (&array)[N])
+{ return array_adapter<Mode, Ch>(array); }
+
+template<typename Mode, typename Ch, typename Iter>
+range_adapter< Mode, ndnboost::iterator_range<Iter> > 
+resolve(const ndnboost::iterator_range<Iter>& rng)
+{ return range_adapter< Mode, ndnboost::iterator_range<Iter> >(rng); }
+
+# endif // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
+#else // #ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
+
+template<typename Mode, typename Ch, typename T>
+struct resolve_traits {
+    // Note: test for is_iterator_range must come before test for output
+    // iterator.
+    typedef typename 
+            iostreams::select<  // Disambiguation for Tru64.
+                is_std_io<T>,
+                mode_adapter<Mode, T>,
+                is_iterator_range<T>,
+                range_adapter<Mode, T>,
+                is_dereferenceable<T>,
+                output_iterator_adapter<Mode, Ch, T>,
+                is_array<T>,
+                array_adapter<Mode, T>,
+                else_,
+                #if !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600)
+                    const T&
+                #else
+                    T
+                #endif
+            >::type type;
+};
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type 
+resolve(const T& t, mpl::true_)
+{   // Bad overload resolution.
+    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
+    return return_type(wrap(const_cast<T&>(t)));
+}
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type 
+resolve(const T& t, mpl::false_)
+{ 
+    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
+    return return_type(t);
+}
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type 
+resolve(const T& t NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T))
+{ return resolve<Mode, Ch>(t, is_std_io<T>()); }
+
+# if !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
+     !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) && \
+     !defined(__GNUC__) // ---------------------------------------------------//
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type 
+resolve(T& t, mpl::true_)
+{ 
+    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
+    return return_type(wrap(t));
+}
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type 
+resolve(T& t, mpl::false_)
+{ 
+    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
+    return return_type(t);
+}
+
+template<typename Mode, typename Ch, typename T>
+typename resolve_traits<Mode, Ch, T>::type 
+resolve(T& t NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(T))
+{ return resolve<Mode, Ch>(t, is_std_io<T>()); }
+
+# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------//
+#endif // #ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // VC7.1 4224.
+
+#endif // NDNBOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/restrict_impl.hpp b/include/ndnboost/iostreams/detail/restrict_impl.hpp
new file mode 100644
index 0000000..a33047a
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/restrict_impl.hpp
@@ -0,0 +1,482 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/detail/restrict_impl.hpp
+ * Date:        Sun Jan 06 12:57:30 MST 2008
+ * Copyright:   2007-2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * If included with the macro NDNBOOST_IOSTREAMS_RESTRICT undefined, defines the 
+ * class template ndnboost::iostreams::restriction. If included with the macro
+ * NDNBOOST_IOSTREAMS_RESTRICT defined as an identifier, defines the overloaded
+ * function template ndnboost::iostreams::NDNBOOST_IOSTREAMS_RESTRICT, and object 
+ * generator for ndnboost::iostreams::restriction.
+ *
+ * This design allows <ndnboost/iostreams/restrict.hpp> and 
+ * <ndnboost/iostreams/slice.hpp> to share an implementation.
+ */
+
+#if !defined(NDNBOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) && \
+    !defined(NDNBOOST_IOSTREAMS_RESTRICT)
+# define NDNBOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED
+                    
+//------------------Implementation of restriction-----------------------------//
+
+# include <algorithm>          // min.
+# include <utility>            // pair.
+# include <ndnboost/cstdint.hpp>  // intmax_t.
+# include <ndnboost/config.hpp>   // DEDUCED_TYPENAME.
+# include <ndnboost/iostreams/categories.hpp>
+# include <ndnboost/iostreams/char_traits.hpp>
+# include <ndnboost/iostreams/detail/adapter/device_adapter.hpp>
+# include <ndnboost/iostreams/detail/adapter/filter_adapter.hpp>
+# include <ndnboost/iostreams/detail/call_traits.hpp>
+# include <ndnboost/iostreams/detail/enable_if_stream.hpp>
+# include <ndnboost/iostreams/detail/error.hpp>
+# include <ndnboost/iostreams/detail/ios.hpp>     // failure.
+# include <ndnboost/iostreams/detail/select.hpp>
+# include <ndnboost/iostreams/operations.hpp>
+# include <ndnboost/iostreams/skip.hpp>
+# include <ndnboost/iostreams/traits.hpp>         // mode_of, is_direct.
+# include <ndnboost/mpl/bool.hpp>
+# include <ndnboost/static_assert.hpp>
+# include <ndnboost/throw_exception.hpp>
+# include <ndnboost/type_traits/is_convertible.hpp>
+
+# include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+//
+// Template name: restricted_indirect_device.
+// Description: Provides an restricted view of an indirect Device.
+// Template parameters:
+//      Device - An indirect model of Device that models either Source or
+//          SeekableDevice.
+//
+template<typename Device>
+class restricted_indirect_device : public device_adapter<Device> {
+private:
+    typedef typename detail::param_type<Device>::type  param_type;
+public:
+    typedef typename char_type_of<Device>::type  char_type;
+    typedef typename mode_of<Device>::type       mode;
+    NDNBOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
+    struct category
+        : mode,
+          device_tag,
+          closable_tag,
+          flushable_tag,
+          localizable_tag,
+          optimally_buffered_tag
+        { };
+    restricted_indirect_device( param_type dev, stream_offset off,
+                                stream_offset len = -1 );
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek(stream_offset off, NDNBOOST_IOS::seekdir way);
+private:
+    stream_offset beg_, pos_, end_;
+};
+
+//
+// Template name: restricted_direct_device.
+// Description: Provides an restricted view of a Direct Device.
+// Template parameters:
+//      Device - A model of Direct and Device.
+//
+template<typename Device>
+class restricted_direct_device : public device_adapter<Device> {
+public:
+    typedef typename char_type_of<Device>::type  char_type;
+    typedef std::pair<char_type*, char_type*>    pair_type;
+    typedef typename mode_of<Device>::type       mode;
+    NDNBOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
+    struct category
+        : mode_of<Device>::type,
+          device_tag,
+          direct_tag,
+          closable_tag,
+          localizable_tag
+        { };
+    restricted_direct_device( const Device& dev, stream_offset off,
+                              stream_offset len = -1 );
+    pair_type input_sequence();
+    pair_type output_sequence();
+private:
+    pair_type sequence(mpl::true_);
+    pair_type sequence(mpl::false_);
+    char_type *beg_, *end_;
+};
+
+//
+// Template name: restricted_filter.
+// Description: Provides an restricted view of a Filter.
+// Template parameters:
+//      Filter - An indirect model of Filter.
+//
+template<typename Filter>
+class restricted_filter : public filter_adapter<Filter> {
+public:
+    typedef typename char_type_of<Filter>::type char_type;
+    typedef typename mode_of<Filter>::type      mode;
+    NDNBOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
+    struct category
+        : mode,
+          filter_tag,
+          multichar_tag,
+          closable_tag,
+          localizable_tag,
+          optimally_buffered_tag
+        { };
+    restricted_filter( const Filter& flt, stream_offset off, 
+                       stream_offset len = -1 );
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        using namespace std;
+        if (!open_)
+            open(src, NDNBOOST_IOS::in);
+        std::streamsize amt =
+            end_ != -1 ?
+                (std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
+                n;
+        std::streamsize result = 
+            iostreams::read(this->component(), src, s, amt);
+        if (result != -1)
+            pos_ += result;
+        return result;
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        if (!open_)
+            open(snk, NDNBOOST_IOS::out);
+        if (end_ != -1 && pos_ + n >= end_) {
+            if(pos_ < end_)
+                pos_ += iostreams::write(this->component(),
+                    snk, s, end_ - pos_);
+            ndnboost::throw_exception(bad_write());
+        }
+        std::streamsize result = 
+            iostreams::write(this->component(), snk, s, n);
+        pos_ += result;
+        return result;
+    }
+
+    template<typename Device>
+    std::streampos seek(Device& dev, stream_offset off, NDNBOOST_IOS::seekdir way)
+    {
+        stream_offset next;
+        if (way == NDNBOOST_IOS::beg) {
+            next = beg_ + off;
+        } else if (way == NDNBOOST_IOS::cur) {
+            next = pos_ + off;
+        } else if (end_ != -1) {
+            next = end_ + off;
+        } else {
+            // Restriction is half-open; seek relative to the actual end.
+            pos_ = this->component().seek(dev, off, NDNBOOST_IOS::end);
+            if (pos_ < beg_)
+                ndnboost::throw_exception(bad_seek());
+            return offset_to_position(pos_ - beg_);
+        }
+        if (next < beg_ || (end_ != -1 && next >= end_))
+            ndnboost::throw_exception(bad_seek());
+        pos_ = this->component().seek(dev, next, NDNBOOST_IOS::cur);
+        return offset_to_position(pos_ - beg_);
+    }
+
+    template<typename Device>
+    void close(Device& dev) 
+    { 
+        open_ = false;
+        detail::close_all(this->component(), dev); 
+    }
+
+    template<typename Device>
+    void close(Device& dev, NDNBOOST_IOS::openmode which) 
+    { 
+        open_ = false;
+        iostreams::close(this->component(), dev, which); 
+    }
+private:
+    template<typename Device>
+    void open(Device& dev, NDNBOOST_IOS::openmode which)
+    {
+        typedef typename is_convertible<mode, dual_use>::type is_dual_use;
+        open_ = true;
+        which = is_dual_use() ? which : (NDNBOOST_IOS::in | NDNBOOST_IOS::out);
+        iostreams::skip(this->component(), dev, beg_, which);
+    }
+
+    stream_offset  beg_, pos_, end_;
+    bool           open_;
+};
+
+template<typename T>
+struct restriction_traits
+    : iostreams::select<  // Disambiguation for Tru64.
+          is_filter<T>,  restricted_filter<T>,
+          is_direct<T>,  restricted_direct_device<T>,
+          else_,         restricted_indirect_device<T>
+      >
+    { };
+
+} // End namespace detail.
+
+template<typename T>
+struct restriction : public detail::restriction_traits<T>::type {
+    typedef typename detail::param_type<T>::type          param_type;
+    typedef typename detail::restriction_traits<T>::type  base_type;
+    restriction(param_type t, stream_offset off, stream_offset len = -1)
+        : base_type(t, off, len)
+        { }
+};
+
+namespace detail {
+
+//--------------Implementation of restricted_indirect_device------------------//
+
+template<typename Device>
+restricted_indirect_device<Device>::restricted_indirect_device
+    (param_type dev, stream_offset off, stream_offset len)
+    : device_adapter<Device>(dev), beg_(off), pos_(off), 
+      end_(len != -1 ? off + len : -1)
+{
+    if (len < -1 || off < 0)
+        ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("bad offset"));
+    iostreams::skip(this->component(), off);
+}
+
+template<typename Device>
+inline std::streamsize restricted_indirect_device<Device>::read
+    (char_type* s, std::streamsize n)
+{
+    using namespace std;
+    std::streamsize amt =
+        end_ != -1 ?
+            (std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
+            n;
+    std::streamsize result = iostreams::read(this->component(), s, amt);
+    if (result != -1)
+        pos_ += result;
+    return result;
+}
+
+template<typename Device>
+inline std::streamsize restricted_indirect_device<Device>::write
+    (const char_type* s, std::streamsize n)
+{
+    if (end_ != -1 && pos_ + n >= end_) {
+        if(pos_ < end_)
+            pos_ += iostreams::write(this->component(), s, end_ - pos_);
+        ndnboost::throw_exception(bad_write());
+    }
+    std::streamsize result = iostreams::write(this->component(), s, n);
+    pos_ += result;
+    return result;
+}
+
+template<typename Device>
+std::streampos restricted_indirect_device<Device>::seek
+    (stream_offset off, NDNBOOST_IOS::seekdir way)
+{
+    stream_offset next;
+    if (way == NDNBOOST_IOS::beg) {
+        next = beg_ + off;
+    } else if (way == NDNBOOST_IOS::cur) {
+        next = pos_ + off;
+    } else if (end_ != -1) {
+        next = end_ + off;
+    } else {
+        // Restriction is half-open; seek relative to the actual end.
+        pos_ = iostreams::seek(this->component(), off, NDNBOOST_IOS::end);
+        if (pos_ < beg_)
+            ndnboost::throw_exception(bad_seek());
+        return offset_to_position(pos_ - beg_);
+    }
+    if (next < beg_ || (end_ != -1 && next > end_))
+        ndnboost::throw_exception(bad_seek());
+    pos_ = iostreams::seek(this->component(), next - pos_, NDNBOOST_IOS::cur);
+    return offset_to_position(pos_ - beg_);
+}
+
+//--------------Implementation of restricted_direct_device--------------------//
+
+template<typename Device>
+restricted_direct_device<Device>::restricted_direct_device
+    (const Device& dev, stream_offset off, stream_offset len)
+    : device_adapter<Device>(dev), beg_(0), end_(0)
+{
+    std::pair<char_type*, char_type*> seq =
+        sequence(is_convertible<category, input>());
+    if ( off < 0 || len < -1 || 
+         (len != -1 && off + len > seq.second - seq.first) )
+    {
+        ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("bad offset"));
+    }
+    beg_ = seq.first + off;
+    end_ = len != -1 ? 
+        seq.first + off + len :
+        seq.second;
+}
+
+template<typename Device>
+typename restricted_direct_device<Device>::pair_type
+restricted_direct_device<Device>::input_sequence()
+{
+    NDNBOOST_STATIC_ASSERT((is_convertible<category, input>::value));
+    return std::make_pair(beg_, end_);
+}
+
+template<typename Device>
+typename restricted_direct_device<Device>::pair_type
+restricted_direct_device<Device>::output_sequence()
+{
+    NDNBOOST_STATIC_ASSERT((is_convertible<category, output>::value));
+    return std::make_pair(beg_, end_);
+}
+
+template<typename Device>
+typename restricted_direct_device<Device>::pair_type
+restricted_direct_device<Device>::sequence(mpl::true_)
+{ return iostreams::input_sequence(this->component()); }
+
+template<typename Device>
+typename restricted_direct_device<Device>::pair_type
+restricted_direct_device<Device>::sequence(mpl::false_)
+{ return iostreams::output_sequence(this->component()); }
+
+//--------------Implementation of restricted_filter---------------------------//
+
+template<typename Filter>
+restricted_filter<Filter>::restricted_filter
+    (const Filter& flt, stream_offset off, stream_offset len)
+    : filter_adapter<Filter>(flt), beg_(off),
+      pos_(off), end_(len != -1 ? off + len : -1), open_(false)
+{
+    if (len < -1 || off < 0)
+        ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("bad offset"));
+}
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#elif defined(NDNBOOST_IOSTREAMS_RESTRICT)
+
+namespace ndnboost { namespace iostreams {
+
+//--------------Implementation of restrict/slice------------------------------//
+
+// Note: The following workarounds are patterned after resolve.hpp. It has not
+// yet been confirmed that they are necessary.
+
+# ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //------------------------//
+#  ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //------------------------------//
+
+template<typename T>
+restriction<T> 
+NDNBOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
+                          NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
+{ return restriction<T>(t, off, len); }
+
+template<typename Ch, typename Tr>
+restriction< std::basic_streambuf<Ch, Tr> >
+NDNBOOST_IOSTREAMS_RESTRICT( std::basic_streambuf<Ch, Tr>& sb, stream_offset off, 
+                          stream_offset len = -1 )
+{ return restriction< std::basic_streambuf<Ch, Tr> >(sb, off, len); }
+
+template<typename Ch, typename Tr>
+restriction< std::basic_istream<Ch, Tr> >
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::basic_istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
+{ return restriction< std::basic_istream<Ch, Tr> >(is, off, len); }
+
+template<typename Ch, typename Tr>
+restriction< std::basic_ostream<Ch, Tr> >
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::basic_ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
+{ return restriction< std::basic_ostream<Ch, Tr> >(os, off, len); }
+
+template<typename Ch, typename Tr>
+restriction< std::basic_iostream<Ch, Tr> >
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::basic_iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
+{ return restriction< std::basic_iostream<Ch, Tr> >(io, off, len); }
+
+#  else // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
+
+template<typename T>
+restriction<T> 
+NDNBOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
+                          NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
+{ return restriction<T>(t, off, len); }
+
+restriction<std::streambuf> 
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::streambuf& sb, stream_offset off, stream_offset len = -1)
+{ return restriction<std::streambuf>(sb, off, len); }
+
+restriction<std::istream> 
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
+{ return restriction<std::istream>(is, off, len); }
+
+restriction<std::ostream> 
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
+{ return restriction<std::ostream>(os, off, len); }
+
+restriction<std::iostream> 
+NDNBOOST_IOSTREAMS_RESTRICT
+    (std::iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
+{ return restriction<std::iostream>(io, off, len); }
+
+#  endif // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------//
+# else // #ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
+
+template<typename T>
+restriction<T> 
+NDNBOOST_IOSTREAMS_RESTRICT
+    (const T& t, stream_offset off, stream_offset len, mpl::true_)
+{   // Bad overload resolution.
+    return restriction<T>(const_cast<T&>(t, off, len));
+}
+
+template<typename T>
+restriction<T> 
+NDNBOOST_IOSTREAMS_RESTRICT
+    (const T& t, stream_offset off, stream_offset len, mpl::false_)
+{ return restriction<T>(t, off, len); }
+
+template<typename T>
+restriction<T> 
+NDNBOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
+                          NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
+{ return NDNBOOST_IOSTREAMS_RESTRICT(t, off, len, is_std_io<T>()); }
+
+# if !NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
+     !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) && \
+     !defined(__GNUC__) // ---------------------------------------------------//
+
+template<typename T>
+restriction<T>
+NDNBOOST_IOSTREAMS_RESTRICT(T& t, stream_offset off, stream_offset len = -1)
+{ return restriction<T>(t, off, len); }
+
+#  endif // Borland 5.x, VC6-7.0 or GCC 2.9x //-------------------------------//
+# endif // #ifndef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //--------------//
+
+} } // End namespaces iostreams, boost.
+
+#endif // #if !defined(NDNBOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) ...
diff --git a/include/ndnboost/iostreams/detail/select.hpp b/include/ndnboost/iostreams/detail/select.hpp
new file mode 100644
index 0000000..c0753f6
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/select.hpp
@@ -0,0 +1,86 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the metafunction select, which mimics the effect of a chain of
+// nested mpl if_'s.
+//
+// -----------------------------------------------------------------------------
+//
+// Usage:
+//      
+// typedef typename select<
+//                      case1,  type1,
+//                      case2,  type2,
+//                      ...
+//                      true_,  typen
+//                  >::type selection;
+//
+// Here case1, case2, ... are models of MPL::IntegralConstant with value type
+// bool, and n <= 12.
+
+#ifndef NDNBOOST_IOSTREAMS_SELECT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_SELECT_HPP_INCLUDED   
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif                  
+ 
+#include <ndnboost/type_traits/is_base_and_derived.hpp>
+#include <ndnboost/mpl/eval_if.hpp>
+#include <ndnboost/mpl/identity.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/mpl/void.hpp>
+
+namespace ndnboost { namespace iostreams { 
+
+typedef mpl::true_ else_;
+
+template< typename Case1 = mpl::true_,
+          typename Type1 = mpl::void_,
+          typename Case2 = mpl::true_,
+          typename Type2 = mpl::void_,
+          typename Case3 = mpl::true_,
+          typename Type3 = mpl::void_,
+          typename Case4 = mpl::true_,
+          typename Type4 = mpl::void_,
+          typename Case5 = mpl::true_,
+          typename Type5 = mpl::void_,
+          typename Case6 = mpl::true_,
+          typename Type6 = mpl::void_,
+          typename Case7 = mpl::true_,
+          typename Type7 = mpl::void_,
+          typename Case8 = mpl::true_,
+          typename Type8 = mpl::void_,
+          typename Case9 = mpl::true_,
+          typename Type9 = mpl::void_,
+          typename Case10 = mpl::true_,
+          typename Type10 = mpl::void_,
+          typename Case11 = mpl::true_,
+          typename Type11 = mpl::void_,
+          typename Case12 = mpl::true_,
+          typename Type12 = mpl::void_ >
+struct select {
+    typedef typename
+            mpl::eval_if<
+                Case1, mpl::identity<Type1>, mpl::eval_if<
+                Case2, mpl::identity<Type2>, mpl::eval_if<
+                Case3, mpl::identity<Type3>, mpl::eval_if<
+                Case4, mpl::identity<Type4>, mpl::eval_if<
+                Case5, mpl::identity<Type5>, mpl::eval_if<
+                Case6, mpl::identity<Type6>, mpl::eval_if<
+                Case7, mpl::identity<Type7>, mpl::eval_if<
+                Case8, mpl::identity<Type8>, mpl::eval_if<
+                Case9, mpl::identity<Type9>, mpl::eval_if<
+                Case10, mpl::identity<Type10>, mpl::eval_if<
+                Case11, mpl::identity<Type11>, mpl::if_<
+                Case12, Type12, mpl::void_ > > > > > > > > > > >
+            >::type type;
+};
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_SELECT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/select_by_size.hpp b/include/ndnboost/iostreams/detail/select_by_size.hpp
new file mode 100644
index 0000000..8a02771
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/select_by_size.hpp
@@ -0,0 +1,161 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2004-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+//
+// Intended as an alternative to type_traits::yes_type and type_traits::no_type.
+// Provides an arbitrary number of types (case_<0>, case_<1>, ...) for
+// determining the results of overload resultion using 'sizeof', plus a uniform
+// means of using the result. yes_type and no_type are typedefs for case_<1>
+// and case_<0>. A single case with negative argument, case_<-1>, is also 
+// provided, for convenience.
+//
+// This header may be included any number of times, with
+// NDNBOOST_SELECT_BY_SIZE_MAX_CASE defined to be the largest N such that case_<N>
+// is needed for a particular application. It defaults to 20.
+//
+// This header depends only on Boost.Config and Boost.Preprocessor. Dependence
+// on Type Traits or MPL was intentionally avoided, to leave open the 
+// possibility that select_by_size could be used by these libraries.
+//
+// Example usage:
+//
+//    #define NDNBOOST_SELECT_BY_SIZE_MAX_CASE 7   // (Needed when default was 2)
+//    #include <ndnboost/utility/select_by_size.hpp>
+//
+//    using namespace ndnboost::utility;
+//
+//    case_<0> helper(bool);
+//    case_<1> helper(int);
+//    case_<2> helper(unsigned);
+//    case_<3> helper(long);
+//    case_<4> helper(unsigned long);
+//    case_<5> helper(float);
+//    case_<6> helper(double);
+//    case_<7> helper(const char*);
+//
+//    struct test {
+//        static const int value =
+//            select_by_size< sizeof(helper(9876UL)) >::value;
+//        NDNBOOST_STATIC_ASSERT(value == 4);
+//    };
+//
+// For compilers with integral constant expression problems, e.g. Borland 5.x,
+// one can also write
+//
+//    struct test {
+//        NDNBOOST_SELECT_BY_SIZE(int, value, helper(9876UL));
+//    };
+//
+// to define a static integral constant 'value' equal to
+//
+//    select_by_size< sizeof(helper(9876UL)) >::value.
+//
+
+// Include guards surround all contents of this header except for explicit
+// specializations of select_by_size for case_<N> with N > 2.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
+
+// The lowest N for which select_by_size< sizeof(case_<N>) > has not been
+// specialized.
+#define SELECT_BY_SIZE_MAX_SPECIALIZED 20
+
+#include <ndnboost/config.hpp>    // NDNBOOST_STATIC_CONSTANT.
+#include <ndnboost/preprocessor/cat.hpp>
+#include <ndnboost/preprocessor/iteration/local.hpp>
+
+/* Alternative implementation using max_align. 
+
+#include <ndnboost/type_traits/alignment_of.hpp>
+#include <ndnboost/type_traits/type_with_alignment.hpp>
+
+namespace ndnboost { namespace utility {
+
+template<int N>
+struct case_ { char c[(N + 1) * alignment_of<detail::max_align>::value]; };
+
+template<unsigned Size>
+struct select_by_size {
+    NDNBOOST_STATIC_CONSTANT(int, value = 
+        (Size / alignment_of<detail::max_align>::value - 1));
+};
+
+} } // End namespaces utility, boost.
+
+*/              // End alternate implementation.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+//--------------Definition of case_-------------------------------------------//
+
+template<int N> struct case_ { char c1; case_<N - 1> c2; };
+template<> struct case_<-1> { char c; };
+typedef case_<true> yes_type;
+typedef case_<false> no_type;
+
+//--------------Declaration of select_by_size---------------------------------//
+
+template<unsigned Size> struct select_by_size;
+
+} } } // End namespaces detail, iostreams, boost.
+
+//--------------Definition of SELECT_BY_SIZE_SPEC-----------------------------//
+
+// Sepecializes select_by_size for sizeof(case<n-1>). The decrement is used
+// here because the preprocessor library doesn't handle negative integers.
+#define SELECT_BY_SIZE_SPEC(n) \
+    namespace ndnboost { namespace iostreams { namespace detail { \
+      static const int NDNBOOST_PP_CAT(sizeof_case_, n) = sizeof(case_<n - 1>); \
+      template<> \
+      struct select_by_size< NDNBOOST_PP_CAT(sizeof_case_, n) > { \
+          struct type { NDNBOOST_STATIC_CONSTANT(int, value = n - 1); }; \
+          NDNBOOST_STATIC_CONSTANT(int, value = type::value); \
+      }; \
+    } } } \
+    /**/
+
+//--------------Default specializations of select_by_size---------------------//
+
+#define NDNBOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n)
+#define NDNBOOST_PP_LOCAL_LIMITS (0, 20)
+#include NDNBOOST_PP_LOCAL_ITERATE()
+#undef NDNBOOST_PP_LOCAL_MACRO
+
+//--------------Definition of SELECT_BY_SIZE----------------------------------//
+
+#define NDNBOOST_SELECT_BY_SIZE(type_, name, expr) \
+    NDNBOOST_STATIC_CONSTANT( \
+        unsigned, \
+        NDNBOOST_PP_CAT(boost_select_by_size_temp_, name) = sizeof(expr) \
+    ); \
+    NDNBOOST_STATIC_CONSTANT( \
+        type_, \
+        name = \
+            ( ::ndnboost::iostreams::detail::select_by_size< \
+                NDNBOOST_PP_CAT(boost_select_by_size_temp_, name) \
+              >::value ) \
+    ) \
+    /**/
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED
+
+//----------Specializations of SELECT_BY_SIZE (outside main inclued guards)---//
+
+#if defined(NDNBOOST_SELECT_BY_SIZE_MAX_CASE) && \
+    NDNBOOST_SELECT_BY_SIZE_MAX_CASE > SELECT_BY_SIZE_MAX_SPECIALIZED
+
+#define NDNBOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n)
+#define NDNBOOST_PP_LOCAL_LIMITS \
+    (SELECT_BY_SIZE_MAX_SPECIALIZED, NDNBOOST_SELECT_BY_SIZE_MAX_CASE) \
+    /**/
+#include NDNBOOST_PP_LOCAL_ITERATE()
+#undef NDNBOOST_PP_LOCAL_MACRO
+#undef SELECT_BY_SIZE_MAX_SPECIALIZED
+#define SELECT_BY_SIZE_MAX_SPECIALIZED NDNBOOST_SELECT_BY_SIZE_MAX_CASE
+
+#endif
diff --git a/include/ndnboost/iostreams/detail/streambuf.hpp b/include/ndnboost/iostreams/detail/streambuf.hpp
new file mode 100644
index 0000000..d499332
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/streambuf.hpp
@@ -0,0 +1,34 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+                 
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# include <streambuf>
+#else 
+# include <streambuf.h>
+#endif 
+
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+# define NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::basic_streambuf< ch, tr >
+# define NDNBOOST_IOSTREAMS_PUBSYNC pubsync
+# define NDNBOOST_IOSTREAMS_PUBSEEKOFF pubseekoff
+# define NDNBOOST_IOSTREAMS_PUBSEEKPOS pubseekpos
+#else
+# define NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::streambuf
+# define NDNBOOST_IOSTREAMS_PUBSYNC sync
+# define NDNBOOST_IOSTREAMS_PUBSEEKOFF seekoff
+# define NDNBOOST_IOSTREAMS_PUBSEEKPOS seekpos
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/streambuf/chainbuf.hpp b/include/ndnboost/iostreams/detail/streambuf/chainbuf.hpp
new file mode 100644
index 0000000..157b855
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/streambuf/chainbuf.hpp
@@ -0,0 +1,116 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif      
+
+#include <ndnboost/config.hpp>                    // NDNBOOST_MSVC, template friends.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/chain.hpp>
+#include <ndnboost/iostreams/detail/access_control.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/streambuf/linked_streambuf.hpp>
+#include <ndnboost/iostreams/detail/translate_int_type.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/noncopyable.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+//--------------Definition of chainbuf----------------------------------------//
+
+//
+// Template name: chainbuf.
+// Description: Stream buffer which operates by delegating to the first
+//      linked_streambuf in a chain.
+// Template parameters:
+//      Chain - The chain type.
+//
+template<typename Chain, typename Mode, typename Access>
+class chainbuf
+    : public NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(
+                 typename Chain::char_type,
+                 typename Chain::traits_type
+             ),
+      public access_control<typename Chain::client_type, Access>,
+      private noncopyable
+{
+private:
+    typedef access_control<chain_client<Chain>, Access>      client_type;
+public:
+    typedef typename Chain::char_type                        char_type;
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(typename Chain::traits_type)
+protected:
+    typedef linked_streambuf<char_type, traits_type>         delegate_type;
+    chainbuf() { client_type::set_chain(&chain_); }
+    int_type underflow() 
+        { sentry t(this); return translate(delegate().underflow()); }
+    int_type pbackfail(int_type c)
+        { sentry t(this); return translate(delegate().pbackfail(c)); }
+    std::streamsize xsgetn(char_type* s, std::streamsize n)
+        { sentry t(this); return delegate().xsgetn(s, n); }
+    int_type overflow(int_type c)
+        { sentry t(this); return translate(delegate().overflow(c)); }
+    std::streamsize xsputn(const char_type* s, std::streamsize n)
+        { sentry t(this); return delegate().xsputn(s, n); }
+    int sync() { sentry t(this); return delegate().sync(); }
+    pos_type seekoff( off_type off, NDNBOOST_IOS::seekdir way,
+                      NDNBOOST_IOS::openmode which =
+                          NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+        { sentry t(this); return delegate().seekoff(off, way, which); }
+    pos_type seekpos( pos_type sp,
+                      NDNBOOST_IOS::openmode which =
+                          NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+        { sentry t(this); return delegate().seekpos(sp, which); }
+protected:
+    typedef NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(
+                 typename Chain::char_type,
+                 typename Chain::traits_type
+             )                                               base_type;
+//#if !NDNBOOST_WORKAROUND(__GNUC__, == 2)                                 
+//    NDNBOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type)
+//#endif
+private:
+
+    // Translate from std int_type to chain's int_type.
+    typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)           std_traits;
+    typedef typename Chain::traits_type                      chain_traits;
+    static typename chain_traits::int_type 
+    translate(typename std_traits::int_type c)
+        { return translate_int_type<std_traits, chain_traits>(c); }
+
+    delegate_type& delegate() 
+        { return static_cast<delegate_type&>(chain_.front()); }
+    void get_pointers()
+        {
+            this->setg(delegate().eback(), delegate().gptr(), delegate().egptr());
+            this->setp(delegate().pbase(), delegate().epptr());
+            this->pbump((int) (delegate().pptr() - delegate().pbase()));
+        }
+    void set_pointers()
+        {
+            delegate().setg(this->eback(), this->gptr(), this->egptr());
+            delegate().setp(this->pbase(), this->epptr());
+            delegate().pbump((int) (this->pptr() - this->pbase()));
+        }
+    struct sentry {
+        sentry(chainbuf<Chain, Mode, Access>* buf) : buf_(buf)
+            { buf_->set_pointers(); }
+        ~sentry() { buf_->get_pointers(); }
+        chainbuf<Chain, Mode, Access>* buf_;
+    };
+    friend struct sentry;
+    Chain chain_;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/streambuf/direct_streambuf.hpp b/include/ndnboost/iostreams/detail/streambuf/direct_streambuf.hpp
new file mode 100644
index 0000000..ec79604
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/streambuf/direct_streambuf.hpp
@@ -0,0 +1,313 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/assert.hpp>
+#include <cstddef>
+#include <typeinfo>
+#include <utility>                                 // pair.
+#include <ndnboost/config.hpp>                        // NDNBOOST_DEDUCED_TYPENAME, 
+#include <ndnboost/iostreams/detail/char_traits.hpp>  // member template friends.
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/error.hpp>
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>
+#include <ndnboost/iostreams/detail/optional.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/streambuf/linked_streambuf.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/throw_exception.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
+
+namespace ndnboost { namespace iostreams { 
+    
+namespace detail {
+
+template< typename T,
+          typename Tr = 
+              NDNBOOST_IOSTREAMS_CHAR_TRAITS(
+                 NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type 
+              ) >
+class direct_streambuf 
+    : public linked_streambuf<NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type, Tr>
+{
+public:
+    typedef typename char_type_of<T>::type                char_type;
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+private:
+    typedef linked_streambuf<char_type, traits_type>      base_type;
+    typedef typename category_of<T>::type                 category;
+    typedef NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(
+                char_type, traits_type
+            )                                             streambuf_type;
+public: // stream needs access.
+    void open(const T& t, std::streamsize buffer_size, 
+              std::streamsize pback_size);
+    bool is_open() const;
+    void close();
+    bool auto_close() const { return auto_close_; }
+    void set_auto_close(bool close) { auto_close_ = close; }
+    bool strict_sync() { return true; }
+
+    // Declared in linked_streambuf.
+    T* component() { return storage_.get(); }
+protected:
+#if !NDNBOOST_WORKAROUND(__GNUC__, == 2)
+    NDNBOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type)
+#endif
+    direct_streambuf();
+
+    //--------------Virtual functions-----------------------------------------//
+
+    // Declared in linked_streambuf.
+    void close_impl(NDNBOOST_IOS::openmode m);
+    const std::type_info& component_type() const { return typeid(T); }
+    void* component_impl() { return component(); } 
+#ifdef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+    public:
+#endif
+
+    // Declared in basic_streambuf.
+    int_type underflow();
+    int_type pbackfail(int_type c);
+    int_type overflow(int_type c);
+    pos_type seekoff( off_type off, NDNBOOST_IOS::seekdir way,
+                      NDNBOOST_IOS::openmode which );
+    pos_type seekpos(pos_type sp, NDNBOOST_IOS::openmode which);
+private:
+    pos_type seek_impl( stream_offset off, NDNBOOST_IOS::seekdir way,
+                        NDNBOOST_IOS::openmode which );
+    void init_input(any_tag) { }
+    void init_input(input);
+    void init_output(any_tag) { }
+    void init_output(output);
+    void init_get_area();
+    void init_put_area();
+    bool one_head() const;
+    bool two_head() const;
+    optional<T>  storage_;
+    char_type   *ibeg_, *iend_, *obeg_, *oend_;
+    bool         auto_close_;
+};
+                    
+//------------------Implementation of direct_streambuf------------------------//
+
+template<typename T, typename Tr>
+direct_streambuf<T, Tr>::direct_streambuf() 
+    : ibeg_(0), iend_(0), obeg_(0), oend_(0), auto_close_(true) 
+{ this->set_true_eof(true); }
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::open
+    (const T& t, std::streamsize, std::streamsize)
+{
+    storage_.reset(t);
+    init_input(category());
+    init_output(category());
+    setg(0, 0, 0);
+    setp(0, 0);
+    this->set_needs_close();
+}
+
+template<typename T, typename Tr>
+bool direct_streambuf<T, Tr>::is_open() const 
+{ return ibeg_ != 0 || obeg_ != 0; }
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::close() 
+{ 
+    base_type* self = this;
+    detail::execute_all( detail::call_member_close(*self, NDNBOOST_IOS::in),
+                         detail::call_member_close(*self, NDNBOOST_IOS::out),
+                         detail::call_reset(storage_) );
+}
+
+template<typename T, typename Tr>
+typename direct_streambuf<T, Tr>::int_type 
+direct_streambuf<T, Tr>::underflow()
+{
+    if (!ibeg_) 
+        ndnboost::throw_exception(cant_read());
+    if (!gptr()) 
+        init_get_area();
+    return gptr() != iend_ ? 
+        traits_type::to_int_type(*gptr()) : 
+        traits_type::eof();
+}
+
+template<typename T, typename Tr>
+typename direct_streambuf<T, Tr>::int_type 
+direct_streambuf<T, Tr>::pbackfail(int_type c)
+{
+    using namespace std;
+    if (!ibeg_) 
+        ndnboost::throw_exception(cant_read());
+    if (gptr() != 0 && gptr() != ibeg_) {
+        gbump(-1);
+        if (!traits_type::eq_int_type(c, traits_type::eof()))
+            *gptr() = traits_type::to_char_type(c);
+        return traits_type::not_eof(c);
+    }
+    ndnboost::throw_exception(bad_putback());
+}
+
+template<typename T, typename Tr>
+typename direct_streambuf<T, Tr>::int_type 
+direct_streambuf<T, Tr>::overflow(int_type c)
+{
+    using namespace std;
+    if (!obeg_)
+        ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("no write access"));
+    if (!pptr()) init_put_area();
+    if (!traits_type::eq_int_type(c, traits_type::eof())) {
+        if (pptr() == oend_)
+            ndnboost::throw_exception(
+                NDNBOOST_IOSTREAMS_FAILURE("write area exhausted")
+            );
+        *pptr() = traits_type::to_char_type(c);
+        pbump(1);
+        return c;
+    }
+    return traits_type::not_eof(c);
+}
+
+template<typename T, typename Tr>
+inline typename direct_streambuf<T, Tr>::pos_type
+direct_streambuf<T, Tr>::seekoff
+    (off_type off, NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which)
+{ return seek_impl(off, way, which); }
+
+template<typename T, typename Tr>
+inline typename direct_streambuf<T, Tr>::pos_type
+direct_streambuf<T, Tr>::seekpos
+    (pos_type sp, NDNBOOST_IOS::openmode which)
+{ 
+    return seek_impl(position_to_offset(sp), NDNBOOST_IOS::beg, which);
+}
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::close_impl(NDNBOOST_IOS::openmode which)
+{
+    if (which == NDNBOOST_IOS::in && ibeg_ != 0) {
+        setg(0, 0, 0);
+        ibeg_ = iend_ = 0;
+    }
+    if (which == NDNBOOST_IOS::out && obeg_ != 0) {
+        sync();
+        setp(0, 0);
+        obeg_ = oend_ = 0;
+    }
+    ndnboost::iostreams::close(*storage_, which);
+}
+
+template<typename T, typename Tr>
+typename direct_streambuf<T, Tr>::pos_type direct_streambuf<T, Tr>::seek_impl
+    (stream_offset off, NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which)
+{
+    using namespace std;
+    NDNBOOST_IOS::openmode both = NDNBOOST_IOS::in | NDNBOOST_IOS::out;
+    if (two_head() && (which & both) == both)
+        ndnboost::throw_exception(bad_seek());
+    stream_offset result = -1;
+    bool one = one_head();
+    if (one && (pptr() != 0 || gptr()== 0))
+        init_get_area(); // Switch to input mode, for code reuse.
+    if (one || ((which & NDNBOOST_IOS::in) != 0 && ibeg_ != 0)) {
+        if (!gptr()) setg(ibeg_, ibeg_, iend_);
+        ptrdiff_t next = 0;
+        switch (way) {
+        case NDNBOOST_IOS::beg: next = off; break;
+        case NDNBOOST_IOS::cur: next = (gptr() - ibeg_) + off; break;
+        case NDNBOOST_IOS::end: next = (iend_ - ibeg_) + off; break;
+        default: NDNBOOST_ASSERT(0);
+        }
+        if (next < 0 || next > (iend_ - ibeg_))
+            ndnboost::throw_exception(bad_seek());
+        setg(ibeg_, ibeg_ + next, iend_);
+        result = next;
+    }
+    if (!one && (which & NDNBOOST_IOS::out) != 0 && obeg_ != 0) {
+        if (!pptr()) setp(obeg_, oend_);
+        ptrdiff_t next = 0;
+        switch (way) {
+        case NDNBOOST_IOS::beg: next = off; break;
+        case NDNBOOST_IOS::cur: next = (pptr() - obeg_) + off; break;
+        case NDNBOOST_IOS::end: next = (oend_ - obeg_) + off; break;
+        default: NDNBOOST_ASSERT(0);
+        }
+        if (next < 0 || next > (oend_ - obeg_))
+            ndnboost::throw_exception(bad_seek());
+        pbump(static_cast<int>(next - (pptr() - obeg_)));
+        result = next;
+    }
+    return offset_to_position(result);
+}
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::init_input(input)
+{
+    std::pair<char_type*, char_type*> p = input_sequence(*storage_);
+    ibeg_ = p.first;
+    iend_ = p.second;
+}
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::init_output(output)
+{
+    std::pair<char_type*, char_type*> p = output_sequence(*storage_);
+    obeg_ = p.first;
+    oend_ = p.second;
+}
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::init_get_area()
+{
+    setg(ibeg_, ibeg_, iend_);
+    if (one_head() && pptr()) {
+        gbump(static_cast<int>(pptr() - obeg_));
+        setp(0, 0);
+    }
+}
+
+template<typename T, typename Tr>
+void direct_streambuf<T, Tr>::init_put_area()
+{
+    setp(obeg_, oend_);
+    if (one_head() && gptr()) {
+        pbump(static_cast<int>(gptr() - ibeg_));
+        setg(0, 0, 0);
+    }
+}
+
+template<typename T, typename Tr>
+inline bool direct_streambuf<T, Tr>::one_head() const
+{ return ibeg_ && obeg_ && ibeg_ == obeg_; }
+
+template<typename T, typename Tr>
+inline bool direct_streambuf<T, Tr>::two_head() const
+{ return ibeg_ && obeg_ && ibeg_ != obeg_; }
+
+//----------------------------------------------------------------------------//
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/streambuf/indirect_streambuf.hpp b/include/ndnboost/iostreams/detail/streambuf/indirect_streambuf.hpp
new file mode 100644
index 0000000..d657ddb
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/streambuf/indirect_streambuf.hpp
@@ -0,0 +1,432 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// This material is heavily indebted to the discussion and code samples in
+// A. Langer and K. Kreft, "Standard C++ IOStreams and Locales",
+// Addison-Wesley, 2000, pp. 228-43.
+
+// User "GMSB" provided an optimization for small seeks.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED
+
+#include <algorithm>                             // min, max.
+#include <cassert>
+#include <exception>
+#include <typeinfo>
+#include <ndnboost/config.hpp>                      // Member template friends.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/constants.hpp>
+#include <ndnboost/iostreams/detail/adapter/concept_adapter.hpp>
+#include <ndnboost/iostreams/detail/buffer.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/double_object.hpp> 
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>
+#include <ndnboost/iostreams/detail/optional.hpp>
+#include <ndnboost/iostreams/detail/push.hpp>
+#include <ndnboost/iostreams/detail/streambuf/linked_streambuf.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC, BCC 5.x
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+//
+// Description: The implementation of basic_streambuf used by chains.
+//
+template<typename T, typename Tr, typename Alloc, typename Mode>
+class indirect_streambuf
+    : public linked_streambuf<NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type, Tr>
+{
+public:
+    typedef typename char_type_of<T>::type                    char_type;
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+private:
+    typedef typename category_of<T>::type                     category;
+    typedef concept_adapter<T>                                wrapper;
+    typedef detail::basic_buffer<char_type, Alloc>            buffer_type;
+    typedef indirect_streambuf<T, Tr, Alloc, Mode>            my_type;
+    typedef detail::linked_streambuf<char_type, traits_type>  base_type;
+    typedef linked_streambuf<char_type, Tr>                   streambuf_type;
+public:
+    indirect_streambuf();
+
+    void open(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS());
+    bool is_open() const;
+    void close();
+    bool auto_close() const;
+    void set_auto_close(bool close);
+    bool strict_sync();
+
+    // Declared in linked_streambuf.
+    T* component() { return &*obj(); }
+protected:
+#if !NDNBOOST_WORKAROUND(__GNUC__, == 2)
+    NDNBOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type)
+#endif
+
+    //----------virtual functions---------------------------------------------//
+
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+    void imbue(const std::locale& loc);
+#endif
+#ifdef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+    public:
+#endif
+    int_type underflow();
+    int_type pbackfail(int_type c);
+    int_type overflow(int_type c);
+    int sync();
+    pos_type seekoff( off_type off, NDNBOOST_IOS::seekdir way,
+                      NDNBOOST_IOS::openmode which );
+    pos_type seekpos(pos_type sp, NDNBOOST_IOS::openmode which);
+
+    // Declared in linked_streambuf.
+    void set_next(streambuf_type* next);
+    void close_impl(NDNBOOST_IOS::openmode m);
+    const std::type_info& component_type() const { return typeid(T); }
+    void* component_impl() { return component(); }
+private:
+
+    //----------Accessor functions--------------------------------------------//
+
+    wrapper& obj() { return *storage_; }
+    streambuf_type* next() const { return next_; }
+    buffer_type& in() { return buffer_.first(); }
+    buffer_type& out() { return buffer_.second(); }
+    bool can_read() const { return is_convertible<Mode, input>::value; }
+    bool can_write() const { return is_convertible<Mode, output>::value; }
+    bool output_buffered() const { return (flags_ & f_output_buffered) != 0; }
+    bool shared_buffer() const { return is_convertible<Mode, seekable>::value; }
+    void set_flags(int f) { flags_ = f; }
+
+    //----------State changing functions--------------------------------------//
+
+    virtual void init_get_area();
+    virtual void init_put_area();
+
+    //----------Utility function----------------------------------------------//
+
+    pos_type seek_impl( stream_offset off, NDNBOOST_IOS::seekdir way,
+                        NDNBOOST_IOS::openmode which );
+    void sync_impl();
+
+    enum flag_type {
+        f_open             = 1,
+        f_output_buffered  = f_open << 1,
+        f_auto_close       = f_output_buffered << 1
+    };
+
+    optional<wrapper>           storage_;
+    streambuf_type*             next_;
+    double_object<
+        buffer_type,
+        is_convertible<
+            Mode,
+            two_sequence
+        >
+    >                           buffer_;
+    std::streamsize             pback_size_;
+    int                         flags_;
+};
+
+//--------------Implementation of indirect_streambuf--------------------------//
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+indirect_streambuf<T, Tr, Alloc, Mode>::indirect_streambuf()
+    : next_(0), pback_size_(0), flags_(f_auto_close) { }
+
+//--------------Implementation of open, is_open and close---------------------//
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::open
+    (const T& t, std::streamsize buffer_size, std::streamsize pback_size)
+{
+    using namespace std;
+
+    // Normalize buffer sizes.
+    buffer_size =
+        (buffer_size != -1) ?
+        buffer_size :
+        iostreams::optimal_buffer_size(t);
+    pback_size =
+        (pback_size != -1) ?
+        pback_size :
+        default_pback_buffer_size;
+
+    // Construct input buffer.
+    if (can_read()) {
+        pback_size_ = (std::max)(std::streamsize(2), pback_size); // STLPort needs 2.
+        std::streamsize size =
+            pback_size_ +
+            ( buffer_size ? buffer_size: 1 );
+        in().resize(size);
+        if (!shared_buffer())
+            init_get_area();
+    }
+
+    // Construct output buffer.
+    if (can_write() && !shared_buffer()) {
+        if (buffer_size != 0)
+            out().resize(buffer_size);
+        init_put_area();
+    }
+
+    storage_.reset(wrapper(t));
+    flags_ |= f_open;
+    if (can_write() && buffer_size > 1)
+        flags_ |= f_output_buffered;
+    this->set_true_eof(false);
+    this->set_needs_close();
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+inline bool indirect_streambuf<T, Tr, Alloc, Mode>::is_open() const
+{ return (flags_ & f_open) != 0; }
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::close()
+{
+    using namespace std;
+    base_type* self = this;
+    detail::execute_all(
+        detail::call_member_close(*self, NDNBOOST_IOS::in),
+        detail::call_member_close(*self, NDNBOOST_IOS::out),
+        detail::call_reset(storage_),
+        detail::clear_flags(flags_)
+    );
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+bool indirect_streambuf<T, Tr, Alloc, Mode>::auto_close() const
+{ return (flags_ & f_auto_close) != 0; }
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::set_auto_close(bool close)
+{ flags_ = (flags_ & ~f_auto_close) | (close ? f_auto_close : 0); }
+
+//--------------Implementation virtual functions------------------------------//
+
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::imbue(const std::locale& loc)
+{
+    if (is_open()) {
+        obj().imbue(loc);
+        if (next_)
+            next_->pubimbue(loc);
+    }
+}
+#endif
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+typename indirect_streambuf<T, Tr, Alloc, Mode>::int_type
+indirect_streambuf<T, Tr, Alloc, Mode>::underflow()
+{
+    using namespace std;
+    if (!gptr()) init_get_area();
+    buffer_type& buf = in();
+    if (gptr() < egptr()) return traits_type::to_int_type(*gptr());
+
+    // Fill putback buffer.
+    std::streamsize keep = 
+        (std::min)( static_cast<std::streamsize>(gptr() - eback()),
+                    pback_size_ );
+    if (keep)
+        traits_type::move( buf.data() + (pback_size_ - keep),
+                           gptr() - keep, keep );
+
+    // Set pointers to reasonable values in case read throws.
+    setg( buf.data() + pback_size_ - keep,
+          buf.data() + pback_size_,
+          buf.data() + pback_size_ );
+
+    // Read from source.
+    std::streamsize chars =
+        obj().read(buf.data() + pback_size_, buf.size() - pback_size_, next_);
+    if (chars == -1) {
+        this->set_true_eof(true);
+        chars = 0;
+    }
+    setg(eback(), gptr(), buf.data() + pback_size_ + chars);
+    return chars != 0 ?
+        traits_type::to_int_type(*gptr()) :
+        traits_type::eof();
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+typename indirect_streambuf<T, Tr, Alloc, Mode>::int_type
+indirect_streambuf<T, Tr, Alloc, Mode>::pbackfail(int_type c)
+{
+    if (gptr() != eback()) {
+        gbump(-1);
+        if (!traits_type::eq_int_type(c, traits_type::eof()))
+            *gptr() = traits_type::to_char_type(c);
+        return traits_type::not_eof(c);
+    } else {
+        ndnboost::throw_exception(bad_putback());
+    }
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+typename indirect_streambuf<T, Tr, Alloc, Mode>::int_type
+indirect_streambuf<T, Tr, Alloc, Mode>::overflow(int_type c)
+{
+    if ( (output_buffered() && pptr() == 0) ||
+         (shared_buffer() && gptr() != 0) )
+    {
+        init_put_area();
+    }
+    if (!traits_type::eq_int_type(c, traits_type::eof())) {
+        if (output_buffered()) {
+            if (pptr() == epptr()) {
+                sync_impl();
+                if (pptr() == epptr())
+                    return traits_type::eof();
+            }
+            *pptr() = traits_type::to_char_type(c);
+            pbump(1);
+        } else {
+            char_type d = traits_type::to_char_type(c);
+            if (obj().write(&d, 1, next_) != 1)
+                return traits_type::eof();
+        }
+    }
+    return traits_type::not_eof(c);
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+int indirect_streambuf<T, Tr, Alloc, Mode>::sync()
+{
+    try { // sync() is no-throw.
+        sync_impl();
+        obj().flush(next_);
+        return 0;
+    } catch (...) { return -1; }
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+bool indirect_streambuf<T, Tr, Alloc, Mode>::strict_sync()
+{
+    try { // sync() is no-throw.
+        sync_impl();
+        return obj().flush(next_);
+    } catch (...) { return false; }
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+inline typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
+indirect_streambuf<T, Tr, Alloc, Mode>::seekoff
+    (off_type off, NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which)
+{ return seek_impl(off, way, which); }
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+inline typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
+indirect_streambuf<T, Tr, Alloc, Mode>::seekpos
+    (pos_type sp, NDNBOOST_IOS::openmode which)
+{ 
+    return seek_impl(position_to_offset(sp), NDNBOOST_IOS::beg, which); 
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
+indirect_streambuf<T, Tr, Alloc, Mode>::seek_impl
+    (stream_offset off, NDNBOOST_IOS::seekdir way, NDNBOOST_IOS::openmode which)
+{
+    if ( gptr() != 0 && way == NDNBOOST_IOS::cur && which == NDNBOOST_IOS::in && 
+         eback() - gptr() <= off && off <= egptr() - gptr() ) 
+    {   // Small seek optimization
+        gbump(off);
+        return obj().seek(0, NDNBOOST_IOS::cur, NDNBOOST_IOS::in, next_) -
+               static_cast<off_type>(egptr() - gptr());
+    }
+    if (pptr() != 0) 
+        this->NDNBOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6.
+    if (way == NDNBOOST_IOS::cur && gptr())
+        off -= static_cast<off_type>(egptr() - gptr());
+    setg(0, 0, 0);
+    setp(0, 0);
+    return obj().seek(off, way, which, next_);
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+inline void indirect_streambuf<T, Tr, Alloc, Mode>::set_next
+    (streambuf_type* next)
+{ next_ = next; }
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+inline void indirect_streambuf<T, Tr, Alloc, Mode>::close_impl
+    (NDNBOOST_IOS::openmode which)
+{
+    if (which == NDNBOOST_IOS::in && is_convertible<Mode, input>::value) {
+        setg(0, 0, 0);
+    }
+    if (which == NDNBOOST_IOS::out && is_convertible<Mode, output>::value) {
+        sync();
+        setp(0, 0);
+    }
+    if ( !is_convertible<category, dual_use>::value ||
+         is_convertible<Mode, input>::value == (which == NDNBOOST_IOS::in) )
+    {
+        obj().close(which, next_);
+    }
+}
+
+//----------State changing functions------------------------------------------//
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::sync_impl()
+{
+    std::streamsize avail, amt;
+    if ((avail = static_cast<std::streamsize>(pptr() - pbase())) > 0) {
+        if ((amt = obj().write(pbase(), avail, next())) == avail)
+            setp(out().begin(), out().end());
+        else {
+            const char_type* ptr = pptr();
+            setp(out().begin() + amt, out().end());
+            pbump(ptr - pptr());
+        }
+    }
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::init_get_area()
+{
+    if (shared_buffer() && pptr() != 0) {
+        sync_impl();
+        setp(0, 0);
+    }
+    setg(in().begin(), in().begin(), in().begin());
+}
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+void indirect_streambuf<T, Tr, Alloc, Mode>::init_put_area()
+{
+    using namespace std;
+    if (shared_buffer() && gptr() != 0)
+        setg(0, 0, 0);
+    if (output_buffered())
+        setp(out().begin(), out().end());
+    else
+        setp(0, 0);
+}
+
+//----------------------------------------------------------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC, BCC 5.x
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/streambuf/linked_streambuf.hpp b/include/ndnboost/iostreams/detail/streambuf/linked_streambuf.hpp
new file mode 100644
index 0000000..d6ec23d
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/streambuf/linked_streambuf.hpp
@@ -0,0 +1,114 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <typeinfo>
+#include <ndnboost/config.hpp>                        // member template friends.
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>          // openmode.
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
+class chain_base;
+
+template<typename Chain, typename Access, typename Mode> class chainbuf;
+
+#define NDNBOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base) \
+    using base::eback; using base::gptr; using base::egptr; \
+    using base::setg; using base::gbump; using base::pbase; \
+    using base::pptr; using base::epptr; using base::setp; \
+    using base::pbump; using base::underflow; using base::pbackfail; \
+    using base::xsgetn; using base::overflow; using base::xsputn; \
+    using base::sync; using base::seekoff; using base::seekpos; \
+    /**/
+
+template<typename Ch, typename Tr = NDNBOOST_IOSTREAMS_CHAR_TRAITS(Ch) >
+class linked_streambuf : public NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, Tr) {
+protected:
+    linked_streambuf() : flags_(0) { }
+    void set_true_eof(bool eof) 
+    { 
+        flags_ = (flags_ & ~f_true_eof) | (eof ? f_true_eof : 0); 
+    }
+public:
+
+    // Should be called only after receiving an ordinary EOF indication,
+    // to confirm that it represents EOF rather than WOULD_BLOCK.
+    bool true_eof() const { return (flags_ & f_true_eof) != 0; }
+protected:
+
+    //----------grant friendship to chain_base and chainbuf-------------------//
+
+#ifndef NDNBOOST_NO_MEMBER_TEMPLATE_FRIENDS
+    template< typename Self, typename ChT, typename TrT,
+              typename Alloc, typename Mode >
+    friend class chain_base;
+    template<typename Chain, typename Mode, typename Access>
+    friend class chainbuf;
+    template<typename U>
+    friend class member_close_operation; 
+#else
+    public:
+        typedef NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, Tr) base;
+        NDNBOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base)
+#endif
+    void close(NDNBOOST_IOS::openmode which)
+    {
+        if ( which == NDNBOOST_IOS::in && 
+            (flags_ & f_input_closed) == 0 )
+        {
+            flags_ |= f_input_closed;
+            close_impl(which);
+        }
+        if ( which == NDNBOOST_IOS::out && 
+            (flags_ & f_output_closed) == 0 )
+        {
+            flags_ |= f_output_closed;
+            close_impl(which);
+        }
+    }
+    void set_needs_close()
+    {
+        flags_ &= ~(f_input_closed | f_output_closed);
+    }
+    virtual void set_next(linked_streambuf<Ch, Tr>* /* next */) { }
+    virtual void close_impl(NDNBOOST_IOS::openmode) = 0;
+    virtual bool auto_close() const = 0;
+    virtual void set_auto_close(bool) = 0;
+    virtual bool strict_sync() = 0;
+    virtual const std::type_info& component_type() const = 0;
+    virtual void* component_impl() = 0;
+#ifndef NDNBOOST_NO_MEMBER_TEMPLATE_FRIENDS
+    private:
+#else
+    public:
+#endif
+private:
+    enum flag_type {
+        f_true_eof       = 1,
+        f_input_closed   = f_true_eof << 1,
+        f_output_closed  = f_input_closed << 1
+    };
+    int flags_;
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/system_failure.hpp b/include/ndnboost/iostreams/detail/system_failure.hpp
new file mode 100644
index 0000000..4a9dcbc
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/system_failure.hpp
@@ -0,0 +1,84 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// (C) Copyright Jonathan Graehl 2004.
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Used by mapped_file.cpp.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <cstring>
+#include <string>
+#include <ndnboost/config.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/iostreams/detail/config/windows_posix.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // failure.
+
+#if defined(NDNBOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__)
+namespace std { using ::strlen; }
+#endif
+
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+# define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers
+# include <windows.h>
+#else
+# include <errno.h>
+# include <string.h>
+#endif
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+inline NDNBOOST_IOSTREAMS_FAILURE system_failure(const char* msg)
+{
+    std::string result;
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    DWORD err;
+    LPVOID lpMsgBuf;
+    if ( (err = ::GetLastError()) != NO_ERROR &&
+         ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                           FORMAT_MESSAGE_FROM_SYSTEM,
+                           NULL,
+                           err,
+                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                           (LPSTR) &lpMsgBuf,
+                           0,
+                           NULL ) != 0 )
+    {
+        result.reserve(std::strlen(msg) + 2 + std::strlen((LPSTR)lpMsgBuf));
+        result.append(msg);
+        result.append(": ");
+        result.append((LPSTR) lpMsgBuf);
+        ::LocalFree(lpMsgBuf);
+    } else {
+        result += msg;
+    }
+#else
+    const char* system_msg = errno ? strerror(errno) : "";
+    result.reserve(std::strlen(msg) + 2 + std::strlen(system_msg));
+    result.append(msg);
+    result.append(": ");
+    result.append(system_msg);
+#endif
+    return NDNBOOST_IOSTREAMS_FAILURE(result);
+}
+
+inline NDNBOOST_IOSTREAMS_FAILURE system_failure(const std::string& msg)
+{ return system_failure(msg.c_str()); }
+
+inline void throw_system_failure(const char* msg)
+{ ndnboost::throw_exception(system_failure(msg)); }
+
+inline void throw_system_failure(const std::string& msg)
+{ ndnboost::throw_exception(system_failure(msg)); }
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/template_params.hpp b/include/ndnboost/iostreams/detail/template_params.hpp
new file mode 100644
index 0000000..aeaaff3
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/template_params.hpp
@@ -0,0 +1,26 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_TEMPLATE_PARAMS_HPP_INCLUDED
+
+#include <ndnboost/preprocessor/control/expr_if.hpp>
+#include <ndnboost/preprocessor/control/if.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+
+#define NDNBOOST_IOSTREAMS_TEMPLATE_PARAMS(arity, param) \
+    NDNBOOST_PP_EXPR_IF(arity, template<) \
+    NDNBOOST_PP_ENUM_PARAMS(arity, typename param) \
+    NDNBOOST_PP_EXPR_IF(arity, >) \
+    /**/
+
+#define NDNBOOST_IOSTREAMS_TEMPLATE_ARGS(arity, param) \
+    NDNBOOST_PP_EXPR_IF(arity, <) \
+    NDNBOOST_PP_ENUM_PARAMS(arity, param) \
+    NDNBOOST_PP_EXPR_IF(arity, >) \
+    /**/
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/translate_int_type.hpp b/include/ndnboost/iostreams/detail/translate_int_type.hpp
new file mode 100644
index 0000000..e5cbb63
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/translate_int_type.hpp
@@ -0,0 +1,62 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<bool IsSame>
+struct translate_int_type_impl;
+
+//
+// Template name: translate_char.
+// Description: Translates a character or an end-of-file indicator from the 
+//      int_type of one character traits type to the int_type of another.
+//
+template<typename SourceTr, typename TargetTr>
+typename TargetTr::int_type 
+translate_int_type(typename SourceTr::int_type c) 
+{ 
+    typedef translate_int_type_impl<is_same<SourceTr, TargetTr>::value> impl;
+    return impl::template inner<SourceTr, TargetTr>::translate(c);
+}
+
+//----------------------------------------------------------------------------//
+
+template<>
+struct translate_int_type_impl<true> {
+    template<typename SourceTr, typename TargetTr>
+    struct inner {
+        static typename TargetTr::int_type 
+        translate(typename SourceTr::int_type c) { return c; }
+    };
+};
+
+template<>
+struct translate_int_type_impl<false> {
+    template<typename SourceTr, typename TargetTr>
+    struct inner {
+        static typename TargetTr::int_type 
+        translate(typename SourceTr::int_type c)
+            { 
+                return SourceTr::eq_int_type(SourceTr::eof()) ?
+                           TargetTr::eof() :
+                           TargetTr::to_int_type(SourceTr::to_char_type(c));
+            }
+    };
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/detail/vc6/close.hpp b/include/ndnboost/iostreams/detail/vc6/close.hpp
new file mode 100644
index 0000000..2fddd11
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/vc6/close.hpp
@@ -0,0 +1,129 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct close_impl;
+
+} // End namespace detail.
+
+template<typename T>
+void close(T& t) { detail::close_all(t); }
+
+template<typename T>
+void close(T& t, NDNBOOST_IOS::openmode which)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), which);
+}
+
+template<typename T, typename Sink>
+void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), snk, which);
+}
+
+namespace detail {
+
+//------------------Definition of close_impl----------------------------------//
+
+template<typename T>
+struct close_tag {
+    typedef typename category_of<T>::type category;
+    typedef typename
+            mpl::eval_if<
+                is_convertible<category, closable_tag>,
+                mpl::if_<
+                    mpl::or_<
+                        is_convertible<category, two_sequence>,
+                        is_convertible<category, dual_use>
+                    >,
+                    two_sequence,
+                    closable_tag
+                >,
+                mpl::identity<any_tag>
+            >::type type;
+};
+
+template<typename T>
+struct close_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          close_impl<NDNBOOST_DEDUCED_TYPENAME close_tag<T>::type>
+      >::type
+    { };
+
+template<>
+struct close_impl<any_tag> {
+    template<typename T>
+    struct inner {
+        static void close(T& t, NDNBOOST_IOS::openmode which)
+        {
+            if (which == NDNBOOST_IOS::out)
+                iostreams::flush(t);
+        }
+
+        template<typename Sink>
+        static void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+        {
+            if (which == NDNBOOST_IOS::out) {
+                non_blocking_adapter<Sink> nb(snk);
+                iostreams::flush(t, nb);
+            }
+        }
+    };
+};
+
+template<>
+struct close_impl<closable_tag> {
+    template<typename T>
+    struct inner {
+        static void close(T& t, NDNBOOST_IOS::openmode which)
+        {
+            typedef typename category_of<T>::type category;
+            const bool in =  is_convertible<category, input>::value &&
+                            !is_convertible<category, output>::value;
+            if (in == (which == NDNBOOST_IOS::in))
+                t.close();
+        }
+        template<typename Sink>
+        static void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+        {
+            typedef typename category_of<T>::type category;
+            const bool in =  is_convertible<category, input>::value &&
+                            !is_convertible<category, output>::value;
+            if (in == (which == NDNBOOST_IOS::in)) {
+                non_blocking_adapter<Sink> nb(snk);
+                t.close(nb);
+            }
+        }
+    };
+};
+
+template<>
+struct close_impl<two_sequence> {
+    template<typename T>
+    struct inner {
+        static void close(T& t, NDNBOOST_IOS::openmode which) { t.close(which); }
+
+        template<typename Sink>
+        static void close(T& t, Sink& snk, NDNBOOST_IOS::openmode which)
+        {
+            non_blocking_adapter<Sink> nb(snk);
+            t.close(nb, which);
+        }
+    };
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
diff --git a/include/ndnboost/iostreams/detail/vc6/read.hpp b/include/ndnboost/iostreams/detail/vc6/read.hpp
new file mode 100644
index 0000000..b664ae6
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/vc6/read.hpp
@@ -0,0 +1,238 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T> 
+struct read_device_impl;
+
+template<typename T> 
+struct read_filter_impl;
+
+} // End namespace detail.
+
+template<typename T>
+typename int_type_of<T>::type get(T& t)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::read_device_impl<T>::inner<unwrapped>::get(detail::unwrap(t));
+}
+
+template<typename T>
+inline std::streamsize
+read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::read_device_impl<T>::inner<unwrapped>::read(detail::unwrap(t), s, n);
+}
+
+template<typename T, typename Source>
+std::streamsize
+read(T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::read_filter_impl<T>::inner<unwrapped>::read(detail::unwrap(t), src, s, n);
+}
+
+template<typename T>
+bool putback(T& t, typename char_type_of<T>::type c)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::read_device_impl<T>::inner<unwrapped>::putback(detail::unwrap(t), c);
+}
+
+//----------------------------------------------------------------------------//
+
+namespace detail {
+
+// Helper function for adding -1 as EOF indicator.
+inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; }
+
+// Helper templates for reading from streambufs.
+template<bool IsLinked>
+struct true_eof_impl;
+
+template<>
+struct true_eof_impl<true> {
+    template<typename T>
+    static bool true_eof(T& t) { return t.true_eof(); }
+};
+
+template<>
+struct true_eof_impl<false> {
+    template<typename T>
+    static bool true_eof(T& t) { return true; }
+};
+
+template<typename T>
+inline bool true_eof(T& t)
+{
+    const bool linked = is_linked<T>::value;
+    return true_eof_impl<linked>::true_eof(t);
+}
+                    
+//------------------Definition of read_device_impl----------------------------//
+
+template<typename T>
+struct read_device_impl
+    : mpl::if_<
+          detail::is_custom<T>,
+          operations<T>,
+          read_device_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              detail::dispatch<
+                  T, istream_tag, streambuf_tag, input
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct read_device_impl<istream_tag> {
+    template<typename T>
+    struct inner {
+        static typename int_type_of<T>::type get(T& t)
+        { return t.get(); }
+
+        static std::streamsize
+        read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+        { return check_eof(t.rdbuf()->sgetn(s, n)); }
+
+        static bool putback(T& t, typename char_type_of<T>::type c)
+        {
+            typedef typename char_type_of<T>::type          char_type;
+            typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
+            return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c),
+                                              traits_type::eof() );
+        }
+    };
+};
+
+template<>
+struct read_device_impl<streambuf_tag> {
+    template<typename T>
+    struct inner {
+        static typename int_type_of<T>::type
+        get(T& t)
+        {
+            typedef typename char_type_of<T>::type  char_type;
+            typedef char_traits<char_type>          traits_type;
+            typename int_type_of<T>::type c;
+            return !traits_type::is_eof(c = t.sbumpc()) ||
+                    detail::true_eof(t)
+                        ?
+                    c : traits_type::would_block();
+        }
+
+        static std::streamsize
+        read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+        {
+            std::streamsize amt;
+            return (amt = t.sgetn(s, n)) != 0 ?
+                amt :
+                detail::true_eof(t) ?
+                    -1 :
+                    0;
+        }
+
+        static bool putback(T& t, typename char_type_of<T>::type c)
+        {
+            typedef typename char_type_of<T>::type  char_type;
+            typedef char_traits<char_type>          traits_type;
+            return !traits_type::is_eof(t.sputbackc(c));
+        }
+    };
+};
+
+template<>
+struct read_device_impl<input> {
+    template<typename T>
+    struct inner {
+        static typename int_type_of<T>::type
+        get(T& t)
+        {
+            typedef typename char_type_of<T>::type  char_type;
+            typedef char_traits<char_type>          traits_type;
+            char_type c;
+            std::streamsize amt;
+            return (amt = t.read(&c, 1)) == 1 ?
+                traits_type::to_int_type(c) :
+                amt == -1 ?
+                    traits_type::eof() :
+                    traits_type::would_block();
+        }
+
+        template<typename T>
+        static std::streamsize
+        read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+        { return t.read(s, n); }
+
+        template<typename T>
+        static bool putback(T& t, typename char_type_of<T>::type c)
+        {   // T must be Peekable.
+            return t.putback(c);
+        }
+    };
+};
+
+//------------------Definition of read_filter_impl----------------------------//
+
+template<typename T>
+struct read_filter_impl
+    : mpl::if_<
+          detail::is_custom<T>,
+          operations<T>,
+          read_filter_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              detail::dispatch<
+                  T, multichar_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct read_filter_impl<multichar_tag> {
+    template<typename T>
+    struct inner {
+        template<typename Source>
+        static std::streamsize read
+            ( T& t, Source& src, typename char_type_of<T>::type* s,   
+              std::streamsize n )
+        { return t.read(src, s, n); }
+    };
+};
+
+template<>
+struct read_filter_impl<any_tag> {
+    template<typename T>
+    struct inner {
+        template<typename Source>
+        static std::streamsize read
+            ( T& t, Source& src, typename char_type_of<T>::type* s, 
+              std::streamsize n )
+        {
+            typedef typename char_type_of<T>::type  char_type;
+            typedef char_traits<char_type>          traits_type;
+            for (std::streamsize off = 0; off < n; ++off) {
+                typename traits_type::int_type c = t.get(src);
+                if (traits_type::is_eof(c))
+                    return check_eof(off);
+                if (traits_type::would_block(c))
+                    return off;
+                s[off] = traits_type::to_char_type(c);
+            }
+            return n;
+        }
+    };
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
diff --git a/include/ndnboost/iostreams/detail/vc6/write.hpp b/include/ndnboost/iostreams/detail/vc6/write.hpp
new file mode 100644
index 0000000..b0398e1
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/vc6/write.hpp
@@ -0,0 +1,159 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T> 
+struct write_device_impl;
+
+template<typename T> 
+struct write_filter_impl;
+
+} // End namespace detail.
+
+template<typename T>
+bool put(T& t, typename char_type_of<T>::type c)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::write_device_impl<T>::inner<unwrapped>::put(detail::unwrap(t), c);
+}
+
+template<typename T>
+inline std::streamsize write
+    (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::write_device_impl<T>::inner<unwrapped>::write(detail::unwrap(t), s, n);
+}
+
+template<typename T, typename Sink>
+inline std::streamsize
+write( T& t, Sink& snk, const typename char_type_of<T>::type* s, 
+       std::streamsize n )
+{
+    typedef typename detail::unwrapped_type<T>::type unwrapped;
+    return detail::write_filter_impl<T>::inner<unwrapped>::write(detail::unwrap(t), snk, s, n);
+}
+
+namespace detail {
+
+//------------------Definition of write_device_impl---------------------------//
+
+template<typename T>
+struct write_device_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          write_device_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, ostream_tag, streambuf_tag, output
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct write_device_impl<ostream_tag> {
+    template<typename T>
+    struct inner {
+        static bool put(T& t, typename char_type_of<T>::type c)
+        {
+            typedef typename char_type_of<T>::type          char_type;
+            typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
+            return !traits_type::eq_int_type( t.rdbuf()->s.sputc(),
+                                            traits_type::eof() );
+        }
+
+        static std::streamsize write
+            (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+        { return t.rdbuf()->sputn(s, n); }
+    };
+};
+
+template<>
+struct write_device_impl<streambuf_tag> {
+    template<typename T>
+    struct inner {
+        static bool put(T& t, typename char_type_of<T>::type c)
+        {
+            typedef typename char_type_of<T>::type          char_type;
+            typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
+            return !traits_type::eq_int_type(t.sputc(c), traits_type::eof());
+        }
+
+        template<typename T>
+        static std::streamsize write
+            (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+        { return t.sputn(s, n); }
+    };
+};
+
+template<>
+struct write_device_impl<output> {
+    template<typename T>
+    struct inner {
+        static bool put(T& t, typename char_type_of<T>::type c)
+        { return t.write(&c, 1) == 1; }
+
+        template<typename T>
+        static std::streamsize
+        write(T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+        { return t.write(s, n); }
+    };
+};
+
+//------------------Definition of write_filter_impl---------------------------//
+
+template<typename T>
+struct write_filter_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          write_filter_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, multichar_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct write_filter_impl<multichar_tag> {
+    template<typename T>
+    struct inner {
+        template<typename Sink>
+        static std::streamsize
+        write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
+               std::streamsize n )
+        { return t.write(snk, s, n); }
+    };
+};
+
+template<>
+struct write_filter_impl<any_tag> {
+    template<typename T>
+    struct inner {
+        template<typename Sink>
+        static std::streamsize
+        write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
+               std::streamsize n )
+        {
+            for (std::streamsize off = 0; off < n; ++off)
+                if (!t.put(snk, s[off]))
+                    return off;
+            return n;
+        }
+    };
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
diff --git a/include/ndnboost/iostreams/detail/wrap_unwrap.hpp b/include/ndnboost/iostreams/detail/wrap_unwrap.hpp
new file mode 100644
index 0000000..93291df
--- /dev/null
+++ b/include/ndnboost/iostreams/detail/wrap_unwrap.hpp
@@ -0,0 +1,127 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <ndnboost/config.hpp>                             // SFINAE, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/enable_if_stream.hpp>
+#include <ndnboost/iostreams/traits_fwd.hpp>               // is_std_io.
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/mpl/identity.hpp>
+#include <ndnboost/mpl/eval_if.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/ref.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+                    
+//------------------Definition of wrap/unwrap traits--------------------------//
+
+template<typename T>
+struct wrapped_type 
+    : mpl::if_<is_std_io<T>, reference_wrapper<T>, T>
+    { };
+
+template<typename T>
+struct unwrapped_type 
+    : unwrap_reference<T>
+    { };
+
+template<typename T>
+struct unwrap_ios 
+    : mpl::eval_if<
+          is_std_io<T>, 
+          unwrap_reference<T>, 
+          mpl::identity<T>
+      >
+    { };
+
+//------------------Definition of wrap----------------------------------------//
+
+#ifndef NDNBOOST_NO_SFINAE //----------------------------------------------------//
+    template<typename T>
+    inline T wrap(const T& t NDNBOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) 
+    { return t; }
+
+    template<typename T>
+    inline typename wrapped_type<T>::type
+    wrap(T& t NDNBOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) { return ndnboost::ref(t); }
+#else // #ifndef NDNBOOST_NO_SFINAE //-------------------------------------------//
+    template<typename T>
+    inline typename wrapped_type<T>::type // BCC 5.x needs namespace qualification.
+    wrap_impl(const T& t, mpl::true_) { return ndnboost::ref(const_cast<T&>(t)); }
+
+    template<typename T>
+    inline typename wrapped_type<T>::type // BCC 5.x needs namespace qualification.
+    wrap_impl(T& t, mpl::true_) { return ndnboost::ref(t); }
+
+    template<typename T>
+    inline typename wrapped_type<T>::type 
+    wrap_impl(const T& t, mpl::false_) { return t; }
+
+    template<typename T>
+    inline typename wrapped_type<T>::type 
+    wrap_impl(T& t, mpl::false_) { return t; }
+
+    template<typename T>
+    inline typename wrapped_type<T>::type 
+    wrap(const T& t) { return wrap_impl(t, is_std_io<T>()); }
+
+    template<typename T>
+    inline typename wrapped_type<T>::type 
+    wrap(T& t) { return wrap_impl(t, is_std_io<T>()); }
+#endif // #ifndef NDNBOOST_NO_SFINAE //------------------------------------------//
+
+//------------------Definition of unwrap--------------------------------------//
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310) //----------------------------------//
+
+template<typename T>
+typename unwrapped_type<T>::type& 
+unwrap(const reference_wrapper<T>& ref) { return ref.get(); }
+
+template<typename T>
+typename unwrapped_type<T>::type& unwrap(T& t) { return t; }
+
+template<typename T>
+const typename unwrapped_type<T>::type& unwrap(const T& t) { return t; }
+
+#else // #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310) //-------------------------//
+
+// Since unwrap is a potential bottleneck, we avoid runtime tag dispatch.
+template<bool IsRefWrap>
+struct unwrap_impl;
+
+template<>
+struct unwrap_impl<true> {
+    template<typename T>
+    static typename unwrapped_type<T>::type& unwrap(const T& t) 
+    { return t.get(); }
+};
+
+template<>
+struct unwrap_impl<false> {
+    template<typename T>
+    static typename unwrapped_type<T>::type& unwrap(const T& t) 
+    { return const_cast<T&>(t); }
+};
+
+template<typename T>
+typename unwrapped_type<T>::type& 
+unwrap(const T& t) 
+{ return unwrap_impl<is_reference_wrapper<T>::value>::unwrap(t); }
+
+#endif // #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1310) //------------------------//
+
+} } } // End namespaces detail, iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/device/array.hpp b/include/ndnboost/iostreams/device/array.hpp
new file mode 100644
index 0000000..f4eb39e
--- /dev/null
+++ b/include/ndnboost/iostreams/device/array.hpp
@@ -0,0 +1,144 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2004-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_ARRAY_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_ARRAY_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>         // NDNBOOST_MSVC, make sure size_t is in std.
+#include <ndnboost/detail/workaround.hpp>
+#include <cstddef>                  // std::size_t.
+#include <utility>                  // pair.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/preprocessor/cat.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename Mode, typename Ch>
+class array_adapter {
+public:
+    typedef Ch                                 char_type;
+    typedef std::pair<char_type*, char_type*>  pair_type;
+    struct category
+        : public Mode,
+          public device_tag,
+          public direct_tag
+        { };
+    array_adapter(char_type* begin, char_type* end);
+    array_adapter(char_type* begin, std::size_t length);
+    array_adapter(const char_type* begin, const char_type* end);
+    array_adapter(const char_type* begin, std::size_t length);
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+    template<int N>
+    array_adapter(char_type (&ar)[N])
+        : begin_(ar), end_(ar + N) 
+        { }
+#endif
+    pair_type input_sequence();
+    pair_type output_sequence();
+private:
+    char_type* begin_;
+    char_type* end_;
+};
+
+} // End namespace detail.
+
+// Local macros, #undef'd below.
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+# define NDNBOOST_IOSTREAMS_ARRAY_CTOR(name, ch) \
+    template<int N> \
+    NDNBOOST_PP_CAT(basic_, name)(ch (&ar)[N]) \
+        : base_type(ar) { } \
+    /**/
+#else
+# define NDNBOOST_IOSTREAMS_ARRAY_CTOR(name, ch)
+#endif
+#define NDNBOOST_IOSTREAMS_ARRAY(name, mode) \
+    template<typename Ch> \
+    struct NDNBOOST_PP_CAT(basic_, name) : detail::array_adapter<mode, Ch> { \
+    private: \
+        typedef detail::array_adapter<mode, Ch>  base_type; \
+    public: \
+        typedef typename base_type::char_type    char_type; \
+        typedef typename base_type::category     category; \
+        NDNBOOST_PP_CAT(basic_, name)(char_type* begin, char_type* end) \
+            : base_type(begin, end) { } \
+        NDNBOOST_PP_CAT(basic_, name)(char_type* begin, std::size_t length) \
+            : base_type(begin, length) { } \
+        NDNBOOST_PP_CAT(basic_, name)(const char_type* begin, const char_type* end) \
+            : base_type(begin, end) { } \
+        NDNBOOST_PP_CAT(basic_, name)(const char_type* begin, std::size_t length) \
+            : base_type(begin, length) { } \
+        NDNBOOST_IOSTREAMS_ARRAY_CTOR(name, Ch) \
+    }; \
+    typedef NDNBOOST_PP_CAT(basic_, name)<char>     name; \
+    typedef NDNBOOST_PP_CAT(basic_, name)<wchar_t>  NDNBOOST_PP_CAT(w, name); \
+    /**/
+NDNBOOST_IOSTREAMS_ARRAY(array_source, input_seekable)
+NDNBOOST_IOSTREAMS_ARRAY(array_sink, output_seekable)
+NDNBOOST_IOSTREAMS_ARRAY(array, seekable)
+#undef NDNBOOST_IOSTREAMS_ARRAY_CTOR
+#undef NDNBOOST_IOSTREAMS_ARRAY
+
+
+//------------------Implementation of array_adapter---------------------------//
+
+namespace detail {
+
+template<typename Mode, typename Ch>
+array_adapter<Mode, Ch>::array_adapter
+    (char_type* begin, char_type* end) 
+    : begin_(begin), end_(end) 
+    { }
+
+template<typename Mode, typename Ch>
+array_adapter<Mode, Ch>::array_adapter
+    (char_type* begin, std::size_t length) 
+    : begin_(begin), end_(begin + length) 
+    { }
+
+template<typename Mode, typename Ch>
+array_adapter<Mode, Ch>::array_adapter
+    (const char_type* begin, const char_type* end) 
+    : begin_(const_cast<char_type*>(begin)),  // Treated as read-only.
+      end_(const_cast<char_type*>(end))       // Treated as read-only.
+{ NDNBOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); }
+
+template<typename Mode, typename Ch>
+array_adapter<Mode, Ch>::array_adapter
+    (const char_type* begin, std::size_t length) 
+    : begin_(const_cast<char_type*>(begin)),       // Treated as read-only.
+      end_(const_cast<char_type*>(begin) + length) // Treated as read-only.
+{ NDNBOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); }
+
+template<typename Mode, typename Ch>
+typename array_adapter<Mode, Ch>::pair_type
+array_adapter<Mode, Ch>::input_sequence()
+{ NDNBOOST_STATIC_ASSERT((is_convertible<Mode, input>::value));
+  return pair_type(begin_, end_); }
+
+template<typename Mode, typename Ch>
+typename array_adapter<Mode, Ch>::pair_type
+array_adapter<Mode, Ch>::output_sequence()
+{ NDNBOOST_STATIC_ASSERT((is_convertible<Mode, output>::value));
+  return pair_type(begin_, end_); }
+
+} // End namespace detail.
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_ARRAY_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/device/back_inserter.hpp b/include/ndnboost/iostreams/device/back_inserter.hpp
new file mode 100644
index 0000000..3daace6
--- /dev/null
+++ b/include/ndnboost/iostreams/device/back_inserter.hpp
@@ -0,0 +1,41 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/detail/ios.hpp> // streamsize.
+#include <ndnboost/iostreams/categories.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template<typename Container>
+class back_insert_device {
+public:
+    typedef typename Container::value_type  char_type;
+    typedef sink_tag                        category;
+    back_insert_device(Container& cnt) : container(&cnt) { }
+    std::streamsize write(const char_type* s, std::streamsize n)
+    { 
+        container->insert(container->end(), s, s + n); 
+        return n;
+    }
+protected:
+    Container* container;
+};
+
+template<typename Container>
+back_insert_device<Container> back_inserter(Container& cnt)
+{ return back_insert_device<Container>(cnt); }
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/device/file.hpp b/include/ndnboost/iostreams/device/file.hpp
new file mode 100644
index 0000000..b8c85f2
--- /dev/null
+++ b/include/ndnboost/iostreams/device/file.hpp
@@ -0,0 +1,191 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+# include <locale>
+#endif
+#include <string>                               // pathnames, char_traits.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>       // openmode, seekdir, int types.
+#include <ndnboost/iostreams/detail/fstream.hpp>
+#include <ndnboost/iostreams/operations.hpp>       // seek.
+#include <ndnboost/shared_ptr.hpp>      
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+template<typename Ch>
+class basic_file {
+public:
+    typedef Ch char_type;
+    struct category
+        : public seekable_device_tag,
+          public closable_tag,
+          public localizable_tag,
+          public flushable_tag
+        { };
+    basic_file( const std::string& path,
+                NDNBOOST_IOS::openmode mode =
+                    NDNBOOST_IOS::in | NDNBOOST_IOS::out,
+                NDNBOOST_IOS::openmode base_mode =
+                    NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+    std::streamsize read(char_type* s, std::streamsize n);
+    bool putback(char_type c);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way, 
+                         NDNBOOST_IOS::openmode which = 
+                             NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+    void open( const std::string& path,
+               NDNBOOST_IOS::openmode mode =
+                   NDNBOOST_IOS::in | NDNBOOST_IOS::out,
+               NDNBOOST_IOS::openmode base_mode =
+                   NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+    bool is_open() const;
+    void close();
+    bool flush();
+#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
+    void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc);  }
+#endif
+private:
+    struct impl {
+        impl(const std::string& path, NDNBOOST_IOS::openmode mode)
+            { file_.open(path.c_str(), mode); }
+        ~impl() { if (file_.is_open()) file_.close(); }
+        NDNBOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_;
+    };
+    shared_ptr<impl> pimpl_;
+};
+
+typedef basic_file<char>     file;
+typedef basic_file<wchar_t>  wfile;
+
+template<typename Ch>
+struct basic_file_source : private basic_file<Ch> {
+    typedef Ch char_type;
+    struct category
+        : input_seekable,
+          device_tag,
+          closable_tag
+        { };
+    using basic_file<Ch>::read;
+    using basic_file<Ch>::putback;
+    using basic_file<Ch>::seek;
+    using basic_file<Ch>::is_open;
+    using basic_file<Ch>::close;
+    basic_file_source( const std::string& path,
+                       NDNBOOST_IOS::openmode mode = 
+                           NDNBOOST_IOS::in )
+        : basic_file<Ch>(path, mode & ~NDNBOOST_IOS::out, NDNBOOST_IOS::in)
+        { }
+    void open( const std::string& path,
+               NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in )
+    {
+        basic_file<Ch>::open(path, mode & ~NDNBOOST_IOS::out, NDNBOOST_IOS::in);
+    }
+};
+
+typedef basic_file_source<char>     file_source;
+typedef basic_file_source<wchar_t>  wfile_source;
+
+template<typename Ch>
+struct basic_file_sink : private basic_file<Ch> {
+    typedef Ch char_type;
+    struct category
+        : output_seekable,
+          device_tag,
+          closable_tag,
+          flushable_tag
+        { };
+    using basic_file<Ch>::write;
+    using basic_file<Ch>::seek;
+    using basic_file<Ch>::is_open;
+    using basic_file<Ch>::close;
+    using basic_file<Ch>::flush;
+    basic_file_sink( const std::string& path,
+                     NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out )
+        : basic_file<Ch>(path, mode & ~NDNBOOST_IOS::in, NDNBOOST_IOS::out)
+        { }
+    void open( const std::string& path,
+               NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out )
+    {
+        basic_file<Ch>::open(path, mode & ~NDNBOOST_IOS::in, NDNBOOST_IOS::out);
+    }
+};
+
+typedef basic_file_sink<char>     file_sink;
+typedef basic_file_sink<wchar_t>  wfile_sink;
+                                 
+//------------------Implementation of basic_file------------------------------//
+
+template<typename Ch>
+basic_file<Ch>::basic_file
+    ( const std::string& path, NDNBOOST_IOS::openmode mode, 
+      NDNBOOST_IOS::openmode base_mode )
+{ 
+    open(path, mode, base_mode);
+}
+
+template<typename Ch>
+inline std::streamsize basic_file<Ch>::read
+    (char_type* s, std::streamsize n)
+{ 
+    std::streamsize result = pimpl_->file_.sgetn(s, n); 
+    return result != 0 ? result : -1;
+}
+
+template<typename Ch>
+inline bool basic_file<Ch>::putback(char_type c)
+{ 
+    return !!pimpl_->file_.sputbackc(c); 
+}
+
+template<typename Ch>
+inline std::streamsize basic_file<Ch>::write
+    (const char_type* s, std::streamsize n)
+{ return pimpl_->file_.sputn(s, n); }
+
+template<typename Ch>
+std::streampos basic_file<Ch>::seek
+    ( stream_offset off, NDNBOOST_IOS::seekdir way, 
+      NDNBOOST_IOS::openmode )
+{ return iostreams::seek(pimpl_->file_, off, way); }
+
+template<typename Ch>
+void basic_file<Ch>::open
+    ( const std::string& path, NDNBOOST_IOS::openmode mode, 
+      NDNBOOST_IOS::openmode base_mode )
+{ 
+    pimpl_.reset(new impl(path, mode | base_mode));
+}
+
+template<typename Ch>
+bool basic_file<Ch>::is_open() const { return pimpl_->file_.is_open(); }
+
+template<typename Ch>
+void basic_file<Ch>::close() { pimpl_->file_.close(); }
+
+template<typename Ch>
+bool basic_file<Ch>::flush()
+{ return pimpl_->file_.NDNBOOST_IOSTREAMS_PUBSYNC() == 0; }
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/device/file_descriptor.hpp b/include/ndnboost/iostreams/device/file_descriptor.hpp
new file mode 100644
index 0000000..165a89e
--- /dev/null
+++ b/include/ndnboost/iostreams/device/file_descriptor.hpp
@@ -0,0 +1,318 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Inspired by fdstream.hpp, (C) Copyright Nicolai M. Josuttis 2001,
+// available at http://www.josuttis.com/cppcode/fdstream.html.
+
+#ifndef NDNBOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <string>
+#include <ndnboost/cstdint.hpp>               // intmax_t.
+#include <ndnboost/iostreams/categories.hpp>  // tags.
+#include <ndnboost/iostreams/detail/config/auto_link.hpp>
+#include <ndnboost/iostreams/detail/config/dyn_link.hpp>
+#include <ndnboost/iostreams/detail/config/windows_posix.hpp>
+#include <ndnboost/iostreams/detail/file_handle.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // openmode, seekdir, int types.
+#include <ndnboost/iostreams/detail/path.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/shared_ptr.hpp>
+
+// Must come last.
+#include <ndnboost/config/abi_prefix.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+// Forward declarations
+class file_descriptor_source;
+class file_descriptor_sink;
+namespace detail { struct file_descriptor_impl; }
+
+enum file_descriptor_flags
+{
+    never_close_handle = 0,
+    close_handle = 3
+};
+
+class NDNBOOST_IOSTREAMS_DECL file_descriptor {
+public:
+    friend class file_descriptor_source;
+    friend class file_descriptor_sink;
+    typedef detail::file_handle  handle_type;
+    typedef char                 char_type;
+    struct category
+        : seekable_device_tag,
+          closable_tag
+        { };
+
+    // Default constructor
+    file_descriptor();
+
+    // Constructors taking file desciptors
+    file_descriptor(handle_type fd, file_descriptor_flags);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    file_descriptor(int fd, file_descriptor_flags);
+#endif
+
+#if defined(NDNBOOST_IOSTREAMS_USE_DEPRECATED)
+    // Constructors taking file desciptors
+    explicit file_descriptor(handle_type fd, bool close_on_exit = false);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    explicit file_descriptor(int fd, bool close_on_exit = false);
+#endif
+#endif
+
+    // Constructor taking a std:: string
+    explicit file_descriptor( const std::string& path,
+                              NDNBOOST_IOS::openmode mode =
+                                  NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+
+    // Constructor taking a C-style string
+    explicit file_descriptor( const char* path,
+                              NDNBOOST_IOS::openmode mode =
+                                  NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+
+    // Constructor taking a Boost.Filesystem path
+    template<typename Path>
+    explicit file_descriptor( const Path& path,
+                              NDNBOOST_IOS::openmode mode =
+                                  NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+    { 
+        init();
+        open(detail::path(path), mode); 
+    }
+
+    // Copy constructor
+    file_descriptor(const file_descriptor& other);
+
+    // open overloads taking file descriptors
+    void open(handle_type fd, file_descriptor_flags);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    void open(int fd, file_descriptor_flags);
+#endif
+
+#if defined(NDNBOOST_IOSTREAMS_USE_DEPRECATED)
+    // open overloads taking file descriptors
+    void open(handle_type fd, bool close_on_exit = false);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    void open(int fd, bool close_on_exit = false);
+#endif
+#endif
+
+    // open overload taking a std::string
+    void open( const std::string& path,
+               NDNBOOST_IOS::openmode mode =
+                   NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+
+    // open overload taking C-style string
+    void open( const char* path,
+               NDNBOOST_IOS::openmode mode =
+                   NDNBOOST_IOS::in | NDNBOOST_IOS::out );
+
+    // open overload taking a Boost.Filesystem path
+    template<typename Path>
+    void open( const Path& path,
+               NDNBOOST_IOS::openmode mode =
+                   NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+    { open(detail::path(path), mode); }
+
+    bool is_open() const;
+    void close();
+    std::streamsize read(char_type* s, std::streamsize n);
+    std::streamsize write(const char_type* s, std::streamsize n);
+    std::streampos seek(stream_offset off, NDNBOOST_IOS::seekdir way);
+    handle_type handle() const;
+private:
+    void init();
+
+    // open overload taking a detail::path
+    void open( const detail::path& path, 
+               NDNBOOST_IOS::openmode, 
+               NDNBOOST_IOS::openmode = NDNBOOST_IOS::openmode(0) );
+
+    typedef detail::file_descriptor_impl impl_type;
+    shared_ptr<impl_type> pimpl_;
+};
+
+class NDNBOOST_IOSTREAMS_DECL file_descriptor_source : private file_descriptor {
+public:
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    typedef void*  handle_type;  // A.k.a HANDLE
+#else
+    typedef int    handle_type;
+#endif
+    typedef char   char_type;
+    struct category
+      : input_seekable,
+        device_tag,
+        closable_tag
+      { };
+    using file_descriptor::is_open;
+    using file_descriptor::close;
+    using file_descriptor::read;
+    using file_descriptor::seek;
+    using file_descriptor::handle;
+
+    // Default constructor
+    file_descriptor_source() { }
+
+    // Constructors taking file desciptors
+    explicit file_descriptor_source(handle_type fd, file_descriptor_flags);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    explicit file_descriptor_source(int fd, file_descriptor_flags);
+#endif
+
+#if defined(NDNBOOST_IOSTREAMS_USE_DEPRECATED)
+    // Constructors taking file desciptors
+    explicit file_descriptor_source(handle_type fd, bool close_on_exit = false);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    explicit file_descriptor_source(int fd, bool close_on_exit = false);
+#endif
+#endif
+
+    // Constructor taking a std:: string
+    explicit file_descriptor_source( const std::string& path,
+                                     NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in );
+
+    // Constructor taking a C-style string
+    explicit file_descriptor_source( const char* path,
+                                     NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in );
+
+    // Constructor taking a Boost.Filesystem path
+    template<typename Path>
+    explicit file_descriptor_source( const Path& path,
+                                     NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in )
+    { open(detail::path(path), mode); }
+
+    // Copy constructor
+    file_descriptor_source(const file_descriptor_source& other);
+
+    // Constructors taking file desciptors
+    void open(handle_type fd, file_descriptor_flags);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    void open(int fd, file_descriptor_flags);
+#endif
+
+#if defined(NDNBOOST_IOSTREAMS_USE_DEPRECATED)
+    // open overloads taking file descriptors
+    void open(handle_type fd, bool close_on_exit = false);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    void open(int fd, bool close_on_exit = false);
+#endif
+#endif
+
+    // open overload taking a std::string
+    void open(const std::string& path, NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in);
+
+    // open overload taking C-style string
+    void open(const char* path, NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in);
+
+    // open overload taking a Boost.Filesystem path
+    template<typename Path>
+    void open(const Path& path, NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in);
+private:
+
+    // open overload taking a detail::path
+    void open(const detail::path& path, NDNBOOST_IOS::openmode);
+};
+
+class NDNBOOST_IOSTREAMS_DECL file_descriptor_sink : private file_descriptor {
+public:
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    typedef void*  handle_type;  // A.k.a HANDLE
+#else
+    typedef int    handle_type;
+#endif
+    typedef char   char_type;
+    struct category
+      : output_seekable,
+        device_tag,
+        closable_tag
+      { };
+    using file_descriptor::is_open;
+    using file_descriptor::close;
+    using file_descriptor::write;
+    using file_descriptor::seek;
+    using file_descriptor::handle;
+
+    // Default constructor
+    file_descriptor_sink() { }
+
+    // Constructors taking file desciptors
+    file_descriptor_sink(handle_type fd, file_descriptor_flags);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    file_descriptor_sink(int fd, file_descriptor_flags);
+#endif
+
+#if defined(NDNBOOST_IOSTREAMS_USE_DEPRECATED)
+    // Constructors taking file desciptors
+    explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    explicit file_descriptor_sink(int fd, bool close_on_exit = false);
+#endif
+#endif
+
+    // Constructor taking a std:: string
+    explicit file_descriptor_sink( const std::string& path,
+                                   NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out );
+
+    // Constructor taking a C-style string
+    explicit file_descriptor_sink( const char* path,
+                                   NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out );
+
+    // Constructor taking a Boost.Filesystem path
+    template<typename Path>
+    explicit file_descriptor_sink( const Path& path,
+                                   NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out )
+    { open(detail::path(path), mode); }
+
+    // Copy constructor
+    file_descriptor_sink(const file_descriptor_sink& other);
+
+    // open overloads taking file descriptors
+    void open(handle_type fd, file_descriptor_flags);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    void open(int fd, file_descriptor_flags);
+#endif
+
+#if defined(NDNBOOST_IOSTREAMS_USE_DEPRECATED)
+    // open overloads taking file descriptors
+    void open(handle_type fd, bool close_on_exit = false);
+#ifdef NDNBOOST_IOSTREAMS_WINDOWS
+    void open(int fd, bool close_on_exit = false);
+#endif
+#endif
+
+    // open overload taking a std::string
+    void open( const std::string& path, 
+               NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out );
+
+    // open overload taking C-style string
+    void open( const char* path, 
+               NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out );
+
+    // open overload taking a Boost.Filesystem path
+    template<typename Path>
+    void open( const Path& path, 
+               NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out )
+    { open(detail::path(path), mode); }
+private:
+
+    // open overload taking a detail::path
+    void open(const detail::path& path, NDNBOOST_IOS::openmode);
+};
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/device/mapped_file.hpp b/include/ndnboost/iostreams/device/mapped_file.hpp
new file mode 100644
index 0000000..f8fbd55
--- /dev/null
+++ b/include/ndnboost/iostreams/device/mapped_file.hpp
@@ -0,0 +1,599 @@
+// (C) Copyright Jorge Lodos 2008.
+// (C) Copyright Jonathan Turkanis 2003.
+// (C) Copyright Craig Henderson 2002.   'boost/memmap.hpp' from sandbox
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+
+#ifndef NDNBOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>                   // make sure size_t is in std.
+#include <cstddef>                            // size_t.
+#include <string>                             // pathnames.
+#include <utility>                            // pair.
+#include <ndnboost/config.hpp>                   // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/close.hpp>
+#include <ndnboost/iostreams/concepts.hpp>
+#include <ndnboost/iostreams/detail/config/auto_link.hpp>
+#include <ndnboost/iostreams/detail/config/dyn_link.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>     // openmode, failure
+#include <ndnboost/iostreams/detail/path.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+// Must come last.
+#include <ndnboost/config/abi_prefix.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+//------------------Definition of mapped_file_base and mapped_file_params-----//
+
+// Forward declarations
+class mapped_file_source;
+class mapped_file_sink;
+class mapped_file;
+namespace detail { class mapped_file_impl; }
+
+class mapped_file_base {
+public:
+    enum mapmode {
+        readonly = 1,
+        readwrite = 2,
+        priv = 4
+    };
+};
+
+// Bitmask operations for mapped_file_base::mapmode
+mapped_file_base::mapmode 
+operator|(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
+
+mapped_file_base::mapmode 
+operator&(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
+
+mapped_file_base::mapmode 
+operator^(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
+
+mapped_file_base::mapmode 
+operator~(mapped_file_base::mapmode a);
+
+mapped_file_base::mapmode 
+operator|=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
+
+mapped_file_base::mapmode 
+operator&=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
+
+mapped_file_base::mapmode 
+operator^=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
+
+//------------------Definition of mapped_file_params--------------------------//
+
+namespace detail {
+
+struct mapped_file_params_base {
+    mapped_file_params_base()
+        : flags(static_cast<mapped_file_base::mapmode>(0)), 
+          mode(), offset(0), length(static_cast<std::size_t>(-1)), 
+          new_file_size(0), hint(0)
+        { }
+private:
+    friend class mapped_file_impl;
+    void normalize();
+public:
+    mapped_file_base::mapmode   flags;
+    NDNBOOST_IOS::openmode         mode;  // Deprecated
+    stream_offset               offset;
+    std::size_t                 length;
+    stream_offset               new_file_size;
+    const char*                 hint;
+};
+
+} // End namespace detail.
+
+// This template allows Boost.Filesystem paths to be specified when creating or
+// reopening a memory mapped file, without creating a dependence on
+// Boost.Filesystem. Possible values of Path include std::string,
+// ndnboost::filesystem::path, ndnboost::filesystem::wpath, 
+// and ndnboost::iostreams::detail::path (used to store either a std::string or a
+// std::wstring).
+template<typename Path>
+struct basic_mapped_file_params 
+    : detail::mapped_file_params_base 
+{
+    typedef detail::mapped_file_params_base base_type;
+
+    // For wide paths, instantiate basic_mapped_file_params 
+    // with ndnboost::filesystem::wpath
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+    NDNBOOST_STATIC_ASSERT((!is_same<Path, std::wstring>::value));
+#endif
+
+    // Default constructor
+    basic_mapped_file_params() { }
+
+    // Construction from a Path
+    explicit basic_mapped_file_params(const Path& p) : path(p) { }
+
+    // Construction from a path of a different type
+    template<typename PathT>
+    explicit basic_mapped_file_params(const PathT& p) : path(p) { }
+
+    // Copy constructor
+    basic_mapped_file_params(const basic_mapped_file_params& other)
+        : base_type(other), path(other.path)
+        { }
+
+    // Templated copy constructor
+    template<typename PathT>
+    basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
+        : base_type(other), path(other.path)
+        { }
+
+    typedef Path  path_type;
+    Path          path;
+};
+
+typedef basic_mapped_file_params<std::string> mapped_file_params;
+
+//------------------Definition of mapped_file_source--------------------------//
+
+class NDNBOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base {
+private:
+    struct safe_bool_helper { int x; };
+    typedef int safe_bool_helper::*                 safe_bool;
+    typedef detail::mapped_file_impl                impl_type;
+    typedef basic_mapped_file_params<detail::path>  param_type;
+    friend class mapped_file;
+    friend class detail::mapped_file_impl;
+    friend struct ndnboost::iostreams::operations<mapped_file_source>;
+public:
+    typedef char                                    char_type;
+    struct category
+        : public source_tag,
+          public direct_tag,
+          public closable_tag
+        { };
+    typedef std::size_t                             size_type;
+    typedef const char*                             iterator;
+    NDNBOOST_STATIC_CONSTANT(size_type, max_length = static_cast<size_type>(-1));
+
+    // Default constructor
+    mapped_file_source();
+
+    // Constructor taking a parameters object
+    template<typename Path>
+    explicit mapped_file_source(const basic_mapped_file_params<Path>& p);
+
+    // Constructor taking a list of parameters
+    template<typename Path>
+    explicit mapped_file_source( const Path& path,
+                                 size_type length = max_length,
+                                 ndnboost::intmax_t offset = 0 );
+
+    // Copy Constructor
+    mapped_file_source(const mapped_file_source& other);
+
+    //--------------Stream interface------------------------------------------//
+
+    template<typename Path>
+    void open(const basic_mapped_file_params<Path>& p);
+
+    template<typename Path>
+    void open( const Path& path,
+               size_type length = max_length,
+               ndnboost::intmax_t offset = 0 );
+
+    bool is_open() const;
+    void close();
+    operator safe_bool() const;
+    bool operator!() const;
+    mapmode flags() const;
+
+    //--------------Container interface---------------------------------------//
+
+    size_type size() const;
+    const char* data() const;
+    iterator begin() const;
+    iterator end() const;
+
+    //--------------Query admissible offsets----------------------------------//
+
+    // Returns the allocation granularity for virtual memory. Values passed
+    // as offsets must be multiples of this value.
+    static int alignment();
+
+private:
+    void init();
+    void open_impl(const param_type& p);
+
+    ndnboost::shared_ptr<impl_type> pimpl_;
+};
+
+//------------------Definition of mapped_file---------------------------------//
+
+class NDNBOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base {
+private:
+    typedef mapped_file_source                      delegate_type;
+    typedef delegate_type::safe_bool                safe_bool;
+    typedef basic_mapped_file_params<detail::path>  param_type;
+    friend struct ndnboost::iostreams::operations<mapped_file >;
+    friend class mapped_file_sink;
+public:
+    typedef char                                    char_type;
+    struct category
+        : public seekable_device_tag,
+          public direct_tag,
+          public closable_tag
+        { };
+    typedef mapped_file_source::size_type           size_type;
+    typedef char*                                   iterator;
+    typedef const char*                             const_iterator;
+    NDNBOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length);
+
+    // Default constructor
+    mapped_file() { }
+
+    // Construstor taking a parameters object
+    template<typename Path>
+    explicit mapped_file(const basic_mapped_file_params<Path>& p);
+
+    // Constructor taking a list of parameters
+    template<typename Path>
+    mapped_file( const Path& path,
+                 mapmode flags,
+                 size_type length = max_length,
+                 stream_offset offset = 0 );
+
+    // Constructor taking a list of parameters, including a 
+    // std::ios_base::openmode (deprecated)
+    template<typename Path>
+    explicit mapped_file( const Path& path,
+                          NDNBOOST_IOS::openmode mode =
+                              NDNBOOST_IOS::in | NDNBOOST_IOS::out,
+                          size_type length = max_length,
+                          stream_offset offset = 0 );
+
+    // Copy Constructor
+    mapped_file(const mapped_file& other);
+
+    //--------------Conversion to mapped_file_source (deprecated)-------------//
+
+    operator mapped_file_source&() { return delegate_; }
+    operator const mapped_file_source&() const { return delegate_; }
+
+    //--------------Stream interface------------------------------------------//
+
+    // open overload taking a parameters object
+    template<typename Path>
+    void open(const basic_mapped_file_params<Path>& p);
+
+    // open overload taking a list of parameters
+    template<typename Path>
+    void open( const Path& path,
+               mapmode mode,
+               size_type length = max_length,
+               stream_offset offset = 0 );
+
+    // open overload taking a list of parameters, including a 
+    // std::ios_base::openmode (deprecated)
+    template<typename Path>
+    void open( const Path& path,
+               NDNBOOST_IOS::openmode mode =
+                   NDNBOOST_IOS::in | NDNBOOST_IOS::out,
+               size_type length = max_length,
+               stream_offset offset = 0 );
+
+    bool is_open() const { return delegate_.is_open(); }
+    void close() { delegate_.close(); }
+    operator safe_bool() const { return delegate_; }
+    bool operator!() const { return !delegate_; }
+    mapmode flags() const { return delegate_.flags(); }
+
+    //--------------Container interface---------------------------------------//
+
+    size_type size() const { return delegate_.size(); }
+    char* data() const;
+    const char* const_data() const { return delegate_.data(); }
+    iterator begin() const { return data(); }
+    const_iterator const_begin() const { return const_data(); }
+    iterator end() const { return data() + size(); }
+    const_iterator const_end() const { return const_data() + size(); }
+
+    //--------------Query admissible offsets----------------------------------//
+
+    // Returns the allocation granularity for virtual memory. Values passed
+    // as offsets must be multiples of this value.
+    static int alignment() { return mapped_file_source::alignment(); }
+
+    //--------------File access----------------------------------------------//
+
+    void resize(stream_offset new_size);
+private:
+    delegate_type delegate_;
+};
+
+//------------------Definition of mapped_file_sink----------------------------//
+
+class NDNBOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file {
+public:
+    friend struct ndnboost::iostreams::operations<mapped_file_sink>;
+    using mapped_file::mapmode;
+    using mapped_file::readonly;
+    using mapped_file::readwrite;
+    using mapped_file::priv;
+    using mapped_file::char_type;
+    struct category
+        : public sink_tag,
+          public direct_tag,
+          public closable_tag
+        { };
+    using mapped_file::size_type;
+    using mapped_file::iterator;
+    using mapped_file::max_length;
+    using mapped_file::is_open;
+    using mapped_file::close;
+    using mapped_file::operator safe_bool;
+    using mapped_file::operator !;
+    using mapped_file::flags;
+    using mapped_file::size;
+    using mapped_file::data;
+    using mapped_file::begin;
+    using mapped_file::end;
+    using mapped_file::alignment;
+    using mapped_file::resize;
+
+    // Default constructor
+    mapped_file_sink() { }
+
+    // Constructor taking a parameters object
+    template<typename Path>
+    explicit mapped_file_sink(const basic_mapped_file_params<Path>& p);
+
+    // Constructor taking a list of parameters
+    template<typename Path>
+    explicit mapped_file_sink( const Path& path,
+                               size_type length = max_length,
+                               ndnboost::intmax_t offset = 0,
+                               mapmode flags = readwrite );
+
+    // Copy Constructor
+    mapped_file_sink(const mapped_file_sink& other);
+
+    // open overload taking a parameters object
+    template<typename Path>
+    void open(const basic_mapped_file_params<Path>& p);
+
+    // open overload taking a list of parameters
+    template<typename Path>
+    void open( const Path& path,
+               size_type length = max_length,
+               ndnboost::intmax_t offset = 0,
+               mapmode flags = readwrite );
+};
+
+//------------------Implementation of mapped_file_source----------------------//
+
+template<typename Path>
+mapped_file_source::mapped_file_source(const basic_mapped_file_params<Path>& p)
+{ init(); open(p); }
+
+template<typename Path>
+mapped_file_source::mapped_file_source( 
+    const Path& path, size_type length, ndnboost::intmax_t offset)
+{ init(); open(path, length, offset); }
+
+template<typename Path>
+void mapped_file_source::open(const basic_mapped_file_params<Path>& p)
+{
+    param_type params(p);
+    if (params.flags) {
+        if (params.flags != mapped_file::readonly)
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("invalid flags"));
+    } else {
+        if (params.mode & NDNBOOST_IOS::out)
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("invalid mode"));
+        params.mode |= NDNBOOST_IOS::in;
+    }
+    open_impl(params);
+}
+
+template<typename Path>
+void mapped_file_source::open(
+    const Path& path, size_type length, ndnboost::intmax_t offset)
+{
+    param_type p(path);
+    p.length = length;
+    p.offset = offset;
+    open(p);
+}
+
+//------------------Implementation of mapped_file-----------------------------//
+
+template<typename Path>
+mapped_file::mapped_file(const basic_mapped_file_params<Path>& p)
+{ open(p); }
+
+template<typename Path>
+mapped_file::mapped_file( 
+    const Path& path, mapmode flags, 
+    size_type length, stream_offset offset )
+{ open(path, flags, length, offset); }
+
+template<typename Path>
+mapped_file::mapped_file( 
+    const Path& path, NDNBOOST_IOS::openmode mode, 
+    size_type length, stream_offset offset )
+{ open(path, mode, length, offset); }
+
+template<typename Path>
+void mapped_file::open(const basic_mapped_file_params<Path>& p)
+{ delegate_.open_impl(p); }
+
+template<typename Path>
+void mapped_file::open( 
+    const Path& path, mapmode flags, 
+    size_type length, stream_offset offset )
+{
+    param_type p(path);
+    p.flags = flags;
+    p.length = length;
+    p.offset = offset;
+    open(p);
+}
+
+template<typename Path>
+void mapped_file::open( 
+    const Path& path, NDNBOOST_IOS::openmode mode, 
+    size_type length, stream_offset offset )
+{
+    param_type p(path);
+    p.mode = mode;
+    p.length = length;
+    p.offset = offset;
+    open(p);
+}
+
+inline char* mapped_file::data() const 
+{ return (flags() != readonly) ? const_cast<char*>(delegate_.data()) : 0; }
+
+//------------------Implementation of mapped_file_sink------------------------//
+
+template<typename Path>
+mapped_file_sink::mapped_file_sink(const basic_mapped_file_params<Path>& p)
+{ open(p); }
+
+template<typename Path>
+mapped_file_sink::mapped_file_sink(
+    const Path& path, size_type length,
+    ndnboost::intmax_t offset, mapmode flags )
+{ open(path, length, offset, flags); }
+
+template<typename Path>
+void mapped_file_sink::open(const basic_mapped_file_params<Path>& p)
+{
+    param_type params(p);
+    if (params.flags) {
+        if (params.flags & mapped_file::readonly)
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("invalid flags"));
+    } else {
+        if (params.mode & NDNBOOST_IOS::in)
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("invalid mode"));
+        params.mode |= NDNBOOST_IOS::out;
+    }
+    mapped_file::open(params);
+}
+
+template<typename Path>
+void mapped_file_sink::open(
+    const Path& path, size_type length,
+    ndnboost::intmax_t offset, mapmode flags )
+{
+    param_type p(path);
+    p.flags = flags;
+    p.length = length;
+    p.offset = offset;
+    open(p);
+}
+
+//------------------Specialization of direct_impl-----------------------------//
+
+template<>
+struct operations<mapped_file_source>
+    : ndnboost::iostreams::detail::close_impl<closable_tag>
+{
+    static std::pair<char*, char*>
+    input_sequence(mapped_file_source& src)
+    {
+        return std::make_pair( const_cast<char*>(src.begin()),
+                               const_cast<char*>(src.end()) );
+    }
+};
+
+template<>
+struct operations<mapped_file>
+    : ndnboost::iostreams::detail::close_impl<closable_tag>
+{
+    static std::pair<char*, char*>
+    input_sequence(mapped_file& file)
+    { 
+        return std::make_pair(file.begin(), file.end()); 
+    }
+    static std::pair<char*, char*>
+    output_sequence(mapped_file& file)
+    { 
+        return std::make_pair(file.begin(), file.end()); 
+    }
+};
+
+template<>
+struct operations<mapped_file_sink>
+    : ndnboost::iostreams::detail::close_impl<closable_tag>
+{
+    static std::pair<char*, char*>
+    output_sequence(mapped_file_sink& sink)
+    { 
+        return std::make_pair(sink.begin(), sink.end()); 
+    }
+};
+                    
+//------------------Definition of mapmode operators---------------------------//
+
+inline mapped_file::mapmode 
+operator|(mapped_file::mapmode a, mapped_file::mapmode b)
+{
+    return static_cast<mapped_file::mapmode>
+        (static_cast<int>(a) | static_cast<int>(b));
+}
+
+inline mapped_file::mapmode 
+operator&(mapped_file::mapmode a, mapped_file::mapmode b)
+{
+    return static_cast<mapped_file::mapmode>
+        (static_cast<int>(a) & static_cast<int>(b));
+}
+
+inline mapped_file::mapmode 
+operator^(mapped_file::mapmode a, mapped_file::mapmode b)
+{
+    return static_cast<mapped_file::mapmode>
+        (static_cast<int>(a) ^ static_cast<int>(b));
+}
+
+inline mapped_file::mapmode
+operator~(mapped_file::mapmode a)
+{
+    return static_cast<mapped_file::mapmode>(~static_cast<int>(a));
+}
+
+inline mapped_file::mapmode 
+operator|=(mapped_file::mapmode& a, mapped_file::mapmode b)
+{
+    return a = a | b;
+}
+
+inline mapped_file::mapmode 
+operator&=(mapped_file::mapmode& a, mapped_file::mapmode b)
+{
+    return a = a & b;
+}
+
+inline mapped_file::mapmode 
+operator^=(mapped_file::mapmode& a, mapped_file::mapmode b)
+{
+    return a = a ^ b;
+}
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/device/null.hpp b/include/ndnboost/iostreams/device/null.hpp
new file mode 100644
index 0000000..66abd9b
--- /dev/null
+++ b/include/ndnboost/iostreams/device/null.hpp
@@ -0,0 +1,66 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2004-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Inspired by Daryle Walker's nullbuf from his More I/O submission.
+
+#ifndef NDNBOOST_IOSTREAMS_NULL_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_NULL_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp> // openmode, streamsize.
+#include <ndnboost/iostreams/positioning.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template<typename Ch, typename Mode>
+class basic_null_device {
+public:
+    typedef Ch char_type;
+    struct category
+        : public Mode,
+          public device_tag,
+          public closable_tag
+        { };
+    std::streamsize read(Ch*, std::streamsize) { return 0; }
+    std::streamsize write(const Ch*, std::streamsize n) { return n; }
+    std::streampos seek( stream_offset, NDNBOOST_IOS::seekdir,
+                         NDNBOOST_IOS::openmode = 
+                             NDNBOOST_IOS::in | NDNBOOST_IOS::out ) 
+    { return -1; }
+    void close() { }
+    void close(NDNBOOST_IOS::openmode) { }
+};
+
+template<typename Ch>
+struct basic_null_source : private basic_null_device<Ch, input> {
+    typedef Ch          char_type;
+    typedef source_tag  category;
+    using basic_null_device<Ch, input>::read;
+    using basic_null_device<Ch, input>::close;
+};
+
+typedef basic_null_source<char>     null_source;
+typedef basic_null_source<wchar_t>  wnull_source;
+
+template<typename Ch>
+struct basic_null_sink : private basic_null_device<Ch, output> {
+    typedef Ch        char_type;
+    typedef sink_tag  category;
+    using basic_null_device<Ch, output>::write;
+    using basic_null_device<Ch, output>::close;
+};
+
+typedef basic_null_sink<char>     null_sink;
+typedef basic_null_sink<wchar_t>  wnull_sink;
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_NULL_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/aggregate.hpp b/include/ndnboost/iostreams/filter/aggregate.hpp
new file mode 100644
index 0000000..3cba05f
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/aggregate.hpp
@@ -0,0 +1,168 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <algorithm>                          // copy, min.
+#include <ndnboost/assert.hpp>
+#include <iterator>                           // back_inserter
+#include <vector>
+#include <ndnboost/iostreams/constants.hpp>      // default_device_buffer_size 
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>     // openmode, streamsize.
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/iostreams/read.hpp>           // check_eof 
+#include <ndnboost/iostreams/write.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Template name: aggregate_filter.
+// Template parameters:
+//      Ch - The character type.
+//      Alloc - The allocator type.
+// Description: Utility for defining DualUseFilters which filter an
+//      entire stream at once. To use, override the protected virtual
+//      member do_filter.
+// Note: This filter should not be copied while it is in use.
+//
+template<typename Ch, typename Alloc = std::allocator<Ch> >
+class aggregate_filter  {
+public:
+    typedef Ch char_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          multichar_tag,
+          closable_tag
+        { };
+    aggregate_filter() : ptr_(0), state_(0) { }
+    virtual ~aggregate_filter() { }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        using namespace std;
+        NDNBOOST_ASSERT(!(state_ & f_write));
+        state_ |= f_read;
+        if (!(state_ & f_eof))
+            do_read(src);
+        std::streamsize amt =
+            (std::min)(n, static_cast<std::streamsize>(data_.size() - ptr_));
+        if (amt) {
+            NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt);
+            ptr_ += amt;
+        }
+        return detail::check_eof(amt);
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink&, const char_type* s, std::streamsize n)
+    {
+        NDNBOOST_ASSERT(!(state_ & f_read));
+        state_ |= f_write;
+        data_.insert(data_.end(), s, s + n);
+        return n;
+    }
+
+    template<typename Sink>
+    void close(Sink& sink, NDNBOOST_IOS::openmode which)
+    {
+        if ((state_ & f_read) != 0 && which == NDNBOOST_IOS::in)
+            close_impl();
+        if ((state_ & f_write) != 0 && which == NDNBOOST_IOS::out) {
+            try {
+                vector_type filtered;
+                do_filter(data_, filtered);
+                do_write( 
+                    sink, &filtered[0],
+                    static_cast<std::streamsize>(filtered.size())
+                );
+            } catch (...) {
+                close_impl();
+                throw;
+            }
+            close_impl();
+        }
+    }
+
+protected:
+    typedef std::vector<Ch, Alloc>           vector_type;
+    typedef typename vector_type::size_type  size_type;
+private:
+    virtual void do_filter(const vector_type& src, vector_type& dest) = 0;
+    virtual void do_close() { }
+
+    template<typename Source>
+    void do_read(Source& src)
+    {
+        using std::streamsize;
+        vector_type data;
+        while (true) {
+            const std::streamsize  size = default_device_buffer_size;
+            Ch                     buf[size];
+            std::streamsize        amt;
+            if ((amt = ndnboost::iostreams::read(src, buf, size)) == -1)
+                break;
+            data.insert(data.end(), buf, buf + amt);
+        }
+        do_filter(data, data_);
+        state_ |= f_eof;
+    }
+
+    template<typename Sink>
+    void do_write(Sink& sink, const char_type* s, std::streamsize n) 
+    { 
+        typedef typename iostreams::category_of<Sink>::type  category;
+        typedef is_convertible<category, output>             can_write;
+        do_write(sink, s, n, can_write()); 
+    }
+
+    template<typename Sink>
+    void do_write(Sink& sink, const char_type* s, std::streamsize n, mpl::true_) 
+    { iostreams::write(sink, s, n); }
+
+    template<typename Sink>
+    void do_write(Sink&, const char_type*, std::streamsize, mpl::false_) { }
+
+    void close_impl()
+    {
+        data_.clear();
+        ptr_ = 0;
+        state_ = 0;
+        do_close();
+    }
+
+    enum flag_type {
+        f_read   = 1,
+        f_write  = f_read << 1,
+        f_eof    = f_write << 1
+    };
+
+    // Note: typically will not be copied while vector contains data.
+    vector_type  data_;
+    size_type    ptr_;
+    int          state_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(aggregate_filter, 1)
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/bzip2.hpp b/include/ndnboost/iostreams/filter/bzip2.hpp
new file mode 100644
index 0000000..f26c4d0
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/bzip2.hpp
@@ -0,0 +1,414 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Note: custom allocators are not supported on VC6, since that compiler
+// had trouble finding the function zlib_base::do_init.
+
+#ifndef NDNBOOST_IOSTREAMS_BZIP2_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_BZIP2_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+                   
+#include <cassert>                            
+#include <memory>            // allocator.
+#include <new>               // bad_alloc.
+#include <ndnboost/config.hpp>  // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/constants.hpp>   // buffer size.
+#include <ndnboost/iostreams/detail/config/auto_link.hpp>
+#include <ndnboost/iostreams/detail/config/bzip2.hpp>
+#include <ndnboost/iostreams/detail/config/dyn_link.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // failure, streamsize.
+#include <ndnboost/iostreams/filter/symmetric.hpp>               
+#include <ndnboost/iostreams/pipeline.hpp>       
+#include <ndnboost/type_traits/is_same.hpp>     
+
+// Must come last.
+#ifdef NDNBOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:4251 4231 4660)
+#endif
+#include <ndnboost/config/abi_prefix.hpp>           
+
+// Temporary fix.
+#undef small
+
+namespace ndnboost { namespace iostreams {
+
+namespace bzip2 {
+
+                    // Typedefs.
+
+typedef void* (*alloc_func)(void*, int, int);
+typedef void (*free_func)(void*, void*);
+
+                    // Status codes
+
+NDNBOOST_IOSTREAMS_DECL extern const int ok;
+NDNBOOST_IOSTREAMS_DECL extern const int run_ok;
+NDNBOOST_IOSTREAMS_DECL extern const int flush_ok;
+NDNBOOST_IOSTREAMS_DECL extern const int finish_ok;
+NDNBOOST_IOSTREAMS_DECL extern const int stream_end;    
+NDNBOOST_IOSTREAMS_DECL extern const int sequence_error;
+NDNBOOST_IOSTREAMS_DECL extern const int param_error;
+NDNBOOST_IOSTREAMS_DECL extern const int mem_error;
+NDNBOOST_IOSTREAMS_DECL extern const int data_error;
+NDNBOOST_IOSTREAMS_DECL extern const int data_error_magic;
+NDNBOOST_IOSTREAMS_DECL extern const int io_error;
+NDNBOOST_IOSTREAMS_DECL extern const int unexpected_eof;
+NDNBOOST_IOSTREAMS_DECL extern const int outbuff_full;
+NDNBOOST_IOSTREAMS_DECL extern const int config_error;
+
+                    // Action codes
+
+NDNBOOST_IOSTREAMS_DECL extern const int finish;
+NDNBOOST_IOSTREAMS_DECL extern const int run;
+
+                    // Default values
+
+const int default_block_size   = 9;
+const int default_work_factor  = 30;
+const bool default_small       = false;
+
+} // End namespace bzip2. 
+
+//
+// Class name: bzip2_params.
+// Description: Encapsulates the parameters passed to deflateInit2
+//      to customize compression.
+//
+struct bzip2_params {
+
+    // Non-explicit constructor for compression.
+    bzip2_params( int block_size   = bzip2::default_block_size,
+                  int work_factor  = bzip2::default_work_factor )
+        : block_size(block_size), work_factor(work_factor)
+        { }
+
+    // Constructor for decompression.
+    bzip2_params(bool small)
+        : small(small), work_factor(0)
+        { }
+
+    union {
+        int   block_size;    // For compression.
+        bool  small;         // For decompression.
+    };
+    int       work_factor;
+};
+
+//
+// Class name: bzip2_error.
+// Description: Subclass of std::ios_base::failure thrown to indicate
+//     bzip2 errors other than out-of-memory conditions.
+//
+class NDNBOOST_IOSTREAMS_DECL bzip2_error : public NDNBOOST_IOSTREAMS_FAILURE {
+public:
+    explicit bzip2_error(int error);
+    int error() const { return error_; }
+    static void check NDNBOOST_PREVENT_MACRO_SUBSTITUTION(int error);
+private:
+    int error_;
+};
+
+namespace detail {
+
+template<typename Alloc>
+struct bzip2_allocator_traits {
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+    typedef typename Alloc::template rebind<char>::other type;
+#else
+    typedef std::allocator<char> type;
+#endif
+};
+
+template< typename Alloc,
+          typename Base = // VC6 workaround (C2516)
+              NDNBOOST_DEDUCED_TYPENAME bzip2_allocator_traits<Alloc>::type >
+struct bzip2_allocator : private Base {
+private:
+    typedef typename Base::size_type size_type;
+public:
+    NDNBOOST_STATIC_CONSTANT(bool, custom = 
+        (!is_same<std::allocator<char>, Base>::value));
+    typedef typename bzip2_allocator_traits<Alloc>::type allocator_type;
+    static void* allocate(void* self, int items, int size);
+    static void deallocate(void* self, void* address);
+};
+
+class NDNBOOST_IOSTREAMS_DECL bzip2_base  { 
+public:
+    typedef char char_type;
+protected:
+    bzip2_base(const bzip2_params& params);
+    ~bzip2_base();
+    bzip2_params& params() { return params_; }
+    bool& ready() { return ready_; }
+    template<typename Alloc> 
+    void init( bool compress,
+               bzip2_allocator<Alloc>& alloc )
+        {
+            bool custom = bzip2_allocator<Alloc>::custom;
+            do_init( compress,
+                     #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+                         custom ? bzip2_allocator<Alloc>::allocate : 0,
+                         custom ? bzip2_allocator<Alloc>::deallocate : 0,
+                     #endif
+                     custom ? &alloc : 0 );
+        }
+    void before( const char*& src_begin, const char* src_end,
+                 char*& dest_begin, char* dest_end );
+    void after(const char*& src_begin, char*& dest_begin);
+    int check_end(const char* src_begin, const char* dest_begin);
+    int compress(int action);
+    int decompress();
+    void end(bool compress);
+private:
+    void do_init( bool compress, 
+                  #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+                      bzip2::alloc_func, 
+                      bzip2::free_func, 
+                  #endif
+                  void* derived );
+    bzip2_params  params_;
+    void*         stream_; // Actual type: bz_stream*.
+    bool          ready_;
+};
+
+//
+// Template name: bzip2_compressor_impl
+// Description: Model of SymmetricFilter implementing compression by
+//      delegating to the libbzip2 function BZ_bzCompress.
+//
+template<typename Alloc = std::allocator<char> >
+class bzip2_compressor_impl 
+    : public bzip2_base, 
+      #if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600)
+          public
+      #endif
+      bzip2_allocator<Alloc> 
+{
+public: 
+    bzip2_compressor_impl(const bzip2_params&);
+    bool filter( const char*& src_begin, const char* src_end,
+                 char*& dest_begin, char* dest_end, bool flush );
+    void close();
+private:
+    void init();
+    bool eof_; // Guard to make sure filter() isn't called after it returns false.
+};
+
+//
+// Template name: bzip2_compressor
+// Description: Model of SymmetricFilter implementing decompression by
+//      delegating to the libbzip2 function BZ_bzDecompress.
+//
+template<typename Alloc = std::allocator<char> >
+class bzip2_decompressor_impl 
+    : public bzip2_base, 
+      #if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600)
+          public
+      #endif
+      bzip2_allocator<Alloc> 
+{ 
+public:
+    bzip2_decompressor_impl(bool small = bzip2::default_small);
+    bool filter( const char*& begin_in, const char* end_in,
+                 char*& begin_out, char* end_out, bool flush );
+    void close();
+private:
+    void init();
+    bool eof_; // Guard to make sure filter() isn't called after it returns false.
+};
+
+} // End namespace detail.
+
+//
+// Template name: bzip2_compressor
+// Description: Model of InputFilter and OutputFilter implementing
+//      compression using libbzip2.
+//
+template<typename Alloc = std::allocator<char> >
+struct basic_bzip2_compressor 
+    : symmetric_filter<detail::bzip2_compressor_impl<Alloc>, Alloc> 
+{
+private:
+    typedef detail::bzip2_compressor_impl<Alloc>        impl_type;
+    typedef symmetric_filter<impl_type, Alloc>  base_type;
+public:
+    typedef typename base_type::char_type               char_type;
+    typedef typename base_type::category                category;
+    basic_bzip2_compressor( const bzip2_params& = bzip2::default_block_size, 
+                            int buffer_size =  default_device_buffer_size );
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_bzip2_compressor, 1)
+
+typedef basic_bzip2_compressor<> bzip2_compressor;
+
+//
+// Template name: bzip2_decompressor
+// Description: Model of InputFilter and OutputFilter implementing
+//      decompression using libbzip2.
+//
+template<typename Alloc = std::allocator<char> >
+struct basic_bzip2_decompressor 
+    : symmetric_filter<detail::bzip2_decompressor_impl<Alloc>, Alloc> 
+{
+private:
+    typedef detail::bzip2_decompressor_impl<Alloc>      impl_type;
+    typedef symmetric_filter<impl_type, Alloc>  base_type;
+public:
+    typedef typename base_type::char_type               char_type;
+    typedef typename base_type::category                category;
+    basic_bzip2_decompressor( bool small = bzip2::default_small,
+                              int buffer_size = default_device_buffer_size );
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_bzip2_decompressor, 1)
+
+typedef basic_bzip2_decompressor<> bzip2_decompressor;
+
+//----------------------------------------------------------------------------//
+
+//------------------Implementation of bzip2_allocator-------------------------//
+
+namespace detail {
+
+template<typename Alloc, typename Base>
+void* bzip2_allocator<Alloc, Base>::allocate(void* self, int items, int size)
+{ 
+    size_type len = items * size;
+    char* ptr = 
+        static_cast<allocator_type*>(self)->allocate
+            (len + sizeof(size_type)
+            #if NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1)
+                , (char*)0
+            #endif
+            );
+    *reinterpret_cast<size_type*>(ptr) = len;
+    return ptr + sizeof(size_type);
+}
+
+template<typename Alloc, typename Base>
+void bzip2_allocator<Alloc, Base>::deallocate(void* self, void* address)
+{ 
+    char* ptr = reinterpret_cast<char*>(address) - sizeof(size_type);
+    size_type len = *reinterpret_cast<size_type*>(ptr) + sizeof(size_type);
+    static_cast<allocator_type*>(self)->deallocate(ptr, len); 
+}
+
+//------------------Implementation of bzip2_compressor_impl-------------------//
+
+template<typename Alloc>
+bzip2_compressor_impl<Alloc>::bzip2_compressor_impl(const bzip2_params& p)
+    : bzip2_base(p), eof_(false) { }
+
+template<typename Alloc>
+bool bzip2_compressor_impl<Alloc>::filter
+    ( const char*& src_begin, const char* src_end,
+      char*& dest_begin, char* dest_end, bool flush )
+{
+    if (!ready()) init();
+    if (eof_) return false;
+    before(src_begin, src_end, dest_begin, dest_end);
+    int result = compress(flush ? bzip2::finish : bzip2::run);
+    after(src_begin, dest_begin);
+    bzip2_error::check NDNBOOST_PREVENT_MACRO_SUBSTITUTION(result);
+    return !(eof_ = result == bzip2::stream_end);
+}
+
+template<typename Alloc>
+void bzip2_compressor_impl<Alloc>::close() 
+{ 
+    try {
+        end(true);
+    } catch (...) { 
+        eof_ = false; 
+        throw;
+    }
+    eof_ = false;
+}
+
+template<typename Alloc>
+inline void bzip2_compressor_impl<Alloc>::init() 
+{ bzip2_base::init(true, static_cast<bzip2_allocator<Alloc>&>(*this)); }
+
+//------------------Implementation of bzip2_decompressor_impl-----------------//
+
+template<typename Alloc>
+bzip2_decompressor_impl<Alloc>::bzip2_decompressor_impl(bool small)
+    : bzip2_base(bzip2_params(small)), eof_(false) { }
+
+template<typename Alloc>
+bool bzip2_decompressor_impl<Alloc>::filter
+    ( const char*& src_begin, const char* src_end,
+      char*& dest_begin, char* dest_end, bool flush )
+{
+    if (eof_) {
+        // reset the stream if there are more characters
+        if(src_begin == src_end)
+            return false;
+        else
+            close();
+    }
+    if (!ready()) 
+        init();
+    before(src_begin, src_end, dest_begin, dest_end);
+    int result = decompress();
+    if(result == bzip2::ok && flush)
+        result = check_end(src_begin, dest_begin);
+    after(src_begin, dest_begin);
+    bzip2_error::check NDNBOOST_PREVENT_MACRO_SUBSTITUTION(result);
+    eof_ = result == bzip2::stream_end;
+    return true; 
+}
+
+template<typename Alloc>
+void bzip2_decompressor_impl<Alloc>::close() 
+{ 
+    try {
+        end(false);
+    } catch (...) { 
+        eof_ = false; 
+        throw;
+    }
+    eof_ = false;
+}
+
+template<typename Alloc>
+inline void bzip2_decompressor_impl<Alloc>::init()
+{ bzip2_base::init(false, static_cast<bzip2_allocator<Alloc>&>(*this)); }
+} // End namespace detail.
+
+//------------------Implementation of bzip2_decompressor----------------------//
+
+template<typename Alloc>
+basic_bzip2_compressor<Alloc>::basic_bzip2_compressor
+        (const bzip2_params& p, int buffer_size) 
+    : base_type(buffer_size, p) 
+    { }
+
+//------------------Implementation of bzip2_decompressor----------------------//
+
+template<typename Alloc>
+basic_bzip2_decompressor<Alloc>::basic_bzip2_decompressor
+        (bool small, int buffer_size) 
+    : base_type(buffer_size, small)
+    { }
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/config/abi_suffix.hpp> // Pops abi_suffix.hpp pragmas.
+#ifdef NDNBOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_BZIP2_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/counter.hpp b/include/ndnboost/iostreams/filter/counter.hpp
new file mode 100644
index 0000000..4780c16
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/counter.hpp
@@ -0,0 +1,82 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_COUNTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_COUNTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <algorithm>  // count.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/pipeline.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4244.
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Template name: basic_counter.
+// Template parameters:
+//      Ch - The character type.
+// Description: Filter which counts lines and characters.
+//
+template<typename Ch>
+class basic_counter  {
+public:
+    typedef Ch char_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          multichar_tag,
+          optimally_buffered_tag
+        { };
+    explicit basic_counter(int first_line = 0, int first_char = 0)
+        : lines_(first_line), chars_(first_char)
+        { }
+    int lines() const { return lines_; }
+    int characters() const { return chars_; }
+    std::streamsize optimal_buffer_size() const { return 0; }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        std::streamsize result = iostreams::read(src, s, n);
+        if (result == -1)
+            return -1;
+        lines_ += std::count(s, s + result, char_traits<Ch>::newline());
+        chars_ += result;
+        return result;
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        std::streamsize result = iostreams::write(snk, s, n);
+        lines_ += std::count(s, s + result, char_traits<Ch>::newline());
+        chars_ += result;
+        return result;
+    }
+private:
+    int lines_;
+    int chars_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_counter, 1)
+
+
+typedef basic_counter<char>     counter;
+typedef basic_counter<wchar_t>  wcounter;
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_COUNTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/grep.hpp b/include/ndnboost/iostreams/filter/grep.hpp
new file mode 100644
index 0000000..e37a296
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/grep.hpp
@@ -0,0 +1,109 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+
+ * File:        ndnboost/iostreams/filter/grep.hpp
+ * Date:        Mon May 26 17:48:45 MDT 2008
+ * Copyright:   2008 CodeRage, LLC
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the class template basic_grep_filter and its specializations
+ * grep_filter and wgrep_filter.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_GREP_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_GREP_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <iostream>
+
+#include <memory>  // allocator.
+#include <ndnboost/iostreams/char_traits.hpp>   
+#include <ndnboost/iostreams/filter/line.hpp>              
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/regex.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace grep {
+
+const int invert      = 1;
+const int whole_line  = invert << 1;
+
+} // End namespace grep.
+
+template< typename Ch,
+          typename Tr = regex_traits<Ch>,
+          typename Alloc = std::allocator<Ch> >
+class basic_grep_filter : public basic_line_filter<Ch, Alloc> {
+private:
+    typedef basic_line_filter<Ch, Alloc>               base_type;
+public:
+    typedef typename base_type::char_type              char_type;
+    typedef typename base_type::category               category;
+    typedef char_traits<char_type>                     traits_type;
+    typedef typename base_type::string_type            string_type;
+    typedef basic_regex<Ch, Tr>                        regex_type;
+    typedef regex_constants::match_flag_type           match_flag_type;
+    basic_grep_filter( const regex_type& re,
+                       match_flag_type match_flags = 
+                           regex_constants::match_default,
+                       int options = 0 );
+    int count() const { return count_; }
+
+    template<typename Sink>
+    void close(Sink& snk, NDNBOOST_IOS::openmode which)
+    {
+        base_type::close(snk, which);
+        options_ &= ~f_initialized;
+    }
+private:
+    virtual string_type do_filter(const string_type& line)
+    {
+        if ((options_ & f_initialized) == 0) {
+            options_ |= f_initialized;
+            count_ = 0;
+        }
+        bool matches = (options_ & grep::whole_line) ?
+            regex_match(line, re_, match_flags_) :
+            regex_search(line, re_, match_flags_);
+        if (options_ & grep::invert)
+            matches = !matches;
+        if (matches)
+            ++count_;
+        return matches ? line + traits_type::newline() : string_type();
+    }
+
+    // Private flags bitwise OR'd with constants from namespace grep
+    enum flags_ {
+        f_initialized = 65536
+    };
+
+    regex_type       re_;
+    match_flag_type  match_flags_;
+    int              options_;
+    int              count_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_grep_filter, 3)
+
+typedef basic_grep_filter<char>     grep_filter;
+typedef basic_grep_filter<wchar_t>  wgrep_filter;
+                    
+//------------------Implementation of basic_grep_filter-----------------------//
+
+template<typename Ch, typename Tr, typename Alloc>
+basic_grep_filter<Ch, Tr, Alloc>::basic_grep_filter
+    (const regex_type& re, match_flag_type match_flags, int options)
+    : base_type(true), re_(re), match_flags_(match_flags), 
+      options_(options), count_(0)
+    { }
+
+} } // End namespaces iostreams, boost.
+
+#endif      // #ifndef NDNBOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/gzip.hpp b/include/ndnboost/iostreams/filter/gzip.hpp
new file mode 100644
index 0000000..d4f9fcd
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/gzip.hpp
@@ -0,0 +1,757 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the definitions of the class templates gzip_compressor and
+// gzip_decompressor for reading and writing files in the gzip file format
+// (RFC 1952). Based in part on work of Jonathan de Halleux; see [...]
+
+#ifndef NDNBOOST_IOSTREAMS_GZIP_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_GZIP_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp> // STATIC_CONSTANT, STDC_NAMESPACE, 
+                            // DINKUMWARE_STDLIB, __STL_CONFIG_H.
+#include <algorithm>                      // min.
+#include <ndnboost/assert.hpp>
+#include <cstdio>                         // EOF.
+#include <cstddef>                        // size_t.
+#include <ctime>                          // std::time_t.
+#include <memory>                         // allocator.
+#include <ndnboost/config.hpp>               // Put size_t in std.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/cstdint.hpp>              // uint8_t, uint32_t.
+#include <ndnboost/iostreams/constants.hpp>  // buffer size.
+#include <ndnboost/iostreams/detail/adapter/non_blocking_adapter.hpp>
+#include <ndnboost/iostreams/detail/adapter/range_adapter.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp> // failure.
+#include <ndnboost/iostreams/detail/error.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/device/back_inserter.hpp>
+#include <ndnboost/iostreams/filter/zlib.hpp>
+#include <ndnboost/iostreams/pipeline.hpp>     
+#include <ndnboost/iostreams/putback.hpp>
+#include <ndnboost/throw_exception.hpp>
+
+// Must come last.
+#if defined(NDNBOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4309)    // Truncation of constant value.
+#endif
+
+#ifdef NDNBOOST_NO_STDC_NAMESPACE
+namespace std { using ::time_t; }
+#endif
+
+namespace ndnboost { namespace iostreams {
+                    
+//------------------Definitions of constants----------------------------------//
+
+namespace gzip {
+
+using namespace ndnboost::iostreams::zlib;
+
+    // Error codes used by gzip_error.
+
+const int zlib_error        = 1;
+const int bad_crc           = 2; // Recorded crc doesn't match data.
+const int bad_length        = 3; // Recorded length doesn't match data.
+const int bad_header        = 4; // Malformed header.
+const int bad_footer        = 5; // Malformed footer.
+const int bad_method        = 6; // Unsupported compression method.
+
+namespace magic {
+
+    // Magic numbers used by gzip header.
+
+const int id1               = 0x1f;
+const int id2               = 0x8b;
+
+} // End namespace magic.
+
+namespace method {
+
+    // Codes used for the 'CM' byte of the gzip header.
+
+const int deflate           = 8;
+
+} // End namespace method.
+
+namespace flags {
+
+    // Codes used for the 'FLG' byte of the gzip header.
+
+const int text              = 1;
+const int header_crc        = 2;
+const int extra             = 4;
+const int name              = 8;
+const int comment           = 16;
+
+} // End namespace flags.
+
+namespace extra_flags {
+
+    // Codes used for the 'XFL' byte of the gzip header.
+
+const int best_compression  = 2;
+const int best_speed        = 4;
+
+} // End namespace extra_flags.
+
+    // Codes used for the 'OS' byte of the gzip header.
+
+const int os_fat            = 0;
+const int os_amiga          = 1;
+const int os_vms            = 2;
+const int os_unix           = 3;
+const int os_vm_cms         = 4;
+const int os_atari          = 5;
+const int os_hpfs           = 6;
+const int os_macintosh      = 7;
+const int os_z_system       = 8;
+const int os_cp_m           = 9;
+const int os_tops_20        = 10;
+const int os_ntfs           = 11;
+const int os_qdos           = 12;
+const int os_acorn          = 13;
+const int os_unknown        = 255;
+
+} // End namespace gzip.
+
+//------------------Definition of gzip_params---------------------------------//
+
+//
+// Class name: gzip_params.
+// Description: Subclass of zlib_params with an additional field
+//      representing a file name.
+//
+struct gzip_params : zlib_params {
+
+    // Non-explicit constructor.
+    gzip_params( int level              = gzip::default_compression,
+                 int method             = gzip::deflated,
+                 int window_bits        = gzip::default_window_bits,
+                 int mem_level          = gzip::default_mem_level,
+                 int strategy           = gzip::default_strategy,
+                 std::string file_name  = "",
+                 std::string comment    = "",
+                 std::time_t mtime      = 0 )
+        : zlib_params(level, method, window_bits, mem_level, strategy),
+          file_name(file_name), comment(comment), mtime(mtime)
+        { }
+    std::string  file_name;
+    std::string  comment;
+    std::time_t  mtime;
+};
+
+//------------------Definition of gzip_error----------------------------------//
+
+//
+// Class name: gzip_error.
+// Description: Subclass of std::ios_base::failure thrown to indicate
+//     zlib errors other than out-of-memory conditions.
+//
+class gzip_error : public NDNBOOST_IOSTREAMS_FAILURE {
+public:
+    explicit gzip_error(int error)
+        : NDNBOOST_IOSTREAMS_FAILURE("gzip error"),
+          error_(error), zlib_error_code_(zlib::okay) { }
+    explicit gzip_error(const zlib_error& e)
+        : NDNBOOST_IOSTREAMS_FAILURE("gzip error"),
+          error_(gzip::zlib_error), zlib_error_code_(e.error())
+        { }
+    int error() const { return error_; }
+    int zlib_error_code() const { return zlib_error_code_; }
+private:
+    int error_;
+    int zlib_error_code_;
+};
+
+//------------------Definition of gzip_compressor-----------------------------//
+
+//
+// Template name: gzip_compressor
+// Description: Model of OutputFilter implementing compression in the
+//      gzip format.
+//
+template<typename Alloc = std::allocator<char> >
+class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
+private:
+    typedef basic_zlib_compressor<Alloc>  base_type;
+public:
+    typedef char char_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          multichar_tag,
+          closable_tag
+        { };
+    basic_gzip_compressor( const gzip_params& = gzip::default_compression,
+                           int buffer_size = default_device_buffer_size );
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        std::streamsize result = 0;
+
+        // Read header.
+        if (!(flags_ & f_header_done))
+            result += read_string(s, n, header_);
+
+        // Read body.
+        if (!(flags_ & f_body_done)) {
+
+            // Read from basic_zlib_filter.
+            std::streamsize amt = base_type::read(src, s + result, n - result);
+            if (amt != -1) {
+                result += amt;
+                if (amt < n - result) { // Double-check for EOF.
+                    amt = base_type::read(src, s + result, n - result);
+                    if (amt != -1)
+                        result += amt;
+                }
+            }
+            if (amt == -1)
+                prepare_footer();
+        }
+
+        // Read footer.
+        if ((flags_ & f_body_done) != 0 && result < n)
+            result += read_string(s + result, n - result, footer_);
+
+        return result != 0 ? result : -1;
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        if (!(flags_ & f_header_done)) {
+            std::streamsize amt = 
+                static_cast<std::streamsize>(header_.size() - offset_);
+            offset_ += ndnboost::iostreams::write(snk, header_.data() + offset_, amt);
+            if (offset_ == header_.size())
+                flags_ |= f_header_done;
+            else
+                return 0;
+        }
+        return base_type::write(snk, s, n);
+    }
+
+    template<typename Sink>
+    void close(Sink& snk, NDNBOOST_IOS::openmode m)
+    {
+        try {
+            // Close zlib compressor.
+            base_type::close(snk, m);
+
+            if (m == NDNBOOST_IOS::out) {
+                if (flags_ & f_header_done) {
+
+                    // Write final fields of gzip file format.
+                    write_long(this->crc(), snk);
+                    write_long(this->total_in(), snk);
+                }
+            }
+        } catch(...) {
+            close_impl();
+            throw;
+        }
+        close_impl();
+    }
+private:
+    static gzip_params normalize_params(gzip_params p);
+    void prepare_footer();
+    std::streamsize read_string(char* s, std::streamsize n, std::string& str);
+
+    template<typename Sink>
+    static void write_long(long n, Sink& next, ndnboost::mpl::true_)
+    {
+        ndnboost::iostreams::put(next, static_cast<char>(0xFF & n));
+        ndnboost::iostreams::put(next, static_cast<char>(0xFF & (n >> 8)));
+        ndnboost::iostreams::put(next, static_cast<char>(0xFF & (n >> 16)));
+        ndnboost::iostreams::put(next, static_cast<char>(0xFF & (n >> 24)));
+    }
+    template<typename Sink>
+    static void write_long(long n, Sink& next, ndnboost::mpl::false_)
+    {
+    }
+    template<typename Sink>
+    static void write_long(long n, Sink& next)
+    {
+        typedef typename category_of<Sink>::type category;
+        typedef is_convertible<category, output> can_write;
+        write_long(n, next, can_write());
+    }
+
+    void close_impl()
+    {
+        #if NDNBOOST_WORKAROUND(__GNUC__, == 2) && defined(__STL_CONFIG_H) || \
+            NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) \
+            /**/
+            footer_.erase(0, std::string::npos);
+        #else
+            footer_.clear();
+        #endif
+        offset_ = 0;
+        flags_ = 0;
+    }
+
+    enum state_type {
+        f_header_done = 1,
+        f_body_done = f_header_done << 1,
+        f_footer_done = f_body_done << 1
+    };
+    std::string  header_;
+    std::string  footer_;
+    std::size_t  offset_;
+    int          flags_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_gzip_compressor, 1)
+
+typedef basic_gzip_compressor<> gzip_compressor;
+
+//------------------Definition of helper templates for decompression----------//
+
+namespace detail {
+
+// Processes gzip headers
+class NDNBOOST_IOSTREAMS_DECL gzip_header {
+public:
+    gzip_header() { reset(); }
+
+    // Members for processing header data
+    void process(char c);
+    bool done() const { return state_ == s_done; }
+    void reset();
+
+    // Members for accessing header data
+    std::string file_name() const { return file_name_; }
+    std::string comment() const { return comment_; }
+    bool text() const { return (flags_ & gzip::flags::text) != 0; }
+    int os() const { return os_; }
+    std::time_t mtime() const { return mtime_; }
+private:
+    enum state_type {
+        s_id1       = 1,
+        s_id2       = s_id1 + 1,
+        s_cm        = s_id2 + 1,
+        s_flg       = s_cm + 1,
+        s_mtime     = s_flg + 1,
+        s_xfl       = s_mtime + 1,
+        s_os        = s_xfl + 1,
+        s_xlen      = s_os + 1,
+        s_extra     = s_xlen + 1,
+        s_name      = s_extra + 1,
+        s_comment   = s_name + 1,
+        s_hcrc      = s_comment + 1,
+        s_done      = s_hcrc + 1
+    };
+    std::string  file_name_;
+    std::string  comment_;
+    int          os_;
+    std::time_t  mtime_;
+    int          flags_;
+    int          state_;
+    int          offset_;  // Offset within fixed-length region.
+    int          xlen_;    // Bytes remaining in extra field.
+};
+
+// Processes gzip footers
+class NDNBOOST_IOSTREAMS_DECL gzip_footer {
+public:
+    gzip_footer() { reset(); }
+    
+    // Members for processing footer data
+    void process(char c);
+    bool done() const { return state_ == s_done; }
+    void reset();
+    
+    // Members for accessing footer data
+    zlib::ulong crc() const { return crc_; }
+    zlib::ulong uncompressed_size() const { return isize_; }
+private:
+    enum state_type {
+        s_crc     = 1,
+        s_isize   = s_crc + 1,
+        s_done    = s_isize + 1
+    };
+    zlib::ulong  crc_;
+    zlib::ulong  isize_;
+    int          state_;
+    int          offset_; 
+};
+
+} // End namespace ndnboost::iostreams::detail.
+
+//------------------Definition of basic_gzip_decompressor---------------------//
+
+//
+// Template name: basic_gzip_decompressor
+// Description: Model of InputFilter implementing compression in the
+//      gzip format.
+//
+template<typename Alloc = std::allocator<char> >
+class basic_gzip_decompressor : basic_zlib_decompressor<Alloc> {
+private:
+    typedef basic_zlib_decompressor<Alloc>   base_type;
+    typedef typename base_type::string_type  string_type;
+public:
+    typedef char char_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          multichar_tag,
+          closable_tag
+        { };
+    basic_gzip_decompressor( int window_bits = gzip::default_window_bits,
+                             int buffer_size = default_device_buffer_size );
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        std::streamsize result = 0;
+        while(result < n) {
+            if(state_ == s_start) {
+                state_ = s_header;
+                header_.reset();
+                footer_.reset();
+            }
+            if (state_ == s_header) {
+                int c = s[result++];
+                header_.process(c);
+                if (header_.done())
+                    state_ = s_body;
+            } else if (state_ == s_body) {
+                try {
+                    std::streamsize amt = 
+                        base_type::write(snk, s + result, n - result);
+                    result += amt;
+                    if (!this->eof()) {
+                        break;
+                    } else {
+                        state_ = s_footer;
+                    }
+                } catch (const zlib_error& e) {
+                    ndnboost::throw_exception(gzip_error(e));
+                }
+            } else { // state_ == s_footer
+                if (footer_.done()) {
+                    if (footer_.crc() != this->crc())
+                        ndnboost::throw_exception(gzip_error(gzip::bad_crc));
+
+                    base_type::close(snk, NDNBOOST_IOS::out);
+                    state_ = s_start;
+                } else {
+                    int c = s[result++];
+                    footer_.process(c);
+                }
+            }
+        }
+        return result;
+    }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        typedef char_traits<char>  traits_type;
+        std::streamsize            result = 0;
+        peekable_source<Source>    peek(src, putback_);
+        while (result < n && state_ != s_done) {
+            if (state_ == s_start) {
+                state_ = s_header;
+                header_.reset();
+                footer_.reset();
+            }
+            if (state_ == s_header) {
+                int c = ndnboost::iostreams::get(peek);
+                if (traits_type::is_eof(c)) {
+                    ndnboost::throw_exception(gzip_error(gzip::bad_header));
+                } else if (traits_type::would_block(c)) {
+                    break;
+                }
+                header_.process(c);
+                if (header_.done())
+                    state_ = s_body;
+            } else if (state_ == s_body) {
+                try {
+                    std::streamsize amt = 
+                        base_type::read(peek, s + result, n - result);
+                    if (amt != -1) {
+                        result += amt;
+                        if (amt < n - result)
+                            break;
+                    } else {
+                        peek.putback(this->unconsumed_input());
+                        state_ = s_footer;
+                    }
+                } catch (const zlib_error& e) {
+                    ndnboost::throw_exception(gzip_error(e));
+                }
+            } else { // state_ == s_footer
+                int c = ndnboost::iostreams::get(peek);
+                if (traits_type::is_eof(c)) {
+                    ndnboost::throw_exception(gzip_error(gzip::bad_footer));
+                } else if (traits_type::would_block(c)) {
+                    break;
+                }
+                footer_.process(c);
+                if (footer_.done()) {
+                    if (footer_.crc() != this->crc())
+                        ndnboost::throw_exception(gzip_error(gzip::bad_crc));
+                    int c = ndnboost::iostreams::get(peek);
+                    if (traits_type::is_eof(c)) {
+                        state_ = s_done;
+                    } else {
+                        peek.putback(c);
+                        base_type::close(peek, NDNBOOST_IOS::in);
+                        state_ = s_start;
+                        header_.reset();
+                        footer_.reset();
+                    }
+                }
+            }
+        }
+        if (peek.has_unconsumed_input()) {
+            putback_ = peek.unconsumed_input();
+        } else {
+            putback_.clear();
+        }
+        return result != 0 || state_ != s_done ?
+            result :
+            -1;
+    }
+
+    template<typename Source>
+    void close(Source& src, NDNBOOST_IOS::openmode m)
+    {
+        try {
+            base_type::close(src, m);
+        } catch (const zlib_error& e) {
+            state_ = s_start;
+            ndnboost::throw_exception(gzip_error(e));
+        }
+        if (m == NDNBOOST_IOS::out) {
+            if (state_ == s_start || state_ == s_header)
+                ndnboost::throw_exception(gzip_error(gzip::bad_header));
+            else if (state_ == s_body)
+                ndnboost::throw_exception(gzip_error(gzip::bad_footer));
+            else if (state_ == s_footer) {
+                if (!footer_.done())
+                    ndnboost::throw_exception(gzip_error(gzip::bad_footer));
+                else if(footer_.crc() != this->crc())
+                    ndnboost::throw_exception(gzip_error(gzip::bad_crc));
+            } else {
+                NDNBOOST_ASSERT(!"Bad state");
+            }
+        }
+        state_ = s_start;
+    }
+
+    std::string file_name() const { return header_.file_name(); }
+    std::string comment() const { return header_.comment(); }
+    bool text() const { return header_.text(); }
+    int os() const { return header_.os(); }
+    std::time_t mtime() const { return header_.mtime(); }
+private:
+    static gzip_params make_params(int window_bits);
+
+    // Source adapter allowing an arbitrary character sequence to be put back.
+    template<typename Source>
+    struct peekable_source {
+        typedef char char_type;
+        struct category : source_tag, peekable_tag { };
+        explicit peekable_source(Source& src, const string_type& putback = "") 
+            : src_(src), putback_(putback), offset_(0)
+            { }
+        std::streamsize read(char* s, std::streamsize n)
+        {
+            std::streamsize result = 0;
+
+            // Copy characters from putback buffer
+            std::streamsize pbsize = 
+                static_cast<std::streamsize>(putback_.size());
+            if (offset_ < pbsize) {
+                result = (std::min)(n, pbsize - offset_);
+                NDNBOOST_IOSTREAMS_CHAR_TRAITS(char)::copy(
+                    s, putback_.data() + offset_, result);
+                offset_ += result;
+                if (result == n)
+                    return result;
+            }
+
+            // Read characters from src_
+            std::streamsize amt = 
+                ndnboost::iostreams::read(src_, s + result, n - result);
+            return amt != -1 ? 
+                result + amt : 
+                result ? result : -1;
+        }
+        bool putback(char c)
+        {
+            if (offset_) {
+                putback_[--offset_] = c;
+            } else {
+                ndnboost::throw_exception(
+                    ndnboost::iostreams::detail::bad_putback());
+            }
+            return true;
+        }
+        void putback(const string_type& s)
+        {
+            putback_.replace(0, offset_, s);
+            offset_ = 0;
+        }
+
+        // Returns true if some characters have been putback but not re-read.
+        bool has_unconsumed_input() const 
+        {
+            return offset_ < static_cast<std::streamsize>(putback_.size());
+        }
+
+        // Returns the sequence of characters that have been put back but not re-read.
+        string_type unconsumed_input() const
+        {
+            return string_type(putback_, offset_, putback_.size() - offset_);
+        }
+        Source&          src_;
+        string_type      putback_;
+        std::streamsize  offset_;
+    };
+
+    enum state_type {
+        s_start   = 1,
+        s_header  = s_start + 1,
+        s_body    = s_header + 1,
+        s_footer  = s_body + 1,
+        s_done    = s_footer + 1
+    };
+    detail::gzip_header  header_;
+    detail::gzip_footer  footer_;
+    string_type          putback_;
+    int                  state_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1)
+
+typedef basic_gzip_decompressor<> gzip_decompressor;
+
+//------------------Implementation of gzip_compressor-------------------------//
+
+template<typename Alloc>
+basic_gzip_compressor<Alloc>::basic_gzip_compressor
+    (const gzip_params& p, int buffer_size)
+    : base_type(normalize_params(p), buffer_size),
+      offset_(0), flags_(0)
+{
+    // Calculate gzip header.
+    bool has_name = !p.file_name.empty();
+    bool has_comment = !p.comment.empty();
+
+    std::string::size_type length =
+        10 +
+        (has_name ? p.file_name.size() + 1 : 0) +
+        (has_comment ? p.comment.size() + 1 : 0);
+        // + 2; // Header crc confuses gunzip.
+    int flags =
+        //gzip::flags::header_crc +
+        (has_name ? gzip::flags::name : 0) +
+        (has_comment ? gzip::flags::comment : 0);
+    int extra_flags =
+        ( p.level == zlib::best_compression ?
+              gzip::extra_flags::best_compression :
+              0 ) +
+        ( p.level == zlib::best_speed ?
+              gzip::extra_flags::best_speed :
+              0 );
+    header_.reserve(length);
+    header_ += gzip::magic::id1;                         // ID1.
+    header_ += gzip::magic::id2;                         // ID2.
+    header_ += gzip::method::deflate;                    // CM.
+    header_ += static_cast<char>(flags);                 // FLG.
+    header_ += static_cast<char>(0xFF & p.mtime);        // MTIME.
+    header_ += static_cast<char>(0xFF & (p.mtime >> 8));
+    header_ += static_cast<char>(0xFF & (p.mtime >> 16));
+    header_ += static_cast<char>(0xFF & (p.mtime >> 24));
+    header_ += static_cast<char>(extra_flags);           // XFL.
+    header_ += static_cast<char>(gzip::os_unknown);      // OS.
+    if (has_name) {
+        header_ += p.file_name;
+        header_ += '\0';
+    }
+    if (has_comment) {
+        header_ += p.comment;
+        header_ += '\0';
+    }
+}
+
+template<typename Alloc>
+gzip_params basic_gzip_compressor<Alloc>::normalize_params(gzip_params p)
+{
+    p.noheader = true;
+    p.calculate_crc = true;
+    return p;
+}
+
+template<typename Alloc>
+void basic_gzip_compressor<Alloc>::prepare_footer()
+{
+    ndnboost::iostreams::back_insert_device<std::string> out(footer_);
+    write_long(this->crc(), out);
+    write_long(this->total_in(), out);
+    flags_ |= f_body_done;
+    offset_ = 0;
+}
+
+template<typename Alloc>
+std::streamsize basic_gzip_compressor<Alloc>::read_string
+    (char* s, std::streamsize n, std::string& str)
+{
+    std::streamsize avail =
+        static_cast<std::streamsize>(str.size() - offset_);
+    std::streamsize amt = (std::min)(avail, n);
+    std::copy( str.data() + offset_,
+               str.data() + offset_ + amt,
+               s );
+    offset_ += amt;
+    if ( !(flags_ & f_header_done) &&
+         offset_ == static_cast<std::size_t>(str.size()) )
+    {
+        flags_ |= f_header_done;
+    }
+    return amt;
+}
+
+//------------------Implementation of gzip_decompressor-----------------------//
+
+template<typename Alloc>
+basic_gzip_decompressor<Alloc>::basic_gzip_decompressor
+    (int window_bits, int buffer_size)
+    : base_type(make_params(window_bits), buffer_size),
+      state_(s_start)
+    { }
+
+template<typename Alloc>
+gzip_params basic_gzip_decompressor<Alloc>::make_params(int window_bits)
+{
+    gzip_params p;
+    p.window_bits = window_bits;
+    p.noheader = true;
+    p.calculate_crc = true;
+    return p;
+}
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#if defined(NDNBOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_GZIP_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/line.hpp b/include/ndnboost/iostreams/filter/line.hpp
new file mode 100644
index 0000000..d8399b3
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/line.hpp
@@ -0,0 +1,227 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <algorithm>                               // min.
+#include <ndnboost/assert.hpp>
+#include <memory>                                  // allocator.
+#include <string>
+#include <ndnboost/config.hpp>                        // NDNBOOST_STATIC_CONSTANT.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/checked_operations.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>          // openmode, streamsize.
+#include <ndnboost/iostreams/read.hpp>                // check_eof 
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/iostreams/write.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4244.
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Template name: line_filter.
+// Template parameters:
+//      Ch - The character type.
+//      Alloc - The allocator type.
+// Description: Filter which processes data one line at a time.
+//
+template< typename Ch,
+          typename Alloc =
+          #if NDNBOOST_WORKAROUND(__GNUC__, < 3)
+              typename std::basic_string<Ch>::allocator_type
+          #else
+              std::allocator<Ch>
+          #endif
+          >
+class basic_line_filter {
+private:
+    typedef typename std::basic_string<Ch>::traits_type  string_traits;
+public:
+    typedef Ch                                           char_type;
+    typedef char_traits<char_type>                       traits_type;
+    typedef std::basic_string<
+                Ch,
+                string_traits,
+                Alloc
+            >                                            string_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          multichar_tag,
+          closable_tag
+        { };
+protected:
+    basic_line_filter(bool suppress_newlines = false) 
+        : pos_(string_type::npos), 
+          flags_(suppress_newlines ? f_suppress : 0) 
+        { }
+public:
+    virtual ~basic_line_filter() { }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        using namespace std;
+        NDNBOOST_ASSERT(!(flags_ & f_write));
+        flags_ |= f_read;
+
+        // Handle unfinished business.
+        std::streamsize result = 0;
+        if (!cur_line_.empty() && (result = read_line(s, n)) == n)
+            return n;
+
+        typename traits_type::int_type status = traits_type::good();
+        while (result < n && !traits_type::is_eof(status)) {
+
+            // Call next_line() to retrieve a line of filtered text, and
+            // read_line() to copy it into buffer s.
+            if (traits_type::would_block(status = next_line(src)))
+                return result;
+            result += read_line(s + result, n - result);
+        }
+
+        return detail::check_eof(result);
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        using namespace std;
+        NDNBOOST_ASSERT(!(flags_ & f_read));
+        flags_ |= f_write;
+
+        // Handle unfinished business.
+        if (pos_ != string_type::npos && !write_line(snk))
+            return 0;
+
+        const char_type *cur = s, *next;
+        while (true) {
+
+            // Search for the next full line in [cur, s + n), filter it
+            // and write it to snk.
+            typename string_type::size_type rest = n - (cur - s);
+            if ((next = traits_type::find(cur, rest, traits_type::newline()))) {
+                cur_line_.append(cur, next - cur);
+                cur = next + 1;
+                if (!write_line(snk))
+                    return static_cast<std::streamsize>(cur - s);
+            } else {
+                cur_line_.append(cur, rest);
+                return n;
+            }
+        }
+    }
+
+    template<typename Sink>
+    void close(Sink& snk, NDNBOOST_IOS::openmode which)
+    {
+        if ((flags_ & f_read) && which == NDNBOOST_IOS::in)
+            close_impl();
+
+        if ((flags_ & f_write) && which == NDNBOOST_IOS::out) {
+            try {
+                if (!cur_line_.empty())
+                    write_line(snk);
+            } catch (...) {
+                try {
+                    close_impl();
+                } catch (...) { }
+                throw;
+            }
+            close_impl();
+        }
+    }
+private:
+    virtual string_type do_filter(const string_type& line) = 0;
+
+    // Copies filtered characters fron the current line into
+    // the given buffer.
+    std::streamsize read_line(char_type* s, std::streamsize n)
+    {
+        using namespace std;
+        std::streamsize result =
+            (std::min) (n, static_cast<std::streamsize>(cur_line_.size()));
+        traits_type::copy(s, cur_line_.data(), result);
+        cur_line_.erase(0, result);
+        return result;
+    }
+
+    // Attempts to retrieve a line of text from the given source; returns
+    // an int_type as a good/eof/would_block status code.
+    template<typename Source>
+    typename traits_type::int_type next_line(Source& src)
+    {
+        using namespace std;
+        typename traits_type::int_type c;
+        while ( traits_type::is_good(c = iostreams::get(src)) &&
+                c != traits_type::newline() )
+        {
+            cur_line_ += traits_type::to_int_type(c);
+        }
+        if (!traits_type::would_block(c)) {
+            if (!cur_line_.empty() || c == traits_type::newline())
+                cur_line_ = do_filter(cur_line_);
+            if (c == traits_type::newline() && (flags_ & f_suppress) == 0)
+                cur_line_ += c;
+        }
+        return c; // status indicator.
+    }
+
+    // Filters the current line and attemps to write it to the given sink.
+    // Returns true for success.
+    template<typename Sink>
+    bool write_line(Sink& snk)
+    {
+        string_type line = do_filter(cur_line_);
+        if ((flags_ & f_suppress) == 0)
+            line += traits_type::newline();
+        std::streamsize amt = static_cast<std::streamsize>(line.size());
+        bool result = iostreams::write_if(snk, line.data(), amt) == amt;
+        if (result)
+            clear();
+        return result;
+    }
+
+    void close_impl()
+    {
+        clear();
+        flags_ &= f_suppress;
+    }
+
+    void clear()
+    {
+        cur_line_.erase();
+        pos_ = string_type::npos;
+    }
+
+    enum flag_type {
+        f_read      = 1,
+        f_write     = f_read << 1,
+        f_suppress  = f_write << 1
+    };
+
+    string_type                      cur_line_;
+    typename string_type::size_type  pos_;
+    int                              flags_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_line_filter, 2)
+
+typedef basic_line_filter<char>     line_filter;
+typedef basic_line_filter<wchar_t>  wline_filter;
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/newline.hpp b/include/ndnboost/iostreams/filter/newline.hpp
new file mode 100644
index 0000000..f47a5ef
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/newline.hpp
@@ -0,0 +1,442 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// NOTE: I hope to replace the current implementation with a much simpler
+// one.
+
+#ifndef NDNBOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/assert.hpp>
+#include <cstdio>
+#include <stdexcept>                       // logic_error.
+#include <ndnboost/config.hpp>                // NDNBOOST_STATIC_CONSTANT.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // NDNBOOST_IOSTREAMS_FAILURE 
+#include <ndnboost/iostreams/read.hpp>        // get 
+#include <ndnboost/iostreams/write.hpp>       // put 
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/iostreams/putback.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+#define NDNBOOST_IOSTREAMS_ASSERT_UNREACHABLE(val) \
+    (NDNBOOST_ASSERT("unreachable code" == 0), val) \
+    /**/
+
+namespace ndnboost { namespace iostreams {
+
+namespace newline {
+
+const char CR                   = 0x0D;
+const char LF                   = 0x0A;
+
+    // Flags for configuring newline_filter.
+
+// Exactly one of the following three flags must be present.
+
+const int posix             = 1;    // Use CR as line separator.
+const int mac               = 2;    // Use LF as line separator.
+const int dos               = 4;    // Use CRLF as line separator.
+const int mixed             = 8;    // Mixed line endings.
+const int final_newline     = 16;
+const int platform_mask     = posix | dos | mac;
+
+} // End namespace newline.
+
+namespace detail {
+
+class newline_base {
+public:
+    bool is_posix() const
+    {
+        return !is_mixed() && (flags_ & newline::posix) != 0;
+    }
+    bool is_dos() const
+    {
+        return !is_mixed() && (flags_ & newline::dos) != 0;
+    }
+    bool is_mac() const
+    {
+        return !is_mixed() && (flags_ & newline::mac) != 0;
+    }
+    bool is_mixed_posix() const { return (flags_ & newline::posix) != 0; }
+    bool is_mixed_dos() const { return (flags_ & newline::dos) != 0; }
+    bool is_mixed_mac() const { return (flags_ & newline::mac) != 0; }
+    bool is_mixed() const
+    {
+        int platform =
+            (flags_ & newline::posix) != 0 ?
+                newline::posix :
+                (flags_ & newline::dos) != 0 ?
+                    newline::dos :
+                    (flags_ & newline::mac) != 0 ?
+                        newline::mac :
+                        0;
+        return (flags_ & ~platform & newline::platform_mask) != 0;
+    }
+    bool has_final_newline() const
+    {
+        return (flags_ & newline::final_newline) != 0;
+    }
+protected:
+    newline_base(int flags) : flags_(flags) { }
+    int flags_;
+};
+
+} // End namespace detail.
+
+class newline_error
+    : public NDNBOOST_IOSTREAMS_FAILURE, public detail::newline_base
+{
+private:
+    friend class newline_checker;
+    newline_error(int flags)
+        : NDNBOOST_IOSTREAMS_FAILURE("bad line endings"),
+          detail::newline_base(flags)
+        { }
+};
+
+class newline_filter {
+public:
+    typedef char char_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          closable_tag
+        { };
+
+    explicit newline_filter(int target) : flags_(target)
+    {
+        if ( target != iostreams::newline::posix &&
+             target != iostreams::newline::dos &&
+             target != iostreams::newline::mac )
+        {
+            ndnboost::throw_exception(std::logic_error("bad flags"));
+        }
+    }
+
+    template<typename Source>
+    int get(Source& src)
+    {
+        using iostreams::newline::CR;
+        using iostreams::newline::LF;
+
+        NDNBOOST_ASSERT((flags_ & f_write) == 0);
+        flags_ |= f_read;
+
+        if (flags_ & (f_has_LF | f_has_EOF)) {
+            if (flags_ & f_has_LF)
+                return newline();
+            else
+                return EOF;
+        }
+
+        int c =
+            (flags_ & f_has_CR) == 0 ?
+                iostreams::get(src) :
+                CR;
+
+        if (c == WOULD_BLOCK )
+            return WOULD_BLOCK;
+
+        if (c == CR) {
+            flags_ |= f_has_CR;
+
+            int d;
+            if ((d = iostreams::get(src)) == WOULD_BLOCK)
+                return WOULD_BLOCK;
+
+            if (d == LF) {
+                flags_ &= ~f_has_CR;
+                return newline();
+            }
+
+            if (d == EOF) {
+                flags_ |= f_has_EOF;
+            } else {
+                iostreams::putback(src, d);
+            }
+
+            flags_ &= ~f_has_CR;
+            return newline();
+        }
+
+        if (c == LF)
+            return newline();
+
+        return c;
+    }
+
+    template<typename Sink>
+    bool put(Sink& dest, char c)
+    {
+        using iostreams::newline::CR;
+        using iostreams::newline::LF;
+
+        NDNBOOST_ASSERT((flags_ & f_read) == 0);
+        flags_ |= f_write;
+
+        if ((flags_ & f_has_LF) != 0)
+            return c == LF ?
+                newline(dest) :
+                newline(dest) && this->put(dest, c);
+
+        if (c == LF)
+           return newline(dest);
+
+        if ((flags_ & f_has_CR) != 0)
+            return newline(dest) ?
+                this->put(dest, c) :
+                false;
+
+        if (c == CR) {
+            flags_ |= f_has_CR;
+            return true;
+        }
+
+        return iostreams::put(dest, c);
+    }
+
+    template<typename Sink>
+    void close(Sink& dest, NDNBOOST_IOS::openmode)
+    {
+        typedef typename iostreams::category_of<Sink>::type category;
+        if ((flags_ & f_write) != 0 && (flags_ & f_has_CR) != 0)
+            newline_if_sink(dest);
+        flags_ &= ~f_has_LF; // Restore original flags.
+    }
+private:
+
+    // Returns the appropriate element of a newline sequence.
+    int newline()
+    {
+        using iostreams::newline::CR;
+        using iostreams::newline::LF;
+
+        switch (flags_ & iostreams::newline::platform_mask) {
+        case iostreams::newline::posix:
+            return LF;
+        case iostreams::newline::mac:
+            return CR;
+        case iostreams::newline::dos:
+            if (flags_ & f_has_LF) {
+                flags_ &= ~f_has_LF;
+                return LF;
+            } else {
+                flags_ |= f_has_LF;
+                return CR;
+            }
+        }
+        return NDNBOOST_IOSTREAMS_ASSERT_UNREACHABLE(0);
+    }
+
+    // Writes a newline sequence.
+    template<typename Sink>
+    bool newline(Sink& dest)
+    {
+        using iostreams::newline::CR;
+        using iostreams::newline::LF;
+
+        bool success = false;
+        switch (flags_ & iostreams::newline::platform_mask) {
+        case iostreams::newline::posix:
+            success = ndnboost::iostreams::put(dest, LF);
+            break;
+        case iostreams::newline::mac:
+            success = ndnboost::iostreams::put(dest, CR);
+            break;
+        case iostreams::newline::dos:
+            if ((flags_ & f_has_LF) != 0) {
+                if ((success = ndnboost::iostreams::put(dest, LF)))
+                    flags_ &= ~f_has_LF;
+            } else if (ndnboost::iostreams::put(dest, CR)) {
+                if (!(success = ndnboost::iostreams::put(dest, LF)))
+                    flags_ |= f_has_LF;
+            }
+            break;
+        }
+        if (success)
+            flags_ &= ~f_has_CR;
+        return success;
+    }
+
+    // Writes a newline sequence if the given device is a Sink.
+    template<typename Device>
+    void newline_if_sink(Device& dest) 
+    { 
+        typedef typename iostreams::category_of<Device>::type category;
+        newline_if_sink(dest, is_convertible<category, output>()); 
+    }
+
+    template<typename Sink>
+    void newline_if_sink(Sink& dest, mpl::true_) { newline(dest); }
+
+    template<typename Source>
+    void newline_if_sink(Source&, mpl::false_) { }
+
+    enum flags {
+        f_has_LF         = 32768,
+        f_has_CR         = f_has_LF << 1,
+        f_has_newline    = f_has_CR << 1,
+        f_has_EOF        = f_has_newline << 1,
+        f_read           = f_has_EOF << 1,
+        f_write          = f_read << 1
+    };
+    int       flags_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(newline_filter, 0)
+
+class newline_checker : public detail::newline_base {
+public:
+    typedef char                 char_type;
+    struct category
+        : dual_use_filter_tag,
+          closable_tag
+        { };
+    explicit newline_checker(int target = newline::mixed)
+        : detail::newline_base(0), target_(target), open_(false)
+        { }
+    template<typename Source>
+    int get(Source& src)
+    {
+        using newline::CR;
+        using newline::LF;
+
+        if (!open_) {
+            open_ = true;
+            source() = 0;
+        }
+
+        int c;
+        if ((c = iostreams::get(src)) == WOULD_BLOCK)
+            return WOULD_BLOCK;
+
+        // Update source flags.
+        if (c != EOF)
+            source() &= ~f_line_complete;
+        if ((source() & f_has_CR) != 0) {
+            if (c == LF) {
+                source() |= newline::dos;
+                source() |= f_line_complete;
+            } else {
+                source() |= newline::mac;
+                if (c == EOF)
+                    source() |= f_line_complete;
+            }
+        } else if (c == LF) {
+            source() |= newline::posix;
+            source() |= f_line_complete;
+        }
+        source() = (source() & ~f_has_CR) | (c == CR ? f_has_CR : 0);
+
+        // Check for errors.
+        if ( c == EOF &&
+            (target_ & newline::final_newline) != 0 &&
+            (source() & f_line_complete) == 0 )
+        {
+            fail();
+        }
+        if ( (target_ & newline::platform_mask) != 0 &&
+             (source() & ~target_ & newline::platform_mask) != 0 )
+        {
+            fail();
+        }
+
+        return c;
+    }
+
+    template<typename Sink>
+    bool put(Sink& dest, int c)
+    {
+        using iostreams::newline::CR;
+        using iostreams::newline::LF;
+
+        if (!open_) {
+            open_ = true;
+            source() = 0;
+        }
+
+        if (!iostreams::put(dest, c))
+            return false;
+
+         // Update source flags.
+        source() &= ~f_line_complete;
+        if ((source() & f_has_CR) != 0) {
+            if (c == LF) {
+                source() |= newline::dos;
+                source() |= f_line_complete;
+            } else {
+                source() |= newline::mac;
+            }
+        } else if (c == LF) {
+            source() |= newline::posix;
+            source() |= f_line_complete;
+        }
+        source() = (source() & ~f_has_CR) | (c == CR ? f_has_CR : 0);
+
+        // Check for errors.
+        if ( (target_ & newline::platform_mask) != 0 &&
+             (source() & ~target_ & newline::platform_mask) != 0 )
+        {
+            fail();
+        }
+
+        return true;
+    }
+
+    template<typename Sink>
+    void close(Sink&, NDNBOOST_IOS::openmode)
+    {
+        using iostreams::newline::final_newline;
+
+        // Update final_newline flag.
+        if ( (source() & f_has_CR) != 0 ||
+             (source() & f_line_complete) != 0 )
+        {
+            source() |= final_newline;
+        }
+
+        // Clear non-sticky flags.
+        source() &= ~(f_has_CR | f_line_complete);
+
+        // Check for errors.
+        if ( (target_ & final_newline) != 0 &&
+             (source() & final_newline) == 0 )
+        {
+            fail();
+        }
+    }
+private:
+    void fail() { ndnboost::throw_exception(newline_error(source())); }
+    int& source() { return flags_; }
+    int source() const { return flags_; }
+
+    enum flags {
+        f_has_CR = 32768,
+        f_line_complete = f_has_CR << 1
+    };
+
+    int   target_;  // Represents expected input.
+    bool  open_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(newline_checker, 0)
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/regex.hpp b/include/ndnboost/iostreams/filter/regex.hpp
new file mode 100644
index 0000000..3bc599a
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/regex.hpp
@@ -0,0 +1,98 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <memory>                         // allocator.
+#include <ndnboost/function.hpp>        
+#include <ndnboost/iostreams/filter/aggregate.hpp>              
+#include <ndnboost/iostreams/pipeline.hpp>                
+#include <ndnboost/regex.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template< typename Ch,
+          typename Tr = regex_traits<Ch>,
+          typename Alloc = std::allocator<Ch> >
+class basic_regex_filter : public aggregate_filter<Ch, Alloc> {
+private:
+    typedef aggregate_filter<Ch, Alloc>                 base_type;
+public:
+    typedef typename base_type::char_type              char_type;
+    typedef typename base_type::category               category;
+    typedef std::basic_string<Ch>                      string_type;
+    typedef basic_regex<Ch, Tr>                        regex_type;
+    typedef regex_constants::match_flag_type           flag_type;
+    typedef match_results<const Ch*>                   match_type;
+    typedef function1<string_type, const match_type&>  formatter;
+
+    basic_regex_filter( const regex_type& re,
+                        const formatter& replace,
+                        flag_type flags = regex_constants::match_default )
+        : re_(re), replace_(replace), flags_(flags) { }
+    basic_regex_filter( const regex_type& re,
+                        const string_type& fmt,
+                        flag_type flags = regex_constants::match_default,
+                        flag_type fmt_flags = regex_constants::format_default )
+        : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
+    basic_regex_filter( const regex_type& re,
+                        const char_type* fmt,
+                        flag_type flags = regex_constants::match_default,
+                        flag_type fmt_flags = regex_constants::format_default )
+        : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
+private:
+    typedef typename base_type::vector_type       vector_type;
+    void do_filter(const vector_type& src, vector_type& dest)
+        {
+            typedef regex_iterator<const Ch*, Ch, Tr> iterator;
+            if (src.empty())
+                return;
+            iterator first(&src[0], &src[0] + src.size(), re_, flags_);
+            iterator last;
+            const Ch* suffix = 0;
+            for (; first != last; ++first) {
+                dest.insert( dest.end(), 
+                             first->prefix().first,
+                             first->prefix().second );
+                string_type replacement = replace_(*first);
+                dest.insert( dest.end(), 
+                             replacement.begin(),
+                             replacement.end() );
+                suffix = first->suffix().first;
+            }
+            if (suffix) {
+                dest.insert(dest.end(), suffix, &src[0] + src.size());
+            } else {
+                dest.insert(dest.end(), &src[0], &src[0] + src.size());
+            }
+        }
+    struct simple_formatter {
+        simple_formatter(const string_type& fmt, flag_type fmt_flags) 
+            : fmt_(fmt), fmt_flags_(fmt_flags) { }
+        string_type operator() (const match_type& match) const
+        { return match.format(fmt_, fmt_flags_); }
+        string_type  fmt_;
+        flag_type    fmt_flags_;
+    };
+    regex_type  re_;
+    formatter   replace_;
+    flag_type   flags_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3)
+
+typedef basic_regex_filter<char>     regex_filter;
+typedef basic_regex_filter<wchar_t>  wregex_filter;
+
+
+} } // End namespaces iostreams, boost.
+
+#endif      // #ifndef NDNBOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/stdio.hpp b/include/ndnboost/iostreams/filter/stdio.hpp
new file mode 100644
index 0000000..33e8426
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/stdio.hpp
@@ -0,0 +1,84 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Based on the work of Christopher Diggins.
+
+#ifndef NDNBOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <iostream>
+#include <memory>    // allocator.
+#include <vector>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>
+#include <ndnboost/iostreams/device/array.hpp>
+#include <ndnboost/iostreams/device/back_inserter.hpp>
+#include <ndnboost/iostreams/filter/aggregate.hpp>
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/iostreams/stream_buffer.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+} // End namespace detail.
+
+template<typename Ch, typename Alloc = std::allocator<Ch> >
+class basic_stdio_filter : public aggregate_filter<Ch, Alloc> {
+private:
+    typedef aggregate_filter<Ch, Alloc>       base_type;
+public:
+    typedef typename base_type::char_type    char_type;
+    typedef typename base_type::category     category;
+    typedef typename base_type::vector_type  vector_type;
+private:
+    static std::istream& standard_input(char*) { return std::cin; }
+    static std::ostream& standard_output(char*) { return std::cout; }
+#ifndef NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+    static std::wistream& standard_input(wchar_t*) { return std::wcin; }
+    static std::wostream& standard_output(wchar_t*) { return std::wcout; }
+#endif // NDNBOOST_IOSTREAMS_NO_WIDE_STREAMS
+
+    struct scoped_redirector { // Thanks to Maxim Egorushkin.
+        typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(Ch)                  traits_type;
+        typedef NDNBOOST_IOSTREAMS_BASIC_IOS(Ch, traits_type)       ios_type;
+        typedef NDNBOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, traits_type) streambuf_type;
+        scoped_redirector( ios_type& ios,
+                           streambuf_type* newbuf )
+            : ios_(ios), old_(ios.rdbuf(newbuf))
+            { }
+        ~scoped_redirector() { ios_.rdbuf(old_); }
+        scoped_redirector& operator=(const scoped_redirector&);
+        ios_type&        ios_;
+        streambuf_type*  old_;
+    };
+
+    virtual void do_filter() = 0;
+    virtual void do_filter(const vector_type& src, vector_type& dest)
+    {
+        stream_buffer< basic_array_source<Ch> >
+                          srcbuf(&src[0], &src[0] + src.size());
+        stream_buffer< back_insert_device<vector_type> >
+                          destbuf(iostreams::back_inserter(dest));
+        scoped_redirector redirect_input(standard_input((Ch*)0), &srcbuf);
+        scoped_redirector redirect_output(standard_output((Ch*)0), &destbuf);
+        do_filter();
+    }
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_stdio_filter, 2)
+
+typedef basic_stdio_filter<char>     stdio_filter;
+typedef basic_stdio_filter<wchar_t>  wstdio_wfilter;
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/symmetric.hpp b/include/ndnboost/iostreams/filter/symmetric.hpp
new file mode 100644
index 0000000..9c59900
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/symmetric.hpp
@@ -0,0 +1,310 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Contains the definitions of the class templates symmetric_filter,
+// which models DualUseFilter based on a model of the Symmetric Filter.
+
+//
+// Roughly, a Symmetric Filter is a class type with the following interface:
+//
+//   struct symmetric_filter {
+//       typedef xxx char_type;
+//
+//       bool filter( const char*& begin_in, const char* end_in,
+//                    char*& begin_out, char* end_out, bool flush )
+//       {
+//          // Consume as many characters as possible from the interval
+//          // [begin_in, end_in), without exhausting the output range
+//          // [begin_out, end_out). If flush is true, write as mush output
+//          // as possible. 
+//          // A return value of true indicates that filter should be called 
+//          // again. More precisely, if flush is false, a return value of 
+//          // false indicates that the natural end of stream has been reached
+//          // and that all filtered data has been forwarded; if flush is
+//          // true, a return value of false indicates that all filtered data 
+//          // has been forwarded.
+//       }
+//       void close() { /* Reset filter's state. */ }
+//   };
+//
+// Symmetric Filter filters need not be CopyConstructable.
+//
+
+#ifndef NDNBOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/assert.hpp>
+#include <memory>                               // allocator, auto_ptr.
+#include <ndnboost/config.hpp>                     // NDNBOOST_DEDUCED_TYPENAME.
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/constants.hpp>        // buffer size.
+#include <ndnboost/iostreams/detail/buffer.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/config/limits.hpp>
+#include <ndnboost/iostreams/detail/template_params.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/iostreams/operations.hpp>       // read, write.
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/preprocessor/iteration/local.hpp>
+#include <ndnboost/preprocessor/punctuation/comma_if.hpp>
+#include <ndnboost/preprocessor/repetition/enum_binary_params.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+#include <ndnboost/shared_ptr.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+template< typename SymmetricFilter,
+          typename Alloc =
+              std::allocator<
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<SymmetricFilter>::type
+              > >
+class symmetric_filter {
+public:
+    typedef typename char_type_of<SymmetricFilter>::type      char_type;
+    typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)            traits_type;
+    typedef std::basic_string<char_type, traits_type, Alloc>  string_type;
+    struct category
+        : dual_use,
+          filter_tag,
+          multichar_tag,
+          closable_tag
+        { };
+
+    // Expands to a sequence of ctors which forward to impl.
+    #define NDNBOOST_PP_LOCAL_MACRO(n) \
+        NDNBOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \
+        explicit symmetric_filter( \
+              int buffer_size NDNBOOST_PP_COMMA_IF(n) \
+              NDNBOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \
+            : pimpl_(new impl(buffer_size NDNBOOST_PP_COMMA_IF(n) \
+                     NDNBOOST_PP_ENUM_PARAMS(n, t))) \
+            { NDNBOOST_ASSERT(buffer_size > 0); } \
+        /**/
+    #define NDNBOOST_PP_LOCAL_LIMITS (0, NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
+    #include NDNBOOST_PP_LOCAL_ITERATE()
+    #undef NDNBOOST_PP_LOCAL_MACRO
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        using namespace std;
+        if (!(state() & f_read))
+            begin_read();
+
+        buffer_type&  buf = pimpl_->buf_;
+        int           status = (state() & f_eof) != 0 ? f_eof : f_good;
+        char_type    *next_s = s,
+                     *end_s = s + n;
+        while (true)
+        {
+            // Invoke filter if there are unconsumed characters in buffer or if
+            // filter must be flushed.
+            bool flush = status == f_eof;
+            if (buf.ptr() != buf.eptr() || flush) {
+                const char_type* next = buf.ptr();
+                bool done =
+                    !filter().filter(next, buf.eptr(), next_s, end_s, flush);
+                buf.ptr() = buf.data() + (next - buf.data());
+                if (done)
+                    return detail::check_eof(
+                               static_cast<std::streamsize>(next_s - s)
+                           );
+            }
+
+            // If no more characters are available without blocking, or
+            // if read request has been satisfied, return.
+            if ( (status == f_would_block && buf.ptr() == buf.eptr()) ||
+                 next_s == end_s )
+            {
+                return static_cast<std::streamsize>(next_s - s);
+            }
+
+            // Fill buffer.
+            if (status == f_good)
+                status = fill(src);
+        }
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        if (!(state() & f_write))
+            begin_write();
+
+        buffer_type&     buf = pimpl_->buf_;
+        const char_type *next_s, *end_s;
+        for (next_s = s, end_s = s + n; next_s != end_s; ) {
+            if (buf.ptr() == buf.eptr() && !flush(snk))
+                break;
+            if(!filter().filter(next_s, end_s, buf.ptr(), buf.eptr(), false)) {
+                flush(snk);
+                break;
+            }
+        }
+        return static_cast<std::streamsize>(next_s - s);
+    }
+
+    template<typename Sink>
+    void close(Sink& snk, NDNBOOST_IOS::openmode mode)
+    {
+        if (mode == NDNBOOST_IOS::out) {
+
+            if (!(state() & f_write))
+                begin_write();
+
+            // Repeatedly invoke filter() with no input.
+            try {
+                buffer_type&     buf = pimpl_->buf_;
+                char_type        dummy;
+                const char_type* end = &dummy;
+                bool             again = true;
+                while (again) {
+                    if (buf.ptr() != buf.eptr())
+                        again = filter().filter( end, end, buf.ptr(),
+                                                 buf.eptr(), true );
+                    flush(snk);
+                }
+            } catch (...) {
+                try { close_impl(); } catch (...) { }
+                throw;
+            }
+            close_impl();
+        } else {
+            close_impl();
+        }
+    }
+    SymmetricFilter& filter() { return *pimpl_; }
+    string_type unconsumed_input() const;
+
+// Give impl access to buffer_type on Tru64
+#if !NDNBOOST_WORKAROUND(__DECCXX_VER, NDNBOOST_TESTED_AT(60590042)) 
+    private:
+#endif
+    typedef detail::buffer<char_type, Alloc> buffer_type;
+private:
+    buffer_type& buf() { return pimpl_->buf_; }
+    const buffer_type& buf() const { return pimpl_->buf_; }
+    int& state() { return pimpl_->state_; }
+    void begin_read();
+    void begin_write();
+
+    template<typename Source>
+    int fill(Source& src)
+    {
+        std::streamsize amt = iostreams::read(src, buf().data(), buf().size());
+        if (amt == -1) {
+            state() |= f_eof;
+            return f_eof;
+        }
+        buf().set(0, amt);
+        return amt != 0 ? f_good : f_would_block;
+    }
+
+    // Attempts to write the contents of the buffer the given Sink.
+    // Returns true if at least on character was written.
+    template<typename Sink>
+    bool flush(Sink& snk)
+    {
+        typedef typename iostreams::category_of<Sink>::type  category;
+        typedef is_convertible<category, output>             can_write;
+        return flush(snk, can_write());
+    }
+
+    template<typename Sink>
+    bool flush(Sink& snk, mpl::true_)
+    {
+        std::streamsize amt =
+            static_cast<std::streamsize>(buf().ptr() - buf().data());
+        std::streamsize result =
+            ndnboost::iostreams::write(snk, buf().data(), amt);
+        if (result < amt && result > 0)
+            traits_type::move(buf().data(), buf().data() + result, amt - result);
+        buf().set(amt - result, buf().size());
+        return result != 0;
+    }
+
+    template<typename Sink>
+    bool flush(Sink&, mpl::false_) { return true;}
+
+    void close_impl();
+
+    enum flag_type {
+        f_read   = 1,
+        f_write  = f_read << 1,
+        f_eof    = f_write << 1,
+        f_good,
+        f_would_block
+    };
+
+    struct impl : SymmetricFilter {
+
+    // Expands to a sequence of ctors which forward to SymmetricFilter.
+    #define NDNBOOST_PP_LOCAL_MACRO(n) \
+        NDNBOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \
+        impl( int buffer_size NDNBOOST_PP_COMMA_IF(n) \
+              NDNBOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \
+            : SymmetricFilter(NDNBOOST_PP_ENUM_PARAMS(n, t)), \
+              buf_(buffer_size), state_(0) \
+            { } \
+        /**/
+    #define NDNBOOST_PP_LOCAL_LIMITS (0, NDNBOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
+    #include NDNBOOST_PP_LOCAL_ITERATE()
+    #undef NDNBOOST_PP_LOCAL_MACRO
+
+        buffer_type  buf_;
+        int          state_;
+    };
+
+    shared_ptr<impl> pimpl_;
+};
+NDNBOOST_IOSTREAMS_PIPABLE(symmetric_filter, 2)
+
+//------------------Implementation of symmetric_filter----------------//
+
+template<typename SymmetricFilter, typename Alloc>
+void symmetric_filter<SymmetricFilter, Alloc>::begin_read()
+{
+    NDNBOOST_ASSERT(!(state() & f_write));
+    state() |= f_read;
+    buf().set(0, 0);
+}
+
+template<typename SymmetricFilter, typename Alloc>
+void symmetric_filter<SymmetricFilter, Alloc>::begin_write()
+{
+    NDNBOOST_ASSERT(!(state() & f_read));
+    state() |= f_write;
+    buf().set(0, buf().size());
+}
+
+template<typename SymmetricFilter, typename Alloc>
+void symmetric_filter<SymmetricFilter, Alloc>::close_impl()
+{
+    state() = 0;
+    buf().set(0, 0);
+    filter().close();
+}
+
+template<typename SymmetricFilter, typename Alloc>
+typename symmetric_filter<SymmetricFilter, Alloc>::string_type
+symmetric_filter<SymmetricFilter, Alloc>::unconsumed_input() const
+{ return string_type(buf().ptr(), buf().eptr()); }
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/test.hpp b/include/ndnboost/iostreams/filter/test.hpp
new file mode 100644
index 0000000..2ad7b5d
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/test.hpp
@@ -0,0 +1,322 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>               // NDNBOOST_MSVC,put size_t in std.
+#include <ndnboost/detail/workaround.hpp>
+#include <algorithm>                      // min.
+#include <cstddef>                        // size_t.
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) || \
+    NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x564)) || \
+    NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
+    /**/
+# include <cstdlib>                       // rand.
+#endif
+#include <cstring>                        // memcpy, strlen.
+#include <iterator>
+#include <string>
+#include <vector>
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) && \
+    !NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x564)) && \
+    !NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
+    /**/
+# include <ndnboost/random/linear_congruential.hpp>
+# include <ndnboost/random/uniform_smallint.hpp>
+#endif
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/compose.hpp>
+#include <ndnboost/iostreams/copy.hpp>
+#include <ndnboost/iostreams/detail/bool_trait_def.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>
+#include <ndnboost/iostreams/device/array.hpp>
+#include <ndnboost/iostreams/device/back_inserter.hpp>
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/type_traits/is_array.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+#undef memcpy
+#undef rand
+#undef strlen
+
+#if defined(NDNBOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__)
+namespace std { 
+    using ::memcpy; 
+    using ::strlen; 
+    #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) || \
+        NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x564)) || \
+        NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
+        /**/
+        using ::rand; 
+    #endif
+}
+#endif
+
+namespace ndnboost { namespace iostreams {
+
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_string, std::basic_string, 3)
+
+const std::streamsize default_increment = 5;
+
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) && \
+    !NDNBOOST_WORKAROUND(__BORLANDC__, NDNBOOST_TESTED_AT(0x564)) && \
+    !NDNBOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
+    /**/
+    std::streamsize rand(int inc)
+    {
+        static rand48                random_gen;
+        static uniform_smallint<int> random_dist(0, inc);
+        return random_dist(random_gen);
+    }
+#else
+    std::streamsize rand(int inc) 
+    { 
+        return (std::rand() * inc + 1) / RAND_MAX; 
+    }
+#endif
+
+class non_blocking_source {
+public:
+    typedef char char_type;
+    struct category
+        : source_tag,
+          peekable_tag
+        { };
+    explicit non_blocking_source( const std::string& data, 
+                                  std::streamsize inc = default_increment ) 
+        : data_(data), inc_(inc), pos_(0)
+        { }
+    std::streamsize read(char* s, std::streamsize n)
+    {
+        if (pos_ == static_cast<std::streamsize>(data_.size()))
+            return -1;
+        std::streamsize avail = 
+            (std::min) (n, static_cast<std::streamsize>(data_.size() - pos_));
+        std::streamsize amt = (std::min) (rand(inc_), avail);
+        if (amt)
+            std::memcpy(s, data_.c_str() + pos_, amt);
+        pos_ += amt;
+        return amt;
+    }
+
+    bool putback(char c)
+    {
+        if (pos_ > 0) {
+            data_[--pos_] = c;
+            return true;
+        }
+        return false;
+    }
+private:
+    std::string      data_;
+    std::streamsize  inc_, pos_;
+};
+
+class non_blocking_sink : public sink {
+public:
+    non_blocking_sink( std::string& dest,
+                       std::streamsize inc = default_increment ) 
+        : dest_(dest), inc_(inc) 
+        { }
+    std::streamsize write(const char* s, std::streamsize n)
+    {
+        std::streamsize amt = (std::min) (rand(inc_), n);
+        dest_.insert(dest_.end(), s, s + amt);
+        return amt;
+    }
+private:
+    non_blocking_sink& operator=(const non_blocking_sink&);
+    std::string&     dest_;
+    std::streamsize  inc_;
+};
+                
+//--------------Definition of test_input_filter-------------------------------//
+
+template<typename Filter>
+bool test_input_filter( Filter filter, 
+                        const std::string& input, 
+                        const std::string& output, 
+                        mpl::true_ )
+{
+    for ( int inc = default_increment; 
+          inc < default_increment * 40; 
+          inc += default_increment )
+    {
+        non_blocking_source  src(input, inc);
+        std::string          dest;
+        iostreams::copy(compose(filter, src), iostreams::back_inserter(dest));
+        if (dest != output)
+            return false;
+    }
+    return true;
+}
+
+template<typename Filter, typename Source1, typename Source2>
+bool test_input_filter( Filter filter, 
+                        const Source1& input, 
+                        const Source2& output, 
+                        mpl::false_ )
+{
+    std::string in;
+    std::string out;
+    iostreams::copy(input, iostreams::back_inserter(in));
+    iostreams::copy(output, iostreams::back_inserter(out));
+    return test_input_filter(filter, in, out);
+}
+
+template<typename Filter, typename Source1, typename Source2>
+bool test_input_filter( Filter filter, 
+                        const Source1& input, 
+                        const Source2& output )
+{
+    // Use tag dispatch to compensate for bad overload resolution.
+    return test_input_filter( filter, input, output,    
+                              is_string<Source1>() );
+}
+
+//--------------Definition of test_output_filter------------------------------//
+
+template<typename Filter>
+bool test_output_filter( Filter filter, 
+                         const std::string& input, 
+                         const std::string& output, 
+                         mpl::true_ )
+{
+    for ( int inc = default_increment; 
+          inc < default_increment * 40; 
+          inc += default_increment )
+    {
+        array_source  src(input.data(), input.data() + input.size());
+        std::string   dest;
+        iostreams::copy(src, compose(filter, non_blocking_sink(dest, inc)));
+        if (dest != output )
+            return false;
+    }
+    return true;
+}
+
+template<typename Filter, typename Source1, typename Source2>
+bool test_output_filter( Filter filter, 
+                         const Source1& input, 
+                         const Source2& output, 
+                         mpl::false_ )
+{
+    std::string in;
+    std::string out;
+    iostreams::copy(input, iostreams::back_inserter(in));
+    iostreams::copy(output, iostreams::back_inserter(out));
+    return test_output_filter(filter, in, out);
+}
+
+template<typename Filter, typename Source1, typename Source2>
+bool test_output_filter( Filter filter, 
+                         const Source1& input, 
+                         const Source2& output )
+{
+    // Use tag dispatch to compensate for bad overload resolution.
+    return test_output_filter( filter, input, output,    
+                               is_string<Source1>() );
+}
+
+//--------------Definition of test_filter_pair--------------------------------//
+
+template<typename OutputFilter, typename InputFilter>
+bool test_filter_pair( OutputFilter out, 
+                       InputFilter in, 
+                       const std::string& data, 
+                       mpl::true_ )
+{
+    for ( int inc = default_increment; 
+          inc <= default_increment * 40; 
+          inc += default_increment )
+    {
+        {
+            array_source  src(data.data(), data.data() + data.size());
+            std::string   temp;
+            std::string   dest;
+            iostreams::copy(src, compose(out, non_blocking_sink(temp, inc)));
+            iostreams::copy( 
+                compose(in, non_blocking_source(temp, inc)),
+                iostreams::back_inserter(dest)
+            );
+            if (dest != data)
+                return false;
+        }
+        {
+            array_source  src(data.data(), data.data() + data.size());
+            std::string   temp;
+            std::string   dest;
+            iostreams::copy(src, compose(out, non_blocking_sink(temp, inc)));
+            // truncate the file, this should not loop, it may throw
+            // std::ios_base::failure, which we swallow.
+            try {
+                temp.resize(temp.size() / 2);
+                iostreams::copy( 
+                    compose(in, non_blocking_source(temp, inc)),
+                    iostreams::back_inserter(dest)
+                );
+            } catch(std::ios_base::failure&) {}
+        }
+        {
+            array_source  src(data.data(), data.data() + data.size());
+            std::string   temp;
+            std::string   dest;
+            iostreams::copy(compose(out, src), non_blocking_sink(temp, inc));
+            iostreams::copy( 
+                non_blocking_source(temp, inc),
+                compose(in, iostreams::back_inserter(dest))
+            );
+            if (dest != data)
+                return false;
+        }
+        {
+            array_source  src(data.data(), data.data() + data.size());
+            std::string   temp;
+            std::string   dest;
+            iostreams::copy(compose(out, src), non_blocking_sink(temp, inc));
+            // truncate the file, this should not loop, it may throw
+            // std::ios_base::failure, which we swallow.
+            try {
+                temp.resize(temp.size() / 2);
+                iostreams::copy( 
+                    non_blocking_source(temp, inc),
+                    compose(in, iostreams::back_inserter(dest))
+                );
+            } catch(std::ios_base::failure&) {}
+        }
+    }
+    return true;
+}
+
+template<typename OutputFilter, typename InputFilter, typename Source>
+bool test_filter_pair( OutputFilter out, 
+                       InputFilter in, 
+                       const Source& data, 
+                       mpl::false_ )
+{
+    std::string str;
+    iostreams::copy(data, iostreams::back_inserter(str));
+    return test_filter_pair(out, in, str);
+}
+
+template<typename OutputFilter, typename InputFilter, typename Source>
+bool test_filter_pair( OutputFilter out, 
+                       InputFilter in, 
+                       const Source& data )
+{
+    // Use tag dispatch to compensate for bad overload resolution.
+    return test_filter_pair(out, in, data, is_string<Source>());
+}
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filter/zlib.hpp b/include/ndnboost/iostreams/filter/zlib.hpp
new file mode 100644
index 0000000..6c5ed39
--- /dev/null
+++ b/include/ndnboost/iostreams/filter/zlib.hpp
@@ -0,0 +1,427 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Note: custom allocators are not supported on VC6, since that compiler
+// had trouble finding the function zlib_base::do_init.
+
+#ifndef NDNBOOST_IOSTREAMS_ZLIB_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_ZLIB_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <cassert>                            
+#include <iosfwd>            // streamsize.                 
+#include <memory>            // allocator, bad_alloc.
+#include <new>          
+#include <ndnboost/config.hpp>  // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM.
+#include <ndnboost/cstdint.hpp> // uint*_t
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/constants.hpp>   // buffer size.
+#include <ndnboost/iostreams/detail/config/auto_link.hpp>
+#include <ndnboost/iostreams/detail/config/dyn_link.hpp>
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/config/zlib.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // failure, streamsize.
+#include <ndnboost/iostreams/filter/symmetric.hpp>                
+#include <ndnboost/iostreams/pipeline.hpp>                
+#include <ndnboost/type_traits/is_same.hpp>
+
+// Must come last.
+#ifdef NDNBOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:4251 4231 4660)         // Dependencies not exported.
+#endif
+#include <ndnboost/config/abi_prefix.hpp>           
+
+namespace ndnboost { namespace iostreams {
+
+namespace zlib {
+                    // Typedefs
+
+typedef uint32_t uint;
+typedef uint8_t byte;
+typedef uint32_t ulong;
+
+// Prefix 'x' prevents symbols from being redefined when Z_PREFIX is defined
+typedef void* (*xalloc_func)(void*, zlib::uint, zlib::uint);
+typedef void (*xfree_func)(void*, void*);
+
+                    // Compression levels
+
+NDNBOOST_IOSTREAMS_DECL extern const int no_compression;
+NDNBOOST_IOSTREAMS_DECL extern const int best_speed;
+NDNBOOST_IOSTREAMS_DECL extern const int best_compression;
+NDNBOOST_IOSTREAMS_DECL extern const int default_compression;
+
+                    // Compression methods
+
+NDNBOOST_IOSTREAMS_DECL extern const int deflated;
+
+                    // Compression strategies
+
+NDNBOOST_IOSTREAMS_DECL extern const int default_strategy;
+NDNBOOST_IOSTREAMS_DECL extern const int filtered;
+NDNBOOST_IOSTREAMS_DECL extern const int huffman_only;
+
+                    // Status codes
+
+NDNBOOST_IOSTREAMS_DECL extern const int okay;
+NDNBOOST_IOSTREAMS_DECL extern const int stream_end;
+NDNBOOST_IOSTREAMS_DECL extern const int stream_error;
+NDNBOOST_IOSTREAMS_DECL extern const int version_error;
+NDNBOOST_IOSTREAMS_DECL extern const int data_error;
+NDNBOOST_IOSTREAMS_DECL extern const int mem_error;
+NDNBOOST_IOSTREAMS_DECL extern const int buf_error;
+
+                    // Flush codes
+
+NDNBOOST_IOSTREAMS_DECL extern const int finish;
+NDNBOOST_IOSTREAMS_DECL extern const int no_flush;
+NDNBOOST_IOSTREAMS_DECL extern const int sync_flush;
+
+                    // Code for current OS
+
+//NDNBOOST_IOSTREAMS_DECL extern const int os_code;
+
+                    // Null pointer constant.
+
+const int null                               = 0;
+
+                    // Default values
+
+const int default_window_bits                = 15;
+const int default_mem_level                  = 8;
+const bool default_crc                       = false;
+const bool default_noheader                  = false;
+
+} // End namespace zlib. 
+
+//
+// Class name: zlib_params.
+// Description: Encapsulates the parameters passed to deflateInit2
+//      and inflateInit2 to customize compression and decompression.
+//
+struct zlib_params {
+
+    // Non-explicit constructor.
+    zlib_params( int level           = zlib::default_compression,
+                 int method          = zlib::deflated,
+                 int window_bits     = zlib::default_window_bits, 
+                 int mem_level       = zlib::default_mem_level, 
+                 int strategy        = zlib::default_strategy,
+                 bool noheader       = zlib::default_noheader,
+                 bool calculate_crc  = zlib::default_crc )
+        : level(level), method(method), window_bits(window_bits),
+          mem_level(mem_level), strategy(strategy),  
+          noheader(noheader), calculate_crc(calculate_crc)
+        { }
+    int level;
+    int method;
+    int window_bits;
+    int mem_level;
+    int strategy;
+    bool noheader;
+    bool calculate_crc;
+};
+
+//
+// Class name: zlib_error.
+// Description: Subclass of std::ios::failure thrown to indicate
+//     zlib errors other than out-of-memory conditions.
+//
+class NDNBOOST_IOSTREAMS_DECL zlib_error : public NDNBOOST_IOSTREAMS_FAILURE {
+public:
+    explicit zlib_error(int error);
+    int error() const { return error_; }
+    static void check NDNBOOST_PREVENT_MACRO_SUBSTITUTION(int error);
+private:
+    int error_;
+};
+
+namespace detail {
+
+template<typename Alloc>
+struct zlib_allocator_traits {
+#ifndef NDNBOOST_NO_STD_ALLOCATOR
+    typedef typename Alloc::template rebind<char>::other type;
+#else
+    typedef std::allocator<char> type;
+#endif
+};
+
+template< typename Alloc,
+          typename Base = // VC6 workaround (C2516)
+              NDNBOOST_DEDUCED_TYPENAME zlib_allocator_traits<Alloc>::type >
+struct zlib_allocator : private Base {
+private:
+    typedef typename Base::size_type size_type;
+public:
+    NDNBOOST_STATIC_CONSTANT(bool, custom = 
+        (!is_same<std::allocator<char>, Base>::value));
+    typedef typename zlib_allocator_traits<Alloc>::type allocator_type;
+    static void* allocate(void* self, zlib::uint items, zlib::uint size);
+    static void deallocate(void* self, void* address);
+};
+
+class NDNBOOST_IOSTREAMS_DECL zlib_base { 
+public:
+    typedef char char_type;
+protected:
+    zlib_base();
+    ~zlib_base();
+    void* stream() { return stream_; }
+    template<typename Alloc> 
+    void init( const zlib_params& p, 
+               bool compress,
+               zlib_allocator<Alloc>& zalloc )
+        {
+            bool custom = zlib_allocator<Alloc>::custom;
+            do_init( p, compress,
+                     #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+                         custom ? zlib_allocator<Alloc>::allocate : 0,
+                         custom ? zlib_allocator<Alloc>::deallocate : 0,
+                     #endif
+                     &zalloc );
+        }
+    void before( const char*& src_begin, const char* src_end,
+                 char*& dest_begin, char* dest_end );
+    void after( const char*& src_begin, char*& dest_begin, 
+                bool compress );
+    int xdeflate(int flush);  // Prefix 'x' prevents symbols from being 
+    int xinflate(int flush);  // redefined when Z_PREFIX is defined
+    void reset(bool compress, bool realloc);
+public:
+    zlib::ulong crc() const { return crc_; }
+    int total_in() const { return total_in_; }
+    int total_out() const { return total_out_; }
+private:
+    void do_init( const zlib_params& p, bool compress, 
+                  #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+                      zlib::xalloc_func, 
+                      zlib::xfree_func, 
+                  #endif
+                  void* derived );
+    void*        stream_;         // Actual type: z_stream*.
+    bool         calculate_crc_;
+    zlib::ulong  crc_;
+    zlib::ulong  crc_imp_;
+    int          total_in_;
+    int          total_out_;
+};
+
+//
+// Template name: zlib_compressor_impl
+// Description: Model of C-Style Filte implementing compression by
+//      delegating to the zlib function deflate.
+//
+template<typename Alloc = std::allocator<char> >
+class zlib_compressor_impl : public zlib_base, public zlib_allocator<Alloc> { 
+public: 
+    zlib_compressor_impl(const zlib_params& = zlib::default_compression);
+    ~zlib_compressor_impl();
+    bool filter( const char*& src_begin, const char* src_end,
+                 char*& dest_begin, char* dest_end, bool flush );
+    void close();
+};
+
+//
+// Template name: zlib_compressor
+// Description: Model of C-Style Filte implementing decompression by
+//      delegating to the zlib function inflate.
+//
+template<typename Alloc = std::allocator<char> >
+class zlib_decompressor_impl : public zlib_base, public zlib_allocator<Alloc> {
+public:
+    zlib_decompressor_impl(const zlib_params&);
+    zlib_decompressor_impl(int window_bits = zlib::default_window_bits);
+    ~zlib_decompressor_impl();
+    bool filter( const char*& begin_in, const char* end_in,
+                 char*& begin_out, char* end_out, bool flush );
+    void close();
+    bool eof() const { return eof_; }
+private:
+    bool eof_;
+};
+
+} // End namespace detail.
+
+//
+// Template name: zlib_compressor
+// Description: Model of InputFilter and OutputFilter implementing
+//      compression using zlib.
+//
+template<typename Alloc = std::allocator<char> >
+struct basic_zlib_compressor 
+    : symmetric_filter<detail::zlib_compressor_impl<Alloc>, Alloc> 
+{
+private:
+    typedef detail::zlib_compressor_impl<Alloc>         impl_type;
+    typedef symmetric_filter<impl_type, Alloc>  base_type;
+public:
+    typedef typename base_type::char_type               char_type;
+    typedef typename base_type::category                category;
+    basic_zlib_compressor( const zlib_params& = zlib::default_compression, 
+                           int buffer_size = default_device_buffer_size );
+    zlib::ulong crc() { return this->filter().crc(); }
+    int total_in() {  return this->filter().total_in(); }
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_zlib_compressor, 1)
+
+typedef basic_zlib_compressor<> zlib_compressor;
+
+//
+// Template name: zlib_decompressor
+// Description: Model of InputFilter and OutputFilter implementing
+//      decompression using zlib.
+//
+template<typename Alloc = std::allocator<char> >
+struct basic_zlib_decompressor 
+    : symmetric_filter<detail::zlib_decompressor_impl<Alloc>, Alloc> 
+{
+private:
+    typedef detail::zlib_decompressor_impl<Alloc>       impl_type;
+    typedef symmetric_filter<impl_type, Alloc>  base_type;
+public:
+    typedef typename base_type::char_type               char_type;
+    typedef typename base_type::category                category;
+    basic_zlib_decompressor( int window_bits = zlib::default_window_bits,
+                             int buffer_size = default_device_buffer_size );
+    basic_zlib_decompressor( const zlib_params& p,
+                             int buffer_size = default_device_buffer_size );
+    zlib::ulong crc() { return this->filter().crc(); }
+    int total_out() {  return this->filter().total_out(); }
+    bool eof() { return this->filter().eof(); }
+};
+NDNBOOST_IOSTREAMS_PIPABLE(basic_zlib_decompressor, 1)
+
+typedef basic_zlib_decompressor<> zlib_decompressor;
+
+//----------------------------------------------------------------------------//
+
+//------------------Implementation of zlib_allocator--------------------------//
+
+namespace detail {
+
+template<typename Alloc, typename Base>
+void* zlib_allocator<Alloc, Base>::allocate
+    (void* self, zlib::uint items, zlib::uint size)
+{ 
+    size_type len = items * size;
+    char* ptr = 
+        static_cast<allocator_type*>(self)->allocate
+            (len + sizeof(size_type)
+            #if NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1)
+                , (char*)0
+            #endif
+            );
+    *reinterpret_cast<size_type*>(ptr) = len;
+    return ptr + sizeof(size_type);
+}
+
+template<typename Alloc, typename Base>
+void zlib_allocator<Alloc, Base>::deallocate(void* self, void* address)
+{ 
+    char* ptr = reinterpret_cast<char*>(address) - sizeof(size_type);
+    size_type len = *reinterpret_cast<size_type*>(ptr) + sizeof(size_type);
+    static_cast<allocator_type*>(self)->deallocate(ptr, len); 
+}
+
+//------------------Implementation of zlib_compressor_impl--------------------//
+
+template<typename Alloc>
+zlib_compressor_impl<Alloc>::zlib_compressor_impl(const zlib_params& p)
+{ init(p, true, static_cast<zlib_allocator<Alloc>&>(*this)); }
+
+template<typename Alloc>
+zlib_compressor_impl<Alloc>::~zlib_compressor_impl()
+{ reset(true, false); }
+
+template<typename Alloc>
+bool zlib_compressor_impl<Alloc>::filter
+    ( const char*& src_begin, const char* src_end,
+      char*& dest_begin, char* dest_end, bool flush )
+{
+    before(src_begin, src_end, dest_begin, dest_end);
+    int result = xdeflate(flush ? zlib::finish : zlib::no_flush);
+    after(src_begin, dest_begin, true);
+    zlib_error::check NDNBOOST_PREVENT_MACRO_SUBSTITUTION(result);
+    return result != zlib::stream_end; 
+}
+
+template<typename Alloc>
+void zlib_compressor_impl<Alloc>::close() { reset(true, true); }
+
+//------------------Implementation of zlib_decompressor_impl------------------//
+
+template<typename Alloc>
+zlib_decompressor_impl<Alloc>::zlib_decompressor_impl(const zlib_params& p)
+  : eof_(false)
+{ init(p, false, static_cast<zlib_allocator<Alloc>&>(*this)); }
+
+template<typename Alloc>
+zlib_decompressor_impl<Alloc>::~zlib_decompressor_impl()
+{ reset(false, false); }
+
+template<typename Alloc>
+zlib_decompressor_impl<Alloc>::zlib_decompressor_impl(int window_bits)
+{ 
+    zlib_params p;
+    p.window_bits = window_bits;
+    init(p, false, static_cast<zlib_allocator<Alloc>&>(*this)); 
+}
+
+template<typename Alloc>
+bool zlib_decompressor_impl<Alloc>::filter
+    ( const char*& src_begin, const char* src_end,
+      char*& dest_begin, char* dest_end, bool /* flush */ )
+{
+    before(src_begin, src_end, dest_begin, dest_end);
+    int result = xinflate(zlib::sync_flush);
+    after(src_begin, dest_begin, false);
+    zlib_error::check NDNBOOST_PREVENT_MACRO_SUBSTITUTION(result);
+    return !(eof_ = result == zlib::stream_end);
+}
+
+template<typename Alloc>
+void zlib_decompressor_impl<Alloc>::close() {
+    eof_ = false;
+    reset(false, true);
+}
+
+} // End namespace detail.
+
+//------------------Implementation of zlib_decompressor-----------------------//
+
+template<typename Alloc>
+basic_zlib_compressor<Alloc>::basic_zlib_compressor
+    (const zlib_params& p, int buffer_size) 
+    : base_type(buffer_size, p) { }
+
+//------------------Implementation of zlib_decompressor-----------------------//
+
+template<typename Alloc>
+basic_zlib_decompressor<Alloc>::basic_zlib_decompressor
+    (int window_bits, int buffer_size) 
+    : base_type(buffer_size, window_bits) { }
+
+template<typename Alloc>
+basic_zlib_decompressor<Alloc>::basic_zlib_decompressor
+    (const zlib_params& p, int buffer_size) 
+    : base_type(buffer_size, p) { }
+
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/config/abi_suffix.hpp> // Pops abi_suffix.hpp pragmas.
+#ifdef NDNBOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_ZLIB_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filtering_stream.hpp b/include/ndnboost/iostreams/filtering_stream.hpp
new file mode 100644
index 0000000..3d085a1
--- /dev/null
+++ b/include/ndnboost/iostreams/filtering_stream.hpp
@@ -0,0 +1,166 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2004-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <memory>                                     // allocator.
+#include <ndnboost/iostreams/detail/access_control.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/iostream.hpp>        // standard streams.
+#include <ndnboost/iostreams/detail/push.hpp>
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp>       // pubsync.
+#include <ndnboost/iostreams/filtering_streambuf.hpp>
+#include <ndnboost/mpl/and.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+//--------------Definition of filtered_istream--------------------------------//
+
+namespace detail {
+
+template<typename Mode, typename Ch, typename Tr>
+struct filtering_stream_traits {
+    typedef typename 
+            iostreams::select<  // Disambiguation for Tru64  
+                mpl::and_< 
+                    is_convertible<Mode, input>, 
+                    is_convertible<Mode, output> 
+                >,          
+                NDNBOOST_IOSTREAMS_BASIC_IOSTREAM(Ch, Tr),
+                is_convertible<Mode, input>, 
+                NDNBOOST_IOSTREAMS_BASIC_ISTREAM(Ch, Tr),
+                else_,        
+                NDNBOOST_IOSTREAMS_BASIC_OSTREAM(Ch, Tr)
+            >::type stream_type;
+    typedef typename
+            iostreams::select< // Dismbiguation required for Tru64.
+                mpl::and_<
+                    is_convertible<Mode, input>,
+                    is_convertible<Mode, output>
+                >,
+                iostream_tag,
+                is_convertible<Mode, input>,
+                istream_tag,
+                else_,
+                ostream_tag
+            >::type stream_tag;
+};
+
+template<typename Chain, typename Access>
+class filtering_stream_base 
+    : public access_control<
+                 ndnboost::iostreams::detail::chain_client<Chain>,
+                 Access
+             >,
+      public filtering_stream_traits<
+                 typename Chain::mode, 
+                 typename Chain::char_type, 
+                 typename Chain::traits_type
+             >::stream_type
+{
+public:
+    typedef Chain                                         chain_type;
+    typedef access_control<
+                 ndnboost::iostreams::detail::chain_client<Chain>,
+                 Access
+             >                                            client_type;
+protected:
+    typedef typename 
+            filtering_stream_traits<
+                 typename Chain::mode, 
+                 typename Chain::char_type, 
+                 typename Chain::traits_type
+            >::stream_type                                stream_type;
+    filtering_stream_base() : stream_type(0) { this->set_chain(&chain_); }
+private:
+    void notify() { this->rdbuf(chain_.empty() ? 0 : &chain_.front()); }
+    Chain chain_;
+};
+
+} // End namespace detail.
+
+//
+// Macro: NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAM(name_, chain_type_, default_char_)
+// Description: Defines a template derived from std::basic_streambuf which uses
+//      a chain to perform i/o. The template has the following parameters:
+//      Mode - the i/o mode.
+//      Ch - The character type.
+//      Tr - The character traits type.
+//      Alloc - The allocator type.
+//      Access - Indicates accessibility of the chain interface; must be either
+//          public_ or protected_; defaults to public_.
+// Macro parameters:
+//      name_ - The name of the template to be defined.
+//      chain_type_ - The name of the chain template.
+//      default_char_ - The default value for the char template parameter.
+//
+#define NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAM(name_, chain_type_, default_char_) \
+    template< typename Mode, \
+              typename Ch = default_char_, \
+              typename Tr = NDNBOOST_IOSTREAMS_CHAR_TRAITS(Ch), \
+              typename Alloc = std::allocator<Ch>, \
+              typename Access = public_ > \
+    class name_ \
+        : public ndnboost::iostreams::detail::filtering_stream_base< \
+                     chain_type_<Mode, Ch, Tr, Alloc>, Access \
+                 > \
+    { \
+    public: \
+        typedef Ch                                char_type; \
+        struct category \
+            : Mode, \
+              closable_tag, \
+              detail::filtering_stream_traits<Mode, Ch, Tr>::stream_tag \
+            { }; \
+        NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \
+        typedef Mode                              mode; \
+        typedef chain_type_<Mode, Ch, Tr, Alloc>  chain_type; \
+        name_() { } \
+        NDNBOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name_, mode, Ch, push_impl) \
+        ~name_() { \
+            if (this->is_complete()) \
+                 this->rdbuf()->NDNBOOST_IOSTREAMS_PUBSYNC(); \
+        } \
+    private: \
+        typedef access_control< \
+                    ndnboost::iostreams::detail::chain_client< \
+                        chain_type_<Mode, Ch, Tr, Alloc> \
+                    >, \
+                    Access \
+                > client_type; \
+        template<typename T> \
+        void push_impl(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS()) \
+        { client_type::push(t NDNBOOST_IOSTREAMS_PUSH_ARGS()); } \
+    }; \
+    /**/    
+NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, ndnboost::iostreams::chain, char)
+NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAM(wfiltering_stream, ndnboost::iostreams::chain, wchar_t)
+
+typedef filtering_stream<input>    filtering_istream;
+typedef filtering_stream<output>   filtering_ostream;
+typedef wfiltering_stream<input>   filtering_wistream;
+typedef wfiltering_stream<output>  filtering_wostream;
+
+//----------------------------------------------------------------------------//
+
+} } // End namespace iostreams, boost
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/filtering_streambuf.hpp b/include/ndnboost/iostreams/filtering_streambuf.hpp
new file mode 100644
index 0000000..c54fd3f
--- /dev/null
+++ b/include/ndnboost/iostreams/filtering_streambuf.hpp
@@ -0,0 +1,70 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <exception>
+#include <memory>                               // allocator.
+#include <ndnboost/iostreams/chain.hpp>
+#include <ndnboost/iostreams/detail/access_control.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/push.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp> // pubsync.
+#include <ndnboost/iostreams/detail/streambuf/chainbuf.hpp>
+#include <ndnboost/mpl/if.hpp>                    
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Macro: NDNBOOST_IOSTREAMS_DEFINE_FILTERBUF(name_, chain_type_, default_char_)
+// Description: Defines a template derived from std::basic_streambuf which uses
+//      a chain to perform i/o. The template has the following parameters:
+//      Ch - The character type.
+//      Tr - The character traits type.
+//      Alloc - The allocator type.
+//      Access - Indicates accessibility of the chain interface; must be either
+//          public_ or protected_; defaults to public_.
+//
+#define NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(name_, chain_type_, default_char_) \
+    template< typename Mode, \
+              typename Ch = default_char_, \
+              typename Tr = NDNBOOST_IOSTREAMS_CHAR_TRAITS(Ch), \
+              typename Alloc = std::allocator<Ch>, \
+              typename Access = public_ > \
+    class name_ : public ndnboost::iostreams::detail::chainbuf< \
+                             chain_type_<Mode, Ch, Tr, Alloc>, Mode, Access \
+                         > \
+    { \
+    public: \
+        typedef Ch                                             char_type; \
+        struct category \
+            : Mode, closable_tag, streambuf_tag \
+            { }; \
+        NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \
+        typedef Mode                                           mode; \
+        typedef chain_type_<Mode, Ch, Tr, Alloc>               chain_type; \
+        name_() { } \
+        NDNBOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name_, mode, Ch, push_impl) \
+        ~name_() { if (this->is_complete()) this->NDNBOOST_IOSTREAMS_PUBSYNC(); } \
+    }; \
+    /**/ 
+NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(filtering_streambuf, ndnboost::iostreams::chain, char)
+NDNBOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(filtering_wstreambuf, ndnboost::iostreams::chain, wchar_t)
+
+typedef filtering_streambuf<input>    filtering_istreambuf;
+typedef filtering_streambuf<output>   filtering_ostreambuf;
+typedef filtering_wstreambuf<input>   filtering_wistreambuf;
+typedef filtering_wstreambuf<output>  filtering_wostreambuf;
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/flush.hpp b/include/ndnboost/iostreams/flush.hpp
new file mode 100644
index 0000000..e10df64
--- /dev/null
+++ b/include/ndnboost/iostreams/flush.hpp
@@ -0,0 +1,125 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_FLUSH_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_FLUSH_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct flush_device_impl;
+
+template<typename T>
+struct flush_filter_impl;
+
+} // End namespace detail.
+
+template<typename T>
+bool flush(T& t)
+{ return detail::flush_device_impl<T>::flush(detail::unwrap(t)); }
+
+template<typename T, typename Sink>
+bool flush(T& t, Sink& snk)
+{ return detail::flush_filter_impl<T>::flush(detail::unwrap(t), snk); }
+
+namespace detail {
+
+//------------------Definition of flush_device_impl---------------------------//
+
+template<typename T>
+struct flush_device_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          flush_device_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, ostream_tag, streambuf_tag, flushable_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct flush_device_impl<ostream_tag> {
+    template<typename T>
+    static bool flush(T& t)
+    { return t.rdbuf()->NDNBOOST_IOSTREAMS_PUBSYNC() == 0; }
+};
+
+template<>
+struct flush_device_impl<streambuf_tag> {
+    template<typename T>
+    static bool flush(T& t)
+    { return t.NDNBOOST_IOSTREAMS_PUBSYNC() == 0; }
+};
+
+template<>
+struct flush_device_impl<flushable_tag> {
+    template<typename T>
+    static bool flush(T& t) { return t.flush(); }
+};
+
+template<>
+struct flush_device_impl<any_tag> {
+    template<typename T>
+    static bool flush(T&) { return true; }
+};
+
+//------------------Definition of flush_filter_impl---------------------------//
+
+template<typename T>
+struct flush_filter_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          flush_filter_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, flushable_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct flush_filter_impl<flushable_tag> {
+    template<typename T, typename Sink>
+    static bool flush(T& t, Sink& snk) { return t.flush(snk); }
+};
+
+template<>
+struct flush_filter_impl<any_tag> {
+    template<typename T, typename Sink>
+    static bool flush(T&, Sink&) { return false; }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_FLUSH_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/get.hpp b/include/ndnboost/iostreams/get.hpp
new file mode 100644
index 0000000..8af8f7a
--- /dev/null
+++ b/include/ndnboost/iostreams/get.hpp
@@ -0,0 +1,17 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_GET_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_GET_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/read.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_GET_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/imbue.hpp b/include/ndnboost/iostreams/imbue.hpp
new file mode 100644
index 0000000..de9ffb3
--- /dev/null
+++ b/include/ndnboost/iostreams/imbue.hpp
@@ -0,0 +1,82 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_IMBUE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_IMBUE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams { 
+
+namespace detail {
+
+// Implementation templates for simulated tag dispatch.
+template<typename T> 
+struct imbue_impl;
+
+} // End namespace detail.
+
+template<typename T, typename Locale>
+void imbue(T& t, const Locale& loc)
+{ detail::imbue_impl<T>::imbue(detail::unwrap(t), loc); }
+
+namespace detail {
+
+//------------------Definition of imbue_impl----------------------------------//
+
+template<typename T>
+struct imbue_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          imbue_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, streambuf_tag, localizable_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct imbue_impl<any_tag> {
+    template<typename T, typename Locale>
+    static void imbue(T&, const Locale&) { }
+};
+
+template<>
+struct imbue_impl<streambuf_tag> {
+    template<typename T, typename Locale>
+    static void imbue(T& t, const Locale& loc) { t.pubimbue(loc); }
+};
+
+template<>
+struct imbue_impl<localizable_tag> {
+    template<typename T, typename Locale>
+    static void imbue(T& t, const Locale& loc) { t.imbue(loc); }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_IMBUE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/input_sequence.hpp b/include/ndnboost/iostreams/input_sequence.hpp
new file mode 100644
index 0000000..7950c6f
--- /dev/null
+++ b/include/ndnboost/iostreams/input_sequence.hpp
@@ -0,0 +1,72 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <utility>           // pair.
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>  // is_custom 
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct input_sequence_impl;
+
+} // End namespace detail.
+
+template<typename T>
+inline std::pair<
+    NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type*,
+    NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type*
+>
+input_sequence(T& t)
+{ return detail::input_sequence_impl<T>::input_sequence(t); }
+
+namespace detail {
+
+//------------------Definition of direct_impl-------------------------------//
+
+template<typename T>
+struct input_sequence_impl
+    : mpl::if_<
+          detail::is_custom<T>,
+          operations<T>,
+          input_sequence_impl<direct_tag>
+      >::type
+    { };
+
+template<>
+struct input_sequence_impl<direct_tag> {
+    template<typename U>
+    static std::pair<
+        NDNBOOST_DEDUCED_TYPENAME char_type_of<U>::type*,
+        NDNBOOST_DEDUCED_TYPENAME char_type_of<U>::type*
+    >
+    input_sequence(U& u) { return u.input_sequence(); }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/invert.hpp b/include/ndnboost/iostreams/invert.hpp
new file mode 100644
index 0000000..8b0e5fd
--- /dev/null
+++ b/include/ndnboost/iostreams/invert.hpp
@@ -0,0 +1,167 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_INVERT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_INVERT_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <algorithm>                             // copy, min.  
+#include <ndnboost/assert.hpp>
+#include <ndnboost/config.hpp>                      // NDNBOOST_DEDUCED_TYPENAME.       
+#include <ndnboost/detail/workaround.hpp>           // default_filter_buffer_size.
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/compose.hpp>
+#include <ndnboost/iostreams/constants.hpp>
+#include <ndnboost/iostreams/device/array.hpp>
+#include <ndnboost/iostreams/detail/buffer.hpp>
+#include <ndnboost/iostreams/detail/counted_array.hpp>
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp> // clear_flags, call_reset
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/ref.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Template name: inverse.
+// Template parameters:
+//      Filter - A model of InputFilter or OutputFilter.
+// Description: Generates an InputFilter from an OutputFilter or
+//      vice versa.
+//
+template<typename Filter>
+class inverse {
+private:
+    NDNBOOST_STATIC_ASSERT(is_filter<Filter>::value);
+    typedef typename category_of<Filter>::type   base_category;
+    typedef reference_wrapper<Filter>            filter_ref;
+public:
+    typedef typename char_type_of<Filter>::type  char_type;
+    typedef typename int_type_of<Filter>::type   int_type;
+    typedef char_traits<char_type>               traits_type;
+    typedef typename 
+            mpl::if_<
+                is_convertible<
+                    base_category,
+                    input
+                >,
+                output,
+                input
+            >::type                              mode;
+    struct category 
+        : mode, 
+          filter_tag, 
+          multichar_tag, 
+          closable_tag 
+        { };
+    explicit inverse( const Filter& filter, 
+                      std::streamsize buffer_size = 
+                          default_filter_buffer_size) 
+        : pimpl_(new impl(filter, buffer_size))
+        { }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char* s, std::streamsize n)
+    {
+        typedef detail::counted_array_sink<char_type>  array_sink;
+        typedef composite<filter_ref, array_sink>      filtered_array_sink;
+
+        NDNBOOST_ASSERT((flags() & f_write) == 0);
+        if (flags() == 0) {
+            flags() = f_read;
+            buf().set(0, 0);
+        }
+
+        filtered_array_sink snk(filter(), array_sink(s, n));
+        int_type status;
+        for ( status = traits_type::good();
+              snk.second().count() < n && status == traits_type::good(); )
+        {
+            status = buf().fill(src);
+            buf().flush(snk);
+        }
+        return snk.second().count() == 0 &&
+               status == traits_type::eof() 
+                   ? 
+               -1
+                   : 
+               snk.second().count();
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& dest, const char* s, std::streamsize n)
+    {
+        typedef detail::counted_array_source<char_type>  array_source;
+        typedef composite<filter_ref, array_source>      filtered_array_source;
+
+        NDNBOOST_ASSERT((flags() & f_read) == 0);
+        if (flags() == 0) {
+            flags() = f_write;
+            buf().set(0, 0);
+        }
+        
+        filtered_array_source src(filter(), array_source(s, n));
+        for (bool good = true; src.second().count() < n && good; ) {
+            buf().fill(src);
+            good = buf().flush(dest);
+        }
+        return src.second().count();
+    }
+
+    template<typename Device>
+    void close(Device& dev)
+    {
+        detail::execute_all(
+            detail::flush_buffer(buf(), dev, (flags() & f_write) != 0),
+            detail::call_close_all(pimpl_->filter_, dev),
+            detail::clear_flags(flags())
+        );
+    }
+private:
+    filter_ref filter() { return ndnboost::ref(pimpl_->filter_); }
+    detail::buffer<char_type>& buf() { return pimpl_->buf_; }
+    int& flags() { return pimpl_->flags_; }
+    
+    enum flags_ {
+        f_read = 1, f_write = 2
+    };
+
+    struct impl {
+        impl(const Filter& filter, std::streamsize n) 
+            : filter_(filter), buf_(n), flags_(0)
+        { buf_.set(0, 0); }
+        Filter                     filter_;
+        detail::buffer<char_type>  buf_;
+        int                        flags_;
+    };
+    shared_ptr<impl> pimpl_;
+};
+
+//
+// Template name: invert.
+// Template parameters:
+//      Filter - A model of InputFilter or OutputFilter.
+// Description: Returns an instance of an appropriate specialization of inverse.
+//
+template<typename Filter>
+inverse<Filter> invert(const Filter& f) { return inverse<Filter>(f); }
+                    
+//----------------------------------------------------------------------------//
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_INVERT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/operations.hpp b/include/ndnboost/iostreams/operations.hpp
new file mode 100644
index 0000000..ab11dee
--- /dev/null
+++ b/include/ndnboost/iostreams/operations.hpp
@@ -0,0 +1,26 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/iostreams/close.hpp>
+#include <ndnboost/iostreams/flush.hpp>
+#include <ndnboost/iostreams/imbue.hpp>
+#include <ndnboost/iostreams/input_sequence.hpp>
+#include <ndnboost/iostreams/optimal_buffer_size.hpp>
+#include <ndnboost/iostreams/output_sequence.hpp>
+#include <ndnboost/iostreams/read.hpp>
+#include <ndnboost/iostreams/seek.hpp>
+#include <ndnboost/iostreams/write.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/operations_fwd.hpp b/include/ndnboost/iostreams/operations_fwd.hpp
new file mode 100644
index 0000000..aee7990
--- /dev/null
+++ b/include/ndnboost/iostreams/operations_fwd.hpp
@@ -0,0 +1,41 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/mpl/not.hpp>
+#include <ndnboost/type_traits/is_base_and_derived.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+template<typename T>
+struct operations;
+
+namespace detail {
+
+struct custom_tag { };
+
+template<typename T>
+struct is_custom
+    : mpl::not_<
+          is_base_and_derived< custom_tag, operations<T> >
+      >
+    { };
+
+} // End namespace detail.
+
+template<typename T>
+struct operations : detail::custom_tag { };
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED //--------------//
diff --git a/include/ndnboost/iostreams/optimal_buffer_size.hpp b/include/ndnboost/iostreams/optimal_buffer_size.hpp
new file mode 100644
index 0000000..edf4a80
--- /dev/null
+++ b/include/ndnboost/iostreams/optimal_buffer_size.hpp
@@ -0,0 +1,87 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/constants.hpp>  // constants.
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct optimal_buffer_size_impl;
+
+} // End namespace detail.
+
+template<typename T>
+std::streamsize optimal_buffer_size(const T& t)
+{
+    typedef detail::optimal_buffer_size_impl<T> impl;
+    return impl::optimal_buffer_size(detail::unwrap(t));
+}
+
+namespace detail {
+
+//------------------Definition of optimal_buffer_size_impl--------------------//
+
+template<typename T>
+struct optimal_buffer_size_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          optimal_buffer_size_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, optimally_buffered_tag, device_tag, filter_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct optimal_buffer_size_impl<optimally_buffered_tag> {
+    template<typename T>
+    static std::streamsize optimal_buffer_size(const T& t)
+    { return t.optimal_buffer_size(); }
+};
+
+template<>
+struct optimal_buffer_size_impl<device_tag> {
+    template<typename T>
+    static std::streamsize optimal_buffer_size(const T&)
+    { return default_device_buffer_size; }
+};
+
+template<>
+struct optimal_buffer_size_impl<filter_tag> {
+    template<typename T>
+    static std::streamsize optimal_buffer_size(const T&)
+    { return default_filter_buffer_size; }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/output_sequence.hpp b/include/ndnboost/iostreams/output_sequence.hpp
new file mode 100644
index 0000000..fa0e522
--- /dev/null
+++ b/include/ndnboost/iostreams/output_sequence.hpp
@@ -0,0 +1,72 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <utility>           // pair.
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>  // is_custom 
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct output_sequence_impl;
+
+} // End namespace detail.
+
+template<typename T>
+inline std::pair<
+    NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type*,
+    NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type*
+>
+output_sequence(T& t)
+{ return detail::output_sequence_impl<T>::output_sequence(t); }
+
+namespace detail {
+
+//------------------Definition of output_sequence_impl------------------------//
+
+template<typename T>
+struct output_sequence_impl
+    : mpl::if_<
+          detail::is_custom<T>,
+          operations<T>,
+          output_sequence_impl<direct_tag>
+      >::type
+    { };
+
+template<>
+struct output_sequence_impl<direct_tag> {
+    template<typename U>
+    static std::pair<
+        NDNBOOST_DEDUCED_TYPENAME char_type_of<U>::type*,
+        NDNBOOST_DEDUCED_TYPENAME char_type_of<U>::type*
+    >
+    output_sequence(U& u) { return u.output_sequence(); }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/pipeline.hpp b/include/ndnboost/iostreams/pipeline.hpp
new file mode 100644
index 0000000..e95d3c0
--- /dev/null
+++ b/include/ndnboost/iostreams/pipeline.hpp
@@ -0,0 +1,128 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp> // NDNBOOST_MSVC.
+#include <ndnboost/detail/workaround.hpp>           
+#include <ndnboost/iostreams/detail/template_params.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/preprocessor/punctuation/comma_if.hpp>
+#include <ndnboost/preprocessor/repetition/enum_params.hpp>
+#include <ndnboost/static_assert.hpp>
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)
+# include <ndnboost/type_traits/is_base_and_derived.hpp>
+#endif
+
+#define NDNBOOST_IOSTREAMS_PIPABLE(filter, arity) \
+    template< NDNBOOST_PP_ENUM_PARAMS(arity, typename T) \
+              NDNBOOST_PP_COMMA_IF(arity) typename Component> \
+    ::ndnboost::iostreams::pipeline< \
+        ::ndnboost::iostreams::detail::pipeline_segment< \
+            filter NDNBOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \
+        >, \
+        Component \
+    > operator|( const filter NDNBOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)& f, \
+                 const Component& c ) \
+    { \
+        typedef ::ndnboost::iostreams::detail::pipeline_segment< \
+                    filter NDNBOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \
+                > segment; \
+        return ::ndnboost::iostreams::pipeline<segment, Component> \
+                   (segment(f), c); \
+    } \
+    /**/
+
+namespace ndnboost { namespace iostreams {
+
+template<typename Pipeline, typename Component>
+struct pipeline;
+    
+namespace detail {
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300) 
+    struct pipeline_base { };
+
+    template<typename T>
+    struct is_pipeline 
+        : is_base_and_derived<pipeline_base, T>
+        { };
+#endif 
+#if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x600)
+    template<typename T>
+    struct is_pipeline : mpl::false_ { };
+
+    template<typename Pipeline, typename Component>
+    struct is_pipeline< pipeline<Pipeline, Component> > : mpl::true_ { };
+#endif
+
+template<typename Component>
+class pipeline_segment 
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+    : pipeline_base 
+#endif 
+{
+public:
+    pipeline_segment(const Component& component) 
+        : component_(component) 
+        { }
+    template<typename Fn>
+    void for_each(Fn fn) const { fn(component_); }
+    template<typename Chain>
+    void push(Chain& chn) const { chn.push(component_); }
+private:
+    pipeline_segment operator=(const pipeline_segment&);
+    const Component& component_;
+};
+
+} // End namespace detail.
+                    
+//------------------Definition of Pipeline------------------------------------//
+
+template<typename Pipeline, typename Component>
+struct pipeline : Pipeline {
+    typedef Pipeline   pipeline_type;
+    typedef Component  component_type;
+    pipeline(const Pipeline& p, const Component& component)
+        : Pipeline(p), component_(component)
+        { }
+    template<typename Fn>
+    void for_each(Fn fn) const
+    {
+        Pipeline::for_each(fn);
+        fn(component_);
+    }
+    template<typename Chain>
+    void push(Chain& chn) const
+    { 
+        Pipeline::push(chn);
+        chn.push(component_);
+    }
+    const Pipeline& tail() const { return *this; }
+    const Component& head() const { return component_; }
+private:
+    pipeline operator=(const pipeline&);
+    const Component& component_;
+};
+
+template<typename Pipeline, typename Filter, typename Component>
+pipeline<pipeline<Pipeline, Filter>, Component>
+operator|(const pipeline<Pipeline, Filter>& p, const Component& cmp)
+{
+    NDNBOOST_STATIC_ASSERT(is_filter<Filter>::value);
+    return pipeline<pipeline<Pipeline, Filter>, Component>(p, cmp);
+}
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/positioning.hpp b/include/ndnboost/iostreams/positioning.hpp
new file mode 100644
index 0000000..178f9e4
--- /dev/null
+++ b/include/ndnboost/iostreams/positioning.hpp
@@ -0,0 +1,117 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Thanks to Gareth Sylvester-Bradley for the Dinkumware versions of the
+// positioning functions.
+
+#ifndef NDNBOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/integer_traits.hpp>
+#include <ndnboost/iostreams/detail/config/codecvt.hpp> // mbstate_t.
+#include <ndnboost/iostreams/detail/config/fpos.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp> // streamoff, streampos.
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> 
+
+#ifdef NDNBOOST_NO_STDC_NAMESPACE
+namespace std { using ::fpos_t; }
+#endif
+
+namespace ndnboost { namespace iostreams {
+                    
+//------------------Definition of stream_offset-------------------------------//
+
+typedef ndnboost::intmax_t stream_offset;
+
+//------------------Definition of stream_offset_to_streamoff------------------//
+
+inline std::streamoff stream_offset_to_streamoff(stream_offset off)
+{ return static_cast<stream_offset>(off); }
+
+//------------------Definition of offset_to_position--------------------------//
+
+# ifndef NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+inline std::streampos offset_to_position(stream_offset off) { return off; }
+
+# else // # ifndef NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+inline std::streampos offset_to_position(stream_offset off)
+{ return std::streampos(std::mbstate_t(), off); }
+
+# endif // # ifndef NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+//------------------Definition of position_to_offset--------------------------//
+
+// Hande custom pos_type's
+template<typename PosType> 
+inline stream_offset position_to_offset(PosType pos)
+{ return std::streamoff(pos); }
+
+# ifndef NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+inline stream_offset position_to_offset(std::streampos pos) { return pos; }
+
+# else // # ifndef NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS
+
+// In the Dinkumware standard library, a std::streampos consists of two stream
+// offsets -- _Fpos, of type std::fpos_t, and _Myoff, of type std::streamoff --
+// together with a conversion state. A std::streampos is converted to a 
+// ndnboost::iostreams::stream_offset by extracting the two stream offsets and
+// summing them. The value of _Fpos can be extracted using the implementation-
+// defined member functions seekpos() or get_fpos_t(), depending on the 
+// Dinkumware version. The value of _Myoff cannot be extracted directly, but can
+// be calculated as the difference between the result of converting the 
+// std::fpos to a std::streamoff and the result of converting the member _Fpos
+// to a long. The latter operation is accomplished with the macro _FPOSOFF, 
+// which works correctly on platforms where std::fpos_t is an integral type and 
+// platforms where it is a struct
+
+// Converts a std::fpos_t to a stream_offset
+inline stream_offset fpos_t_to_offset(std::fpos_t pos)
+{
+#  if defined(_POSIX_) || (_INTEGRAL_MAX_BITS >= 64) || defined(__IBMCPP__)
+    return pos;
+#  else
+    return _FPOSOFF(pos);
+#  endif
+}
+
+// Extracts the member _Fpos from a std::fpos
+inline std::fpos_t streampos_to_fpos_t(std::streampos pos)
+{
+#  if defined (_CPPLIB_VER) || defined(__IBMCPP__)
+    return pos.seekpos();
+#  else
+    return pos.get_fpos_t();
+#  endif
+}
+
+inline stream_offset position_to_offset(std::streampos pos)
+{
+    return fpos_t_to_offset(streampos_to_fpos_t(pos)) +
+        static_cast<stream_offset>(
+            static_cast<std::streamoff>(pos) -
+            _FPOSOFF(streampos_to_fpos_t(pos))
+        );
+}
+
+# endif // # ifndef NDNBOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS 
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> 
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/put.hpp b/include/ndnboost/iostreams/put.hpp
new file mode 100644
index 0000000..893fed5
--- /dev/null
+++ b/include/ndnboost/iostreams/put.hpp
@@ -0,0 +1,17 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_PUT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_PUT_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/write.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_PUT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/putback.hpp b/include/ndnboost/iostreams/putback.hpp
new file mode 100644
index 0000000..986924d
--- /dev/null
+++ b/include/ndnboost/iostreams/putback.hpp
@@ -0,0 +1,17 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/read.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/read.hpp b/include/ndnboost/iostreams/read.hpp
new file mode 100644
index 0000000..c11edf4
--- /dev/null
+++ b/include/ndnboost/iostreams/read.hpp
@@ -0,0 +1,247 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_READ_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_READ_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // streamsize.
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //-----------------------------------//
+# include <ndnboost/iostreams/detail/vc6/read.hpp>
+#else // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //--------------------------//
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct read_device_impl;
+
+template<typename T>
+struct read_filter_impl;
+
+} // End namespace detail.
+
+template<typename T>
+typename int_type_of<T>::type get(T& t)
+{ return detail::read_device_impl<T>::get(detail::unwrap(t)); }
+
+template<typename T>
+inline std::streamsize
+read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+{ return detail::read_device_impl<T>::read(detail::unwrap(t), s, n); }
+
+template<typename T, typename Source>
+std::streamsize
+read(T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
+{ return detail::read_filter_impl<T>::read(detail::unwrap(t), src, s, n); }
+
+template<typename T>
+bool putback(T& t, typename char_type_of<T>::type c)
+{ return detail::read_device_impl<T>::putback(detail::unwrap(t), c); }
+
+//----------------------------------------------------------------------------//
+
+namespace detail {
+
+// Helper function for adding -1 as EOF indicator.
+inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; }
+
+// Helper templates for reading from streambufs.
+template<bool IsLinked>
+struct true_eof_impl;
+
+template<>
+struct true_eof_impl<true> {
+    template<typename T>
+    static bool true_eof(T& t) { return t.true_eof(); }
+};
+
+template<>
+struct true_eof_impl<false> {
+    template<typename T>
+    static bool true_eof(T&) { return true; }
+};
+
+template<typename T>
+inline bool true_eof(T& t)
+{
+    const bool linked = is_linked<T>::value;
+    return true_eof_impl<linked>::true_eof(t);
+}
+
+//------------------Definition of read_device_impl----------------------------//
+
+template<typename T>
+struct read_device_impl
+    : mpl::if_<
+          detail::is_custom<T>,
+          operations<T>,
+          read_device_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              detail::dispatch<
+                  T, istream_tag, streambuf_tag, input
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct read_device_impl<istream_tag> {
+    template<typename T>
+    static typename int_type_of<T>::type get(T& t)
+    { return t.get(); }
+
+    template<typename T>
+    static std::streamsize
+    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+    { return check_eof(t.rdbuf()->sgetn(s, n)); }
+
+    template<typename T>
+    static bool putback(T& t, typename char_type_of<T>::type c)
+    {
+        typedef typename char_type_of<T>::type          char_type;
+        typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
+        return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c),
+                                          traits_type::eof() );
+    }
+};
+
+template<>
+struct read_device_impl<streambuf_tag> {
+    template<typename T>
+    static typename int_type_of<T>::type
+    get(T& t)
+    {   // gcc 2.95 needs namespace qualification for char_traits.
+        typedef typename char_type_of<T>::type     char_type;
+        typedef iostreams::char_traits<char_type>  traits_type;
+        typename int_type_of<T>::type c;
+        return !traits_type::is_eof(c = t.sbumpc()) ||
+                detail::true_eof(t)
+                    ?
+                c : traits_type::would_block();
+    }
+
+    template<typename T>
+    static std::streamsize
+    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+    {
+        std::streamsize amt;
+        return (amt = t.sgetn(s, n)) != 0 ?
+            amt :
+            detail::true_eof(t) ?
+                -1 :
+                0;
+    }
+
+    template<typename T>
+    static bool putback(T& t, typename char_type_of<T>::type c)
+    {   // gcc 2.95 needs namespace qualification for char_traits.
+        typedef typename char_type_of<T>::type     char_type;
+        typedef iostreams::char_traits<char_type>  traits_type;
+        return !traits_type::is_eof(t.sputbackc(c));
+    }
+};
+
+template<>
+struct read_device_impl<input> {
+    template<typename T>
+    static typename int_type_of<T>::type
+    get(T& t)
+    {   // gcc 2.95 needs namespace qualification for char_traits.
+        typedef typename char_type_of<T>::type     char_type;
+        typedef iostreams::char_traits<char_type>  traits_type;
+        char_type c;
+        std::streamsize amt;
+        return (amt = t.read(&c, 1)) == 1 ?
+            traits_type::to_int_type(c) :
+            amt == -1 ?
+                traits_type::eof() :
+                traits_type::would_block();
+    }
+
+    template<typename T>
+    static std::streamsize
+    read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
+    { return t.read(s, n); }
+
+    template<typename T>
+    static bool putback(T& t, typename char_type_of<T>::type c)
+    {   // T must be Peekable.
+        return t.putback(c);
+    }
+};
+
+//------------------Definition of read_filter_impl----------------------------//
+
+template<typename T>
+struct read_filter_impl
+    : mpl::if_<
+          detail::is_custom<T>,
+          operations<T>,
+          read_filter_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              detail::dispatch<
+                  T, multichar_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct read_filter_impl<multichar_tag> {
+    template<typename T, typename Source>
+    static std::streamsize read
+       (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
+    { return t.read(src, s, n); }
+};
+
+template<>
+struct read_filter_impl<any_tag> {
+    template<typename T, typename Source>
+    static std::streamsize read
+       (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
+    {   // gcc 2.95 needs namespace qualification for char_traits.
+        typedef typename char_type_of<T>::type     char_type;
+        typedef iostreams::char_traits<char_type>  traits_type;
+        for (std::streamsize off = 0; off < n; ++off) {
+            typename traits_type::int_type c = t.get(src);
+            if (traits_type::is_eof(c))
+                return check_eof(off);
+            if (traits_type::would_block(c))
+                return off;
+            s[off] = traits_type::to_char_type(c);
+        }
+        return n;
+    }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //-------------------------//
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_READ_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/restrict.hpp b/include/ndnboost/iostreams/restrict.hpp
new file mode 100644
index 0000000..8b0fde4
--- /dev/null
+++ b/include/ndnboost/iostreams/restrict.hpp
@@ -0,0 +1,26 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * File:        ndnboost/iostreams/detail/restrict.hpp
+ * Date:        Sun Jan 06 12:57:30 MST 2008
+ * Copyright:   2008 CodeRage, LLC
+                2004-2007 Jonathan Turkanis
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the class template ndnboost::iostreams::restriction and the 
+ * overloaded function template ndnboost::iostreams::restrict
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
+
+#include <ndnboost/iostreams/detail/restrict_impl.hpp>
+#define NDNBOOST_IOSTREAMS_RESTRICT restrict
+#include <ndnboost/iostreams/detail/restrict_impl.hpp>
+#undef NDNBOOST_IOSTREAMS_RESTRICT
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/seek.hpp b/include/ndnboost/iostreams/seek.hpp
new file mode 100644
index 0000000..6ff19b1
--- /dev/null
+++ b/include/ndnboost/iostreams/seek.hpp
@@ -0,0 +1,180 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_SEEK_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_SEEK_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/integer_traits.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>       // streamsize, seekdir, openmode.
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/iostreams/positioning.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T>
+struct seek_device_impl;
+
+template<typename T>
+struct seek_filter_impl;
+
+} // End namespace detail.
+
+template<typename T>
+inline std::streampos
+seek( T& t, stream_offset off, NDNBOOST_IOS::seekdir way,
+      NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+{ 
+    using namespace detail;
+    return seek_device_impl<T>::seek(detail::unwrap(t), off, way, which); 
+}
+
+template<typename T, typename Device>
+inline std::streampos
+seek( T& t, Device& dev, stream_offset off, NDNBOOST_IOS::seekdir way,
+      NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+{ 
+    using namespace detail;
+    return seek_filter_impl<T>::seek(detail::unwrap(t), dev, off, way, which);
+}
+
+namespace detail {
+
+//------------------Definition of seek_device_impl----------------------------//
+
+template<typename T>
+struct seek_device_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          seek_device_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, iostream_tag, istream_tag, ostream_tag,
+                  streambuf_tag, two_head, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+struct seek_impl_basic_ios {
+    template<typename T>
+    static std::streampos seek( T& t, stream_offset off,
+                                NDNBOOST_IOS::seekdir way,
+                                NDNBOOST_IOS::openmode which )
+    {
+        if ( way == NDNBOOST_IOS::beg &&
+             ( off < integer_traits<std::streamoff>::const_min ||
+               off > integer_traits<std::streamoff>::const_max ) )
+        {
+            return t.rdbuf()->pubseekpos(offset_to_position(off));
+        } else {
+            return t.rdbuf()->pubseekoff(off, way, which);
+        }
+    }
+};
+
+template<>
+struct seek_device_impl<iostream_tag> : seek_impl_basic_ios { };
+
+template<>
+struct seek_device_impl<istream_tag> : seek_impl_basic_ios { };
+
+template<>
+struct seek_device_impl<ostream_tag> : seek_impl_basic_ios { };
+
+template<>
+struct seek_device_impl<streambuf_tag> {
+    template<typename T>
+    static std::streampos seek( T& t, stream_offset off,
+                                NDNBOOST_IOS::seekdir way,
+                                NDNBOOST_IOS::openmode which )
+    {
+        if ( way == NDNBOOST_IOS::beg &&
+             ( off < integer_traits<std::streamoff>::const_min ||
+               off > integer_traits<std::streamoff>::const_max ) )
+        {
+            return t.NDNBOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off));
+        } else {
+            return t.NDNBOOST_IOSTREAMS_PUBSEEKOFF(off, way, which);
+        }
+    }
+};
+
+template<>
+struct seek_device_impl<two_head> {
+    template<typename T>
+    static std::streampos seek( T& t, stream_offset off,
+                                NDNBOOST_IOS::seekdir way,
+                                NDNBOOST_IOS::openmode which )
+    { return t.seek(off, way, which); }
+};
+
+template<>
+struct seek_device_impl<any_tag> {
+    template<typename T>
+    static std::streampos seek( T& t, stream_offset off,
+                                NDNBOOST_IOS::seekdir way,
+                                NDNBOOST_IOS::openmode )
+    { return t.seek(off, way); }
+};
+
+//------------------Definition of seek_filter_impl----------------------------//
+
+template<typename T>
+struct seek_filter_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          seek_filter_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<T, two_head, any_tag>::type
+          >
+      >::type
+    { };
+
+template<>
+struct seek_filter_impl<two_head> {
+    template<typename T, typename Device>
+    static std::streampos seek( T& t, Device& d,
+                                stream_offset off,
+                                NDNBOOST_IOS::seekdir way,
+                                NDNBOOST_IOS::openmode which )
+    { return t.seek(d, off, way, which); }
+};
+
+template<>
+struct seek_filter_impl<any_tag> {
+    template<typename T, typename Device>
+    static std::streampos seek( T& t, Device& d,
+                                stream_offset off,
+                                NDNBOOST_IOS::seekdir way,
+                                NDNBOOST_IOS::openmode )
+    { return t.seek(d, off, way); }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_SEEK_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/skip.hpp b/include/ndnboost/iostreams/skip.hpp
new file mode 100644
index 0000000..6b5a600
--- /dev/null
+++ b/include/ndnboost/iostreams/skip.hpp
@@ -0,0 +1,112 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// To do: handle bidirection streams and output-seekable components.
+
+#ifndef NDNBOOST_IOSTREAMS_SKIP_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_SKIP_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/char_traits.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // failure.
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/seek.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/and.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/mpl/or.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename Device>
+void skip(Device& dev, stream_offset off, mpl::true_)
+{ iostreams::seek(dev, off, NDNBOOST_IOS::cur); }
+
+template<typename Device>
+void skip(Device& dev, stream_offset off, mpl::false_)
+{   // gcc 2.95 needs namespace qualification for char_traits.
+    typedef typename char_type_of<Device>::type  char_type;
+    typedef iostreams::char_traits<char_type>    traits_type;
+    for (stream_offset z = 0; z < off; ) {
+        typename traits_type::int_type c;
+        if (traits_type::is_eof(c = iostreams::get(dev)))
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("bad skip offset"));
+        if (!traits_type::would_block(c))
+            ++z;
+    }
+}
+
+template<typename Filter, typename Device>
+void skip( Filter& flt, Device& dev, stream_offset off,
+           NDNBOOST_IOS::openmode which, mpl::true_ )
+{ ndnboost::iostreams::seek(flt, dev, off, NDNBOOST_IOS::cur, which); }
+
+template<typename Filter, typename Device>
+void skip( Filter& flt, Device& dev, stream_offset off,
+           NDNBOOST_IOS::openmode, mpl::false_ )
+{ 
+    typedef typename char_type_of<Device>::type char_type;
+    char_type c;
+    for (stream_offset z = 0; z < off; ) {
+        std::streamsize amt;
+        if ((amt = iostreams::read(flt, dev, &c, 1)) == -1)
+            ndnboost::throw_exception(NDNBOOST_IOSTREAMS_FAILURE("bad skip offset"));
+        if (amt == 1)
+            ++z;
+    }
+}
+
+} // End namespace detail.
+
+template<typename Device>
+void skip(Device& dev, stream_offset off)
+{ 
+    typedef typename mode_of<Device>::type     mode;
+    typedef mpl::or_<
+        is_convertible<mode, input_seekable>,
+        is_convertible<mode, output_seekable>
+    >                                          can_seek;
+    NDNBOOST_STATIC_ASSERT(
+        (can_seek::value || is_convertible<mode, input>::value)
+    );
+    detail::skip(dev, off, can_seek());
+}
+
+template<typename Filter, typename Device>
+void skip( Filter& flt, Device& dev, stream_offset off, 
+           NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_IOS::out )
+{ 
+    typedef typename mode_of<Filter>::type                 filter_mode;
+    typedef typename mode_of<Device>::type                 device_mode;
+    typedef mpl::or_<
+        mpl::and_<
+            is_convertible<filter_mode, input_seekable>,
+            is_convertible<device_mode, input_seekable>
+        >,
+        mpl::and_<
+            is_convertible<filter_mode, output_seekable>,
+            is_convertible<device_mode, output_seekable>
+        >
+    >                                                      can_seek;
+    NDNBOOST_STATIC_ASSERT(
+        ( can_seek::value || 
+          (is_convertible<filter_mode, input>::value &&
+          is_convertible<device_mode, input>::value) )
+    );
+    detail::skip(flt, dev, off, which, can_seek());
+}
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_SKIP_HPP_INCLUDED //------------------------//
diff --git a/include/ndnboost/iostreams/slice.hpp b/include/ndnboost/iostreams/slice.hpp
new file mode 100644
index 0000000..cf16ea9
--- /dev/null
+++ b/include/ndnboost/iostreams/slice.hpp
@@ -0,0 +1,28 @@
+/*
+ * 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.)
+ * 
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * File:        ndnboost/iostreams/detail/restrict.hpp
+ * Date:        Sun Jan 06 12:57:30 MST 2008
+ * Copyright:   2008 CodeRage, LLC
+                2004-2007 Jonathan Turkanis
+ * Author:      Jonathan Turkanis
+ * Contact:     turkanis at coderage dot com
+ *
+ * Defines the class template ndnboost::iostreams::restriction and the 
+ * overloaded function template ndnboost::iostreams::slice.
+ *
+ * This header is provided for platforms on which "restrict" is a keyword.
+ */
+
+#ifndef NDNBOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
+
+#include <ndnboost/iostreams/detail/restrict_impl.hpp>
+#define NDNBOOST_IOSTREAMS_RESTRICT slice
+#include <ndnboost/iostreams/detail/restrict_impl.hpp>
+#undef NDNBOOST_IOSTREAMS_RESTRICT
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/stream.hpp b/include/ndnboost/iostreams/stream.hpp
new file mode 100644
index 0000000..e158117
--- /dev/null
+++ b/include/ndnboost/iostreams/stream.hpp
@@ -0,0 +1,151 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_STREAM_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_STREAM_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/iostreams/constants.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/config/overload_resolution.hpp>
+#include <ndnboost/iostreams/detail/forward.hpp>
+#include <ndnboost/iostreams/detail/iostream.hpp>  // standard streams.
+#include <ndnboost/iostreams/detail/select.hpp>
+#include <ndnboost/iostreams/stream_buffer.hpp>
+#include <ndnboost/mpl/and.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/utility/base_from_member.hpp>
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename Device, typename Tr>
+struct stream_traits {
+    typedef typename char_type_of<Device>::type                char_type;
+    typedef Tr                                                 traits_type;
+    typedef typename category_of<Device>::type                 mode;
+    typedef typename
+            iostreams::select< // Disambiguation required for Tru64.
+                mpl::and_<
+                    is_convertible<mode, input>,
+                    is_convertible<mode, output>
+                >,
+                NDNBOOST_IOSTREAMS_BASIC_IOSTREAM(char_type, traits_type),
+                is_convertible<mode, input>,
+                NDNBOOST_IOSTREAMS_BASIC_ISTREAM(char_type, traits_type),
+                else_,
+                NDNBOOST_IOSTREAMS_BASIC_OSTREAM(char_type, traits_type)
+            >::type stream_type;
+    typedef typename
+            iostreams::select< // Disambiguation required for Tru64.
+                mpl::and_<
+                    is_convertible<mode, input>,
+                    is_convertible<mode, output>
+                >,
+                iostream_tag,
+                is_convertible<mode, input>,
+                istream_tag,
+                else_,
+                ostream_tag
+            >::type stream_tag;
+};
+
+// By encapsulating initialization in a base, we can define the macro
+// NDNBOOST_IOSTREAMS_DEFINE_FORWARDING_FUNCTIONS to generate constructors
+// without base member initializer lists.
+template< typename Device,
+          typename Tr =
+              NDNBOOST_IOSTREAMS_CHAR_TRAITS(
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+              ),
+          typename Alloc =
+              std::allocator<
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+              >,
+          typename Base = // VC6 Workaround.
+              NDNBOOST_DEDUCED_TYPENAME
+              detail::stream_traits<Device, Tr>::stream_type >
+class stream_base
+    : protected base_from_member< stream_buffer<Device, Tr, Alloc> >,
+      public Base
+{
+private:
+    typedef base_from_member< stream_buffer<Device, Tr, Alloc> >  pbase_type;
+    typedef typename stream_traits<Device, Tr>::stream_type       stream_type;
+protected:
+    using pbase_type::member; // Avoid warning about 'this' in initializer list.
+public:
+    stream_base() : pbase_type(), stream_type(&member) { }
+};
+
+} } } // End namespaces detail, iostreams, boost.
+
+#ifdef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION
+# include <ndnboost/iostreams/detail/broken_overload_resolution/stream.hpp>
+#else
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Template name: stream.
+// Description: A iostream which reads from and writes to an instance of a
+//      designated device type.
+// Template parameters:
+//      Device - A device type.
+//      Alloc - The allocator type.
+//
+template< typename Device,
+          typename Tr =
+              NDNBOOST_IOSTREAMS_CHAR_TRAITS(
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+              ),
+          typename Alloc =
+              std::allocator<
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<Device>::type
+              > >
+struct stream : detail::stream_base<Device, Tr, Alloc> {
+public:
+    typedef typename char_type_of<Device>::type  char_type;
+    struct category 
+        : mode_of<Device>::type,
+          closable_tag,
+          detail::stream_traits<Device, Tr>::stream_tag
+        { };
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+private:
+    typedef typename
+            detail::stream_traits<
+                Device, Tr
+            >::stream_type                       stream_type;
+public:
+    stream() { }
+    NDNBOOST_IOSTREAMS_FORWARD( stream, open_impl, Device,
+                             NDNBOOST_IOSTREAMS_PUSH_PARAMS,
+                             NDNBOOST_IOSTREAMS_PUSH_ARGS )
+    bool is_open() const { return this->member.is_open(); }
+    void close() { this->member.close(); }
+    bool auto_close() const { return this->member.auto_close(); }
+    void set_auto_close(bool close) { this->member.set_auto_close(close); }
+    bool strict_sync() { return this->member.strict_sync(); }
+    Device& operator*() { return *this->member; }
+    Device* operator->() { return &*this->member; }
+    Device* component() { return this->member.component(); }
+private:
+    void open_impl(const Device& dev NDNBOOST_IOSTREAMS_PUSH_PARAMS()) // For forwarding.
+    { 
+        this->clear(); 
+        this->member.open(dev NDNBOOST_IOSTREAMS_PUSH_ARGS()); 
+    }
+};
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifdef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_stream_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/stream_buffer.hpp b/include/ndnboost/iostreams/stream_buffer.hpp
new file mode 100644
index 0000000..8b12972
--- /dev/null
+++ b/include/ndnboost/iostreams/stream_buffer.hpp
@@ -0,0 +1,116 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <memory>            // allocator.
+#include <ndnboost/config.hpp>  // NDNBOOST_DEDUCED_TYPENAME.
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/config/overload_resolution.hpp>
+#include <ndnboost/iostreams/detail/forward.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // failure, streamsize.
+#include <ndnboost/iostreams/detail/streambuf/direct_streambuf.hpp>
+#include <ndnboost/iostreams/detail/streambuf/indirect_streambuf.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
+
+namespace ndnboost { namespace iostreams { namespace detail {
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+struct stream_buffer_traits {
+    typedef typename
+            mpl::if_<
+                is_convertible<
+                    NDNBOOST_DEDUCED_TYPENAME category_of<T>::type,
+                    direct_tag
+                >,
+                direct_streambuf<T, Tr>,
+                indirect_streambuf<T, Tr, Alloc, Mode>
+            >::type type;
+};
+
+} } } // End namespaces detail, iostreams, boost
+
+#ifdef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION
+# include <ndnboost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp>
+#else
+
+namespace ndnboost { namespace iostreams {
+
+template< typename T,
+          typename Tr =
+              NDNBOOST_IOSTREAMS_CHAR_TRAITS(
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type
+              ),
+          typename Alloc =
+              std::allocator<
+                  NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type
+              >,
+          typename Mode = NDNBOOST_DEDUCED_TYPENAME mode_of<T>::type >
+class stream_buffer
+    : public detail::stream_buffer_traits<T, Tr, Alloc, Mode>::type
+{
+private:
+    NDNBOOST_STATIC_ASSERT((
+        is_convertible<
+            NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<T>::type, Mode
+        >::value
+    ));
+    typedef typename
+            detail::stream_buffer_traits<
+                T, Tr, Alloc, Mode
+            >::type                           base_type;
+public:
+    typedef typename char_type_of<T>::type    char_type;
+    struct category 
+        : Mode,
+          closable_tag,
+          streambuf_tag
+        { };
+    NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
+public:
+    stream_buffer() { }
+    ~stream_buffer()
+    { 
+        try { 
+            if (this->is_open() && this->auto_close()) 
+                this->close(); 
+        } catch (...) { } 
+    }
+    NDNBOOST_IOSTREAMS_FORWARD( stream_buffer, open_impl, T,
+                             NDNBOOST_IOSTREAMS_PUSH_PARAMS,
+                             NDNBOOST_IOSTREAMS_PUSH_ARGS )
+    T& operator*() { return *this->component(); }
+    T* operator->() { return this->component(); }
+private:
+    void open_impl(const T& t NDNBOOST_IOSTREAMS_PUSH_PARAMS())
+        {   // Used for forwarding.
+            if (this->is_open())
+                ndnboost::throw_exception(
+                    NDNBOOST_IOSTREAMS_FAILURE("already open")
+                );
+            base_type::open(t NDNBOOST_IOSTREAMS_PUSH_ARGS());
+        }
+};
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifdef NDNBOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/tee.hpp b/include/ndnboost/iostreams/tee.hpp
new file mode 100644
index 0000000..a7c3cbb
--- /dev/null
+++ b/include/ndnboost/iostreams/tee.hpp
@@ -0,0 +1,232 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2005-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_TEE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_TEE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/assert.hpp>
+#include <ndnboost/config.hpp>  // NDNBOOST_DEDUCE_TYPENAME.
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/adapter/device_adapter.hpp>
+#include <ndnboost/iostreams/detail/adapter/filter_adapter.hpp>
+#include <ndnboost/iostreams/detail/call_traits.hpp>
+#include <ndnboost/iostreams/detail/execute.hpp>
+#include <ndnboost/iostreams/detail/functional.hpp>  // call_close_all 
+#include <ndnboost/iostreams/operations.hpp>
+#include <ndnboost/iostreams/pipeline.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+#include <ndnboost/type_traits/is_same.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+//
+// Template name: tee_filter.
+// Template parameters:
+//      Device - A blocking Sink.
+//
+template<typename Device>
+class tee_filter : public detail::filter_adapter<Device> {
+public:
+    typedef typename detail::param_type<Device>::type  param_type;
+    typedef typename char_type_of<Device>::type        char_type;
+    struct category
+        : dual_use_filter_tag,
+          multichar_tag,
+          closable_tag,
+          flushable_tag,
+          localizable_tag,
+          optimally_buffered_tag
+        { };
+
+    NDNBOOST_STATIC_ASSERT(is_device<Device>::value);
+    NDNBOOST_STATIC_ASSERT((
+        is_convertible< // Using mode_of causes failures on VC6-7.0.
+            NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
+        >::value
+    ));
+
+    explicit tee_filter(param_type dev) 
+        : detail::filter_adapter<Device>(dev) 
+        { }
+
+    template<typename Source>
+    std::streamsize read(Source& src, char_type* s, std::streamsize n)
+    {
+        std::streamsize result = iostreams::read(src, s, n);
+        if (result != -1) {
+            std::streamsize result2 = iostreams::write(this->component(), s, result);
+            (void) result2; // Suppress 'unused variable' warning.
+            NDNBOOST_ASSERT(result == result2);
+        }
+        return result;
+    }
+
+    template<typename Sink>
+    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
+    {
+        std::streamsize result = iostreams::write(snk, s, n);
+        std::streamsize result2 = iostreams::write(this->component(), s, result);
+        (void) result2; // Suppress 'unused variable' warning.
+        NDNBOOST_ASSERT(result == result2);
+        return result;
+    }
+
+    template<typename Next>
+    void close(Next&, NDNBOOST_IOS::openmode)
+    { 
+        detail::close_all(this->component());
+    }
+
+    template<typename Sink>
+    bool flush(Sink& snk)
+    {
+        bool r1 = iostreams::flush(snk);
+        bool r2 = iostreams::flush(this->component());
+        return r1 && r2;
+    }
+};
+NDNBOOST_IOSTREAMS_PIPABLE(tee_filter, 1)
+
+//
+// Template name: tee_device.
+// Template parameters:
+//      Device - A blocking Device.
+//      Sink - A blocking Sink.
+//
+template<typename Device, typename Sink>
+class tee_device {
+public:
+    typedef typename detail::param_type<Device>::type  device_param;
+    typedef typename detail::param_type<Sink>::type    sink_param;
+    typedef typename detail::value_type<Device>::type  device_value;
+    typedef typename detail::value_type<Sink>::type    sink_value;
+    typedef typename char_type_of<Device>::type        char_type;
+    typedef typename
+            mpl::if_<
+                 is_convertible<
+                     NDNBOOST_DEDUCED_TYPENAME 
+                         iostreams::category_of<Device>::type, 
+                     output
+                 >,
+                 output,
+                 input
+            >::type                                    mode;
+    NDNBOOST_STATIC_ASSERT(is_device<Device>::value);
+    NDNBOOST_STATIC_ASSERT(is_device<Sink>::value);
+    NDNBOOST_STATIC_ASSERT((
+        is_same<
+            char_type, 
+            NDNBOOST_DEDUCED_TYPENAME char_type_of<Sink>::type
+        >::value
+    ));
+    NDNBOOST_STATIC_ASSERT((
+        is_convertible<
+            NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Sink>::type, 
+            output
+        >::value
+    ));
+    struct category
+        : mode,
+          device_tag,
+          closable_tag,
+          flushable_tag,
+          localizable_tag,
+          optimally_buffered_tag
+        { };
+    tee_device(device_param device, sink_param sink) 
+        : dev_(device), sink_(sink)
+        { }
+    std::streamsize read(char_type* s, std::streamsize n)
+    {
+        NDNBOOST_STATIC_ASSERT((
+            is_convertible<
+                NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, input
+            >::value
+        ));
+        std::streamsize result1 = iostreams::read(dev_, s, n);
+        if (result1 != -1) {
+            std::streamsize result2 = iostreams::write(sink_, s, result1);
+            (void) result1; // Suppress 'unused variable' warning.
+            (void) result2;
+            NDNBOOST_ASSERT(result1 == result2);
+        }
+        return result1;
+    }
+    std::streamsize write(const char_type* s, std::streamsize n)
+    {
+        NDNBOOST_STATIC_ASSERT((
+            is_convertible<
+                NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
+            >::value
+        ));
+        std::streamsize result1 = iostreams::write(dev_, s, n);
+        std::streamsize result2 = iostreams::write(sink_, s, n);
+        (void) result1; // Suppress 'unused variable' warning.
+        (void) result2;
+        NDNBOOST_ASSERT(result1 == n && result2 == n);
+        return n;
+    }
+    void close()
+    {
+        detail::execute_all( detail::call_close_all(dev_),
+                             detail::call_close_all(sink_) );
+    }
+    bool flush()
+    {
+        bool r1 = iostreams::flush(dev_);
+        bool r2 = iostreams::flush(sink_);
+        return r1 && r2;
+    }
+    template<typename Locale>
+    void imbue(const Locale& loc)
+    {
+        iostreams::imbue(dev_, loc);
+        iostreams::imbue(sink_, loc);
+    }
+    std::streamsize optimal_buffer_size() const 
+    {
+        return (std::max) ( iostreams::optimal_buffer_size(dev_), 
+                            iostreams::optimal_buffer_size(sink_) );
+    }
+private:
+    device_value  dev_;
+    sink_value    sink_;
+};
+
+template<typename Sink>
+tee_filter<Sink> tee(Sink& snk) 
+{ return tee_filter<Sink>(snk); }
+
+template<typename Sink>
+tee_filter<Sink> tee(const Sink& snk) 
+{ return tee_filter<Sink>(snk); }
+
+template<typename Device, typename Sink>
+tee_device<Device, Sink> tee(Device& dev, Sink& sink) 
+{ return tee_device<Device, Sink>(dev, sink); }
+
+template<typename Device, typename Sink>
+tee_device<Device, Sink> tee(const Device& dev, Sink& sink) 
+{ return tee_device<Device, Sink>(dev, sink); }
+
+template<typename Device, typename Sink>
+tee_device<Device, Sink> tee(Device& dev, const Sink& sink) 
+{ return tee_device<Device, Sink>(dev, sink); }
+
+template<typename Device, typename Sink>
+tee_device<Device, Sink> tee(const Device& dev, const Sink& sink) 
+{ return tee_device<Device, Sink>(dev, sink); }
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_TEE_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/traits.hpp b/include/ndnboost/iostreams/traits.hpp
new file mode 100644
index 0000000..515eb07
--- /dev/null
+++ b/include/ndnboost/iostreams/traits.hpp
@@ -0,0 +1,391 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// 
+// Contains metafunctions char_type_of, category_of and mode_of used for
+// deducing the i/o category and i/o mode of a model of Filter or Device.
+//
+// Also contains several utility metafunctions, functions and macros.
+//
+
+#ifndef NDNBOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <iosfwd>            // stream types, char_traits.
+#include <ndnboost/config.hpp>  // partial spec, deduced typename.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/bool_trait_def.hpp> 
+#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
+#include <ndnboost/iostreams/detail/is_iterator_range.hpp>    
+#include <ndnboost/iostreams/detail/select.hpp>        
+#include <ndnboost/iostreams/detail/select_by_size.hpp>      
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>       
+#include <ndnboost/iostreams/traits_fwd.hpp> 
+#include <ndnboost/mpl/bool.hpp>   
+#include <ndnboost/mpl/eval_if.hpp>
+#include <ndnboost/mpl/identity.hpp>      
+#include <ndnboost/mpl/int.hpp>  
+#include <ndnboost/mpl/or.hpp>                 
+#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+# include <ndnboost/range/iterator_range.hpp>
+# include <ndnboost/range/value_type.hpp>
+#endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+#include <ndnboost/ref.hpp>
+#include <ndnboost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace ndnboost { namespace iostreams {
+
+//----------Definitions of predicates for streams and stream buffers----------//
+
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
+
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream, std::basic_ifstream, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream, std::basic_ofstream, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream, std::basic_fstream, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf, std::basic_filebuf, 2)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream, std::basic_istringstream, 3)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream, std::basic_ostringstream, 3)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3)
+
+#else // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
+
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0)
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0)
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------//
+
+template<typename T>
+struct is_std_io
+    : mpl::or_< is_istream<T>, is_ostream<T>, is_streambuf<T> >
+    { };
+
+template<typename T>
+struct is_std_file_device
+    : mpl::or_< 
+          is_ifstream<T>, 
+          is_ofstream<T>, 
+          is_fstream<T>, 
+          is_filebuf<T>
+      >
+    { };
+
+template<typename T>
+struct is_std_string_device
+    : mpl::or_< 
+          is_istringstream<T>, 
+          is_ostringstream<T>, 
+          is_stringstream<T>, 
+          is_stringbuf<T>
+      >
+    { };
+
+template<typename Device, typename Tr, typename Alloc>
+struct stream;
+
+template<typename T, typename Tr, typename Alloc, typename Mode>
+class stream_buffer;
+
+template< typename Mode, typename Ch, typename Tr, 
+          typename Alloc, typename Access >
+class filtering_stream;
+
+template< typename Mode, typename Ch, typename Tr, 
+          typename Alloc, typename Access >
+class wfiltering_stream;
+
+template< typename Mode, typename Ch, typename Tr, 
+          typename Alloc, typename Access >
+class filtering_streambuf;
+
+template< typename Mode, typename Ch, typename Tr, 
+          typename Alloc, typename Access >
+class filtering_wstreambuf;
+
+namespace detail {
+
+template<typename T, typename Tr>
+class linked_streambuf;
+
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream,
+                                ndnboost::iostreams::stream,
+                                3 )
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer,
+                                ndnboost::iostreams::stream_buffer,
+                                4 )
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl,
+                                ndnboost::iostreams::filtering_stream,
+                                5 )
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl,
+                                ndnboost::iostreams::wfiltering_stream,
+                                5 )
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl,
+                                ndnboost::iostreams::filtering_streambuf,
+                                5 )
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl,
+                                ndnboost::iostreams::filtering_wstreambuf,
+                                5 )
+NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2)
+
+template<typename T>
+struct is_filtering_stream
+    : mpl::or_<
+          is_filtering_stream_impl<T>,
+          is_filtering_wstream_impl<T>
+      >
+    { };
+
+template<typename T>
+struct is_filtering_streambuf
+    : mpl::or_<
+          is_filtering_streambuf_impl<T>,
+          is_filtering_wstreambuf_impl<T>
+      >
+    { };
+
+template<typename T>
+struct is_boost
+    : mpl::or_<
+          is_boost_stream<T>, 
+          is_boost_stream_buffer<T>, 
+          is_filtering_stream<T>, 
+          is_filtering_streambuf<T>
+      >
+    { };
+
+} // End namespace detail.
+                    
+//------------------Definitions of char_type_of-------------------------------//
+
+namespace detail {
+
+template<typename T>
+struct member_char_type { typedef typename T::char_type type; };
+
+} // End namespace detail.
+
+#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
+# ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
+
+template<typename T>
+struct char_type_of 
+    : detail::member_char_type<
+          typename detail::unwrapped_type<T>::type
+      > 
+    { };
+
+# else // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
+
+template<typename T>
+struct char_type_of {
+    typedef typename detail::unwrapped_type<T>::type U;
+    typedef typename 
+            mpl::eval_if<
+                is_std_io<U>,
+                mpl::identity<char>,
+                detail::member_char_type<U>
+            >::type type;
+};
+
+# endif // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
+
+template<typename Iter>
+struct char_type_of< iterator_range<Iter> > {
+    typedef typename iterator_value<Iter>::type type;
+};
+
+#else // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //------------------//
+
+template<typename T>
+struct char_type_of {
+    template<typename U>
+    struct get_value_type {
+        #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+            typedef typename range_value<U>::type type;
+        #endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+    };
+    typedef typename 
+            mpl::eval_if<
+                is_iterator_range<T>,
+                get_value_type<T>,
+                detail::member_char_type<
+                    NDNBOOST_DEDUCED_TYPENAME detail::unwrapped_type<T>::type
+                >
+            >::type type;
+};
+
+#endif // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
+
+//------------------Definitions of category_of--------------------------------//
+
+namespace detail {
+
+template<typename T>
+struct member_category { typedef typename T::category type; };
+
+} // End namespace detail.
+
+template<typename T>
+struct category_of {
+    template<typename U>
+    struct member_category { 
+        typedef typename U::category type; 
+    };
+    typedef typename detail::unwrapped_type<T>::type U;
+    typedef typename  
+            mpl::eval_if<
+                mpl::and_<
+                    is_std_io<U>,
+                    mpl::not_< detail::is_boost<U> >
+                >,
+                iostreams::select<  // Disambiguation for Tru64
+                    is_filebuf<U>,        filebuf_tag,
+                    is_ifstream<U>,       ifstream_tag,
+                    is_ofstream<U>,       ofstream_tag,
+                    is_fstream<U>,        fstream_tag,
+                    is_stringbuf<U>,      stringbuf_tag,
+                    is_istringstream<U>,  istringstream_tag,
+                    is_ostringstream<U>,  ostringstream_tag,
+                    is_stringstream<U>,   stringstream_tag,
+                    is_streambuf<U>,      generic_streambuf_tag,
+                    is_iostream<U>,       generic_iostream_tag,
+                    is_istream<U>,        generic_istream_tag, 
+                    is_ostream<U>,        generic_ostream_tag
+                >,
+                detail::member_category<U>
+            >::type type;
+};
+
+// Partial specialization for reference wrappers
+#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
+
+template<typename T>
+struct category_of< reference_wrapper<T> >
+    : category_of<T>
+    { };
+
+#endif // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
+
+//------------------Definition of get_category--------------------------------//
+
+// 
+// Returns an object of type category_of<T>::type.
+// 
+template<typename T>
+inline typename category_of<T>::type get_category(const T&) 
+{ typedef typename category_of<T>::type category; return category(); }
+
+//------------------Definition of int_type_of---------------------------------//
+
+template<typename T>
+struct int_type_of { 
+#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
+    typedef std::char_traits<
+                NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type
+            > traits_type;      
+    typedef typename traits_type::int_type type; 
+#else  
+    typedef int                            type; 
+#endif
+};
+
+//------------------Definition of mode_of-------------------------------------//
+
+namespace detail {
+
+template<int N> struct io_mode_impl;
+
+#define NDNBOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \
+    case_<id_> io_mode_impl_helper(tag_); \
+    template<> struct io_mode_impl<id_> { typedef tag_ type; }; \
+    /**/
+NDNBOOST_IOSTREAMS_MODE_HELPER(input, 1)
+NDNBOOST_IOSTREAMS_MODE_HELPER(output, 2)
+NDNBOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3)
+NDNBOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4)
+NDNBOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5)
+NDNBOOST_IOSTREAMS_MODE_HELPER(seekable, 6)
+NDNBOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7)
+NDNBOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8)
+NDNBOOST_IOSTREAMS_MODE_HELPER(dual_use, 9)
+#undef NDNBOOST_IOSTREAMS_MODE_HELPER
+
+template<typename T>
+struct io_mode_id {
+    typedef typename category_of<T>::type category;
+    NDNBOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category()));
+};
+
+} // End namespace detail.
+
+template<typename T> // Borland 5.6.4 requires this circumlocution.
+struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { };
+
+// Partial specialization for reference wrappers
+#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
+
+template<typename T>
+struct mode_of< reference_wrapper<T> >
+    : mode_of<T>
+    { };
+
+#endif // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
+                    
+//------------------Definition of is_device, is_filter and is_direct----------//
+
+namespace detail {
+
+template<typename T, typename Tag>
+struct has_trait_impl {
+    typedef typename category_of<T>::type category;
+    NDNBOOST_STATIC_CONSTANT(bool, value = (is_convertible<category, Tag>::value));
+};
+
+template<typename T, typename Tag>
+struct has_trait 
+    : mpl::bool_<has_trait_impl<T, Tag>::value>
+    { }; 
+
+} // End namespace detail.
+
+template<typename T>
+struct is_device : detail::has_trait<T, device_tag> { };
+
+template<typename T>
+struct is_filter : detail::has_trait<T, filter_tag> { };
+
+template<typename T>
+struct is_direct : detail::has_trait<T, direct_tag> { };
+                    
+//------------------Definition of NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------//
+
+#define NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \
+    typedef Tr                              traits_type; \
+    typedef typename traits_type::int_type  int_type; \
+    typedef typename traits_type::off_type  off_type; \
+    typedef typename traits_type::pos_type  pos_type; \
+    /**/
+
+} } // End namespaces iostreams, boost.
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/traits_fwd.hpp b/include/ndnboost/iostreams/traits_fwd.hpp
new file mode 100644
index 0000000..fd2acea
--- /dev/null
+++ b/include/ndnboost/iostreams/traits_fwd.hpp
@@ -0,0 +1,111 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// Forward declarations of templates defined in traits.hpp.
+
+#ifndef NDNBOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif              
+
+#include <iosfwd> // stream types, char_traits.
+
+namespace ndnboost { namespace iostreams {      
+
+template<typename T>
+struct is_istream;
+
+template<typename T>
+struct is_ostream;
+
+template<typename T>
+struct is_iostream;
+
+template<typename T>
+struct is_streambuf;
+
+template<typename T>
+struct is_istringstream;
+
+template<typename T>
+struct is_ostringstream;
+
+template<typename T>
+struct is_stringstream;
+
+template<typename T>
+struct is_stringbuf;
+
+template<typename T>
+struct is_ifstream;
+
+template<typename T>
+struct is_ofstream;
+
+template<typename T>
+struct is_fstream;
+
+template<typename T>
+struct is_filebuf;
+
+template<typename T>
+struct is_std_io;
+
+template<typename T>
+struct is_std_file_device;
+
+template<typename T>
+struct is_std_string_device;
+
+template<typename T>
+struct char_type_of;
+
+template<typename T>
+struct category_of;
+
+template<typename T>
+struct int_type_of;
+
+template<typename T>
+struct mode_of;
+
+template<typename T>
+struct is_device;
+
+template<typename T>
+struct is_filter;
+
+template<typename T>
+struct is_direct;
+
+namespace detail {
+
+template<typename T>
+struct is_boost_stream;
+
+template<typename T>
+struct is_boost_stream_buffer;
+
+template<typename T>
+struct is_filtering_stream;
+
+template<typename T>
+struct is_filtering_streambuf;
+
+template<typename T>
+struct is_linked;
+
+template<typename T>
+struct is_boost;
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED
diff --git a/include/ndnboost/iostreams/write.hpp b/include/ndnboost/iostreams/write.hpp
new file mode 100644
index 0000000..b2d812e
--- /dev/null
+++ b/include/ndnboost/iostreams/write.hpp
@@ -0,0 +1,171 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// 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.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+#ifndef NDNBOOST_IOSTREAMS_WRITE_HPP_INCLUDED
+#define NDNBOOST_IOSTREAMS_WRITE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <ndnboost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/iostreams/categories.hpp>
+#include <ndnboost/iostreams/detail/char_traits.hpp>
+#include <ndnboost/iostreams/detail/dispatch.hpp>
+#include <ndnboost/iostreams/detail/ios.hpp>  // streamsize.
+#include <ndnboost/iostreams/detail/streambuf.hpp>
+#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
+#include <ndnboost/iostreams/operations_fwd.hpp>
+#include <ndnboost/iostreams/traits.hpp>
+#include <ndnboost/mpl/if.hpp>
+
+// Must come last.
+#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //-----------------------------------//
+# include <ndnboost/iostreams/detail/vc6/write.hpp>
+#else // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //--------------------------//
+
+namespace ndnboost { namespace iostreams {
+
+namespace detail {
+
+template<typename T> 
+struct write_device_impl;
+
+template<typename T> 
+struct write_filter_impl;
+
+} // End namespace detail.
+
+template<typename T>
+bool put(T& t, typename char_type_of<T>::type c)
+{ return detail::write_device_impl<T>::put(detail::unwrap(t), c); }
+
+template<typename T>
+inline std::streamsize write
+    (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+{ return detail::write_device_impl<T>::write(detail::unwrap(t), s, n); }
+
+template<typename T, typename Sink>
+inline std::streamsize
+write( T& t, Sink& snk, const typename char_type_of<T>::type* s, 
+       std::streamsize n )
+{ return detail::write_filter_impl<T>::write(detail::unwrap(t), snk, s, n); }
+
+namespace detail {
+
+//------------------Definition of write_device_impl---------------------------//
+
+template<typename T>
+struct write_device_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          write_device_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, ostream_tag, streambuf_tag, output
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct write_device_impl<ostream_tag> {
+    template<typename T>
+    static bool put(T& t, typename char_type_of<T>::type c)
+    {
+        typedef typename char_type_of<T>::type          char_type;
+        typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
+        return !traits_type::eq_int_type( t.rdbuf()->sputc(c),
+                                          traits_type::eof() );
+    }
+
+    template<typename T>
+    static std::streamsize write
+        (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+    { return t.rdbuf()->sputn(s, n); }
+};
+
+template<>
+struct write_device_impl<streambuf_tag> {
+    template<typename T>
+    static bool put(T& t, typename char_type_of<T>::type c)
+    {
+        typedef typename char_type_of<T>::type          char_type;
+        typedef NDNBOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
+        return !traits_type::eq_int_type(t.sputc(c), traits_type::eof());
+    }
+
+    template<typename T>
+    static std::streamsize write
+        (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+    { return t.sputn(s, n); }
+};
+
+template<>
+struct write_device_impl<output> {
+    template<typename T>
+    static bool put(T& t, typename char_type_of<T>::type c)
+    { return t.write(&c, 1) == 1; }
+
+    template<typename T>
+    static std::streamsize
+    write(T& t, const typename char_type_of<T>::type* s, std::streamsize n)
+    { return t.write(s, n); }
+};
+
+//------------------Definition of write_filter_impl---------------------------//
+
+template<typename T>
+struct write_filter_impl
+    : mpl::if_<
+          is_custom<T>,
+          operations<T>,
+          write_filter_impl<
+              NDNBOOST_DEDUCED_TYPENAME
+              dispatch<
+                  T, multichar_tag, any_tag
+              >::type
+          >
+      >::type
+    { };
+
+template<>
+struct write_filter_impl<multichar_tag> {
+    template<typename T, typename Sink>
+    static std::streamsize
+    write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
+           std::streamsize n )
+    { return t.write(snk, s, n); }
+};
+
+template<>
+struct write_filter_impl<any_tag> {
+    template<typename T, typename Sink>
+    static std::streamsize
+    write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
+           std::streamsize n )
+    {
+        for (std::streamsize off = 0; off < n; ++off)
+            if (!t.put(snk, s[off]))
+                return off;
+        return n;
+    }
+};
+
+} // End namespace detail.
+
+} } // End namespaces iostreams, boost.
+
+#endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300) //-------------------------//
+
+#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
+
+#endif // #ifndef NDNBOOST_IOSTREAMS_WRITE_HPP_INCLUDED
diff --git a/include/ndnboost/operators.hpp b/include/ndnboost/operators.hpp
new file mode 100644
index 0000000..b82a069
--- /dev/null
+++ b/include/ndnboost/operators.hpp
@@ -0,0 +1,978 @@
+//  Boost operators.hpp header file  ----------------------------------------//
+
+//  (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
+//  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)
+
+//  See http://www.boost.org/libs/utility/operators.htm for documentation.
+
+//  Revision History
+//  16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
+//            (Matthew Bradbury, fixes #4432)
+//  07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
+//  03 Apr 08 Make sure "convertible to bool" is sufficient
+//            for T::operator<, etc. (Daniel Frey)
+//  24 May 07 Changed empty_base to depend on T, see
+//            http://svn.boost.org/trac/boost/ticket/979
+//  21 Oct 02 Modified implementation of operators to allow compilers with a
+//            correct named return value optimization (NRVO) to produce optimal
+//            code.  (Daniel Frey)
+//  02 Dec 01 Bug fixed in random_access_iteratable.  (Helmut Zeisel)
+//  28 Sep 01 Factored out iterator operator groups.  (Daryle Walker)
+//  27 Aug 01 'left' form for non commutative operators added;
+//            additional classes for groups of related operators added;
+//            workaround for empty base class optimization
+//            bug of GCC 3.0 (Helmut Zeisel)
+//  25 Jun 01 output_iterator_helper changes: removed default template 
+//            parameters, added support for self-proxying, additional 
+//            documentation and tests (Aleksey Gurtovoy)
+//  29 May 01 Added operator classes for << and >>.  Added input and output
+//            iterator helper classes.  Added classes to connect equality and
+//            relational operators.  Added classes for groups of related
+//            operators.  Reimplemented example operator and iterator helper
+//            classes in terms of the new groups.  (Daryle Walker, with help
+//            from Alexy Gurtovoy)
+//  11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
+//            supplied arguments from actually being used (Dave Abrahams)
+//  04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
+//            refactoring of compiler workarounds, additional documentation
+//            (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
+//            Dave Abrahams) 
+//  28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
+//            Jeremy Siek (Dave Abrahams)
+//  20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
+//            (Mark Rodgers)
+//  20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
+//  10 Jun 00 Support for the base class chaining technique was added
+//            (Aleksey Gurtovoy). See documentation and the comments below 
+//            for the details. 
+//  12 Dec 99 Initial version with iterator operators (Jeremy Siek)
+//  18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
+//            specializations of dividable, subtractable, modable (Ed Brey) 
+//  17 Nov 99 Add comments (Beman Dawes)
+//            Remove unnecessary specialization of operators<> (Ed Brey)
+//  15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
+//            operators.(Beman Dawes)
+//  12 Nov 99 Add operators templates (Ed Brey)
+//  11 Nov 99 Add single template parameter version for compilers without
+//            partial specialization (Beman Dawes)
+//  10 Nov 99 Initial version
+
+// 10 Jun 00:
+// An additional optional template parameter was added to most of 
+// operator templates to support the base class chaining technique (see 
+// documentation for the details). Unfortunately, a straightforward
+// implementation of this change would have broken compatibility with the
+// previous version of the library by making it impossible to use the same
+// template name (e.g. 'addable') for both the 1- and 2-argument versions of
+// an operator template. This implementation solves the backward-compatibility
+// issue at the cost of some simplicity.
+//
+// One of the complications is an existence of special auxiliary class template
+// 'is_chained_base<>' (see 'detail' namespace below), which is used
+// to determine whether its template parameter is a library's operator template
+// or not. You have to specialize 'is_chained_base<>' for each new 
+// operator template you add to the library.
+//
+// However, most of the non-trivial implementation details are hidden behind 
+// several local macros defined below, and as soon as you understand them,
+// you understand the whole library implementation. 
+
+#ifndef NDNBOOST_OPERATORS_HPP
+#define NDNBOOST_OPERATORS_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/iterator.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+#if defined(__sgi) && !defined(__GNUC__)
+#   pragma set woff 1234
+#endif
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1600)
+#   pragma warning( disable : 4284 ) // complaint about return type of 
+#endif                               // operator-> not begin a UDT
+
+namespace ndnboost {
+namespace detail {
+
+template <typename T> class empty_base {
+
+// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
+#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
+  bool dummy; 
+#endif
+
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+// In this section we supply the xxxx1 and xxxx2 forms of the operator
+// templates, which are explicitly targeted at the 1-type-argument and
+// 2-type-argument operator forms, respectively. Some compilers get confused
+// when inline friend functions are overloaded in namespaces other than the
+// global namespace. When NDNBOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
+// these templates must go in the global namespace.
+
+#ifndef NDNBOOST_NO_OPERATORS_IN_NAMESPACE
+namespace ndnboost
+{
+#endif
+
+//  Basic operator classes (contributed by Dave Abrahams) ------------------//
+
+//  Note that friend functions defined in a class are implicitly inline.
+//  See the C++ std, 11.4 [class.friend] paragraph 5
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct less_than_comparable2 : B
+{
+     friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
+     friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
+     friend bool operator>(const U& x, const T& y)  { return y < x; }
+     friend bool operator<(const U& x, const T& y)  { return y > x; }
+     friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
+     friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
+};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct less_than_comparable1 : B
+{
+     friend bool operator>(const T& x, const T& y)  { return y < x; }
+     friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
+     friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
+};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct equality_comparable2 : B
+{
+     friend bool operator==(const U& y, const T& x) { return x == y; }
+     friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
+     friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
+};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct equality_comparable1 : B
+{
+     friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
+};
+
+// A macro which produces "name_2left" from "name".
+#define NDNBOOST_OPERATOR2_LEFT(name) name##2##_##left
+
+//  NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
+
+#if defined(NDNBOOST_HAS_NRVO) || defined(NDNBOOST_FORCE_SYMMETRIC_OPERATORS)
+
+// This is the optimal implementation for ISO/ANSI C++,
+// but it requires the compiler to implement the NRVO.
+// If the compiler has no NRVO, this is the best symmetric
+// implementation available.
+
+#define NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                         \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >        \
+struct NAME##2 : B                                                            \
+{                                                                             \
+  friend T operator OP( const T& lhs, const U& rhs )                          \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
+  friend T operator OP( const U& lhs, const T& rhs )                          \
+    { T nrv( rhs ); nrv OP##= lhs; return nrv; }                              \
+};                                                                            \
+                                                                              \
+template <class T, class B = ::ndnboost::detail::empty_base<T> >                 \
+struct NAME##1 : B                                                            \
+{                                                                             \
+  friend T operator OP( const T& lhs, const T& rhs )                          \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
+};
+
+#define NDNBOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >  \
+struct NAME##2 : B                                                      \
+{                                                                       \
+  friend T operator OP( const T& lhs, const U& rhs )                    \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
+};                                                                      \
+                                                                        \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >  \
+struct NDNBOOST_OPERATOR2_LEFT(NAME) : B                                   \
+{                                                                       \
+  friend T operator OP( const U& lhs, const T& rhs )                    \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
+};                                                                      \
+                                                                        \
+template <class T, class B = ::ndnboost::detail::empty_base<T> >           \
+struct NAME##1 : B                                                      \
+{                                                                       \
+  friend T operator OP( const T& lhs, const T& rhs )                    \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
+};
+
+#else // defined(NDNBOOST_HAS_NRVO) || defined(NDNBOOST_FORCE_SYMMETRIC_OPERATORS)
+
+// For compilers without NRVO the following code is optimal, but not
+// symmetric!  Note that the implementation of
+// NDNBOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
+// optimization opportunities to the compiler :)
+
+#define NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                   \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >  \
+struct NAME##2 : B                                                      \
+{                                                                       \
+  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
+  friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
+};                                                                      \
+                                                                        \
+template <class T, class B = ::ndnboost::detail::empty_base<T> >           \
+struct NAME##1 : B                                                      \
+{                                                                       \
+  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
+};
+
+#define NDNBOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >  \
+struct NAME##2 : B                                                      \
+{                                                                       \
+  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
+};                                                                      \
+                                                                        \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >  \
+struct NDNBOOST_OPERATOR2_LEFT(NAME) : B                                   \
+{                                                                       \
+  friend T operator OP( const U& lhs, const T& rhs )                    \
+    { return T( lhs ) OP##= rhs; }                                      \
+};                                                                      \
+                                                                        \
+template <class T, class B = ::ndnboost::detail::empty_base<T> >           \
+struct NAME##1 : B                                                      \
+{                                                                       \
+  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
+};
+
+#endif // defined(NDNBOOST_HAS_NRVO) || defined(NDNBOOST_FORCE_SYMMETRIC_OPERATORS)
+
+NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
+NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
+NDNBOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
+NDNBOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
+NDNBOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
+NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
+NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
+NDNBOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
+
+#undef NDNBOOST_BINARY_OPERATOR_COMMUTATIVE
+#undef NDNBOOST_BINARY_OPERATOR_NON_COMMUTATIVE
+#undef NDNBOOST_OPERATOR2_LEFT
+
+//  incrementable and decrementable contributed by Jeremy Siek
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct incrementable : B
+{
+  friend T operator++(T& x, int)
+  {
+    incrementable_type nrv(x);
+    ++x;
+    return nrv;
+  }
+private: // The use of this typedef works around a Borland bug
+  typedef T incrementable_type;
+};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct decrementable : B
+{
+  friend T operator--(T& x, int)
+  {
+    decrementable_type nrv(x);
+    --x;
+    return nrv;
+  }
+private: // The use of this typedef works around a Borland bug
+  typedef T decrementable_type;
+};
+
+//  Iterator operator classes (contributed by Jeremy Siek) ------------------//
+
+template <class T, class P, class B = ::ndnboost::detail::empty_base<T> >
+struct dereferenceable : B
+{
+  P operator->() const
+  { 
+    return &*static_cast<const T&>(*this); 
+  }
+};
+
+template <class T, class I, class R, class B = ::ndnboost::detail::empty_base<T> >
+struct indexable : B
+{
+  R operator[](I n) const
+  {
+    return *(static_cast<const T&>(*this) + n);
+  }
+};
+
+//  More operator classes (contributed by Daryle Walker) --------------------//
+//  (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
+
+#if defined(NDNBOOST_HAS_NRVO) || defined(NDNBOOST_FORCE_SYMMETRIC_OPERATORS)
+
+#define NDNBOOST_BINARY_OPERATOR( NAME, OP )                                     \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >        \
+struct NAME##2 : B                                                            \
+{                                                                             \
+  friend T operator OP( const T& lhs, const U& rhs )                          \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
+};                                                                            \
+                                                                              \
+template <class T, class B = ::ndnboost::detail::empty_base<T> >                 \
+struct NAME##1 : B                                                            \
+{                                                                             \
+  friend T operator OP( const T& lhs, const T& rhs )                          \
+    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
+};
+
+#else // defined(NDNBOOST_HAS_NRVO) || defined(NDNBOOST_FORCE_SYMMETRIC_OPERATORS)
+
+#define NDNBOOST_BINARY_OPERATOR( NAME, OP )                                     \
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >        \
+struct NAME##2 : B                                                            \
+{                                                                             \
+  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
+};                                                                            \
+                                                                              \
+template <class T, class B = ::ndnboost::detail::empty_base<T> >                 \
+struct NAME##1 : B                                                            \
+{                                                                             \
+  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \
+};
+
+#endif // defined(NDNBOOST_HAS_NRVO) || defined(NDNBOOST_FORCE_SYMMETRIC_OPERATORS)
+
+NDNBOOST_BINARY_OPERATOR( left_shiftable, << )
+NDNBOOST_BINARY_OPERATOR( right_shiftable, >> )
+
+#undef NDNBOOST_BINARY_OPERATOR
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct equivalent2 : B
+{
+  friend bool operator==(const T& x, const U& y)
+  {
+    return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
+  }
+};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct equivalent1 : B
+{
+  friend bool operator==(const T&x, const T&y)
+  {
+    return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
+  }
+};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct partially_ordered2 : B
+{
+  friend bool operator<=(const T& x, const U& y)
+    { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
+  friend bool operator>=(const T& x, const U& y)
+    { return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
+  friend bool operator>(const U& x, const T& y)
+    { return y < x; }
+  friend bool operator<(const U& x, const T& y)
+    { return y > x; }
+  friend bool operator<=(const U& x, const T& y)
+    { return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
+  friend bool operator>=(const U& x, const T& y)
+    { return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
+};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct partially_ordered1 : B
+{
+  friend bool operator>(const T& x, const T& y)
+    { return y < x; }
+  friend bool operator<=(const T& x, const T& y)
+    { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
+  friend bool operator>=(const T& x, const T& y)
+    { return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
+};
+
+//  Combined operator classes (contributed by Daryle Walker) ----------------//
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct totally_ordered2
+    : less_than_comparable2<T, U
+    , equality_comparable2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct totally_ordered1
+    : less_than_comparable1<T
+    , equality_comparable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct additive2
+    : addable2<T, U
+    , subtractable2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct additive1
+    : addable1<T
+    , subtractable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct multiplicative2
+    : multipliable2<T, U
+    , dividable2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct multiplicative1
+    : multipliable1<T
+    , dividable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct integer_multiplicative2
+    : multiplicative2<T, U
+    , modable2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct integer_multiplicative1
+    : multiplicative1<T
+    , modable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct arithmetic2
+    : additive2<T, U
+    , multiplicative2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct arithmetic1
+    : additive1<T
+    , multiplicative1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct integer_arithmetic2
+    : additive2<T, U
+    , integer_multiplicative2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct integer_arithmetic1
+    : additive1<T
+    , integer_multiplicative1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct bitwise2
+    : xorable2<T, U
+    , andable2<T, U
+    , orable2<T, U, B
+      > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct bitwise1
+    : xorable1<T
+    , andable1<T
+    , orable1<T, B
+      > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct unit_steppable
+    : incrementable<T
+    , decrementable<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct shiftable2
+    : left_shiftable2<T, U
+    , right_shiftable2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct shiftable1
+    : left_shiftable1<T
+    , right_shiftable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct ring_operators2
+    : additive2<T, U
+    , subtractable2_left<T, U
+    , multipliable2<T, U, B
+      > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct ring_operators1
+    : additive1<T
+    , multipliable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_ring_operators2
+    : ring_operators2<T, U
+    , totally_ordered2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_ring_operators1
+    : ring_operators1<T
+    , totally_ordered1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct field_operators2
+    : ring_operators2<T, U
+    , dividable2<T, U
+    , dividable2_left<T, U, B
+      > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct field_operators1
+    : ring_operators1<T
+    , dividable1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_field_operators2
+    : field_operators2<T, U
+    , totally_ordered2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_field_operators1
+    : field_operators1<T
+    , totally_ordered1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct euclidian_ring_operators2
+    : ring_operators2<T, U
+    , dividable2<T, U
+    , dividable2_left<T, U
+    , modable2<T, U
+    , modable2_left<T, U, B
+      > > > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct euclidian_ring_operators1
+    : ring_operators1<T
+    , dividable1<T
+    , modable1<T, B
+      > > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_euclidian_ring_operators2
+    : totally_ordered2<T, U
+    , euclidian_ring_operators2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_euclidian_ring_operators1
+    : totally_ordered1<T
+    , euclidian_ring_operators1<T, B
+      > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct euclidean_ring_operators2
+    : ring_operators2<T, U
+    , dividable2<T, U
+    , dividable2_left<T, U
+    , modable2<T, U
+    , modable2_left<T, U, B
+      > > > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct euclidean_ring_operators1
+    : ring_operators1<T
+    , dividable1<T
+    , modable1<T, B
+      > > > {};
+
+template <class T, class U, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_euclidean_ring_operators2
+    : totally_ordered2<T, U
+    , euclidean_ring_operators2<T, U, B
+      > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct ordered_euclidean_ring_operators1
+    : totally_ordered1<T
+    , euclidean_ring_operators1<T, B
+      > > {};
+
+template <class T, class P, class B = ::ndnboost::detail::empty_base<T> >
+struct input_iteratable
+    : equality_comparable1<T
+    , incrementable<T
+    , dereferenceable<T, P, B
+      > > > {};
+
+template <class T, class B = ::ndnboost::detail::empty_base<T> >
+struct output_iteratable
+    : incrementable<T, B
+      > {};
+
+template <class T, class P, class B = ::ndnboost::detail::empty_base<T> >
+struct forward_iteratable
+    : input_iteratable<T, P, B
+      > {};
+
+template <class T, class P, class B = ::ndnboost::detail::empty_base<T> >
+struct bidirectional_iteratable
+    : forward_iteratable<T, P
+    , decrementable<T, B
+      > > {};
+
+//  To avoid repeated derivation from equality_comparable,
+//  which is an indirect base class of bidirectional_iterable,
+//  random_access_iteratable must not be derived from totally_ordered1
+//  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
+template <class T, class P, class D, class R, class B = ::ndnboost::detail::empty_base<T> >
+struct random_access_iteratable
+    : bidirectional_iteratable<T, P
+    , less_than_comparable1<T
+    , additive2<T, D
+    , indexable<T, D, R, B
+      > > > > {};
+
+#ifndef NDNBOOST_NO_OPERATORS_IN_NAMESPACE
+} // namespace ndnboost
+#endif // NDNBOOST_NO_OPERATORS_IN_NAMESPACE
+
+
+// NDNBOOST_IMPORT_TEMPLATE1 .. NDNBOOST_IMPORT_TEMPLATE4 -
+//
+// When NDNBOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
+// operator template into the boost namespace. NDNBOOST_IMPORT_TEMPLATE1 is used
+// for one-argument forms of operator templates; NDNBOOST_IMPORT_TEMPLATE2 for
+// two-argument forms. Note that these macros expect to be invoked from within
+// boost.
+
+#ifndef NDNBOOST_NO_OPERATORS_IN_NAMESPACE
+
+  // The template is already in boost so we have nothing to do.
+# define NDNBOOST_IMPORT_TEMPLATE4(template_name)
+# define NDNBOOST_IMPORT_TEMPLATE3(template_name)
+# define NDNBOOST_IMPORT_TEMPLATE2(template_name)
+# define NDNBOOST_IMPORT_TEMPLATE1(template_name)
+
+#else // NDNBOOST_NO_OPERATORS_IN_NAMESPACE
+
+#  ifndef NDNBOOST_NO_USING_TEMPLATE
+
+     // Bring the names in with a using-declaration
+     // to avoid stressing the compiler.
+#    define NDNBOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
+#    define NDNBOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
+#    define NDNBOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
+#    define NDNBOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
+
+#  else
+
+     // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
+     // from working, we are forced to use inheritance for that compiler.
+#    define NDNBOOST_IMPORT_TEMPLATE4(template_name)                                             \
+     template <class T, class U, class V, class W, class B = ::ndnboost::detail::empty_base<T> > \
+     struct template_name : ::template_name<T, U, V, W, B> {};
+
+#    define NDNBOOST_IMPORT_TEMPLATE3(template_name)                                    \
+     template <class T, class U, class V, class B = ::ndnboost::detail::empty_base<T> > \
+     struct template_name : ::template_name<T, U, V, B> {};
+
+#    define NDNBOOST_IMPORT_TEMPLATE2(template_name)                           \
+     template <class T, class U, class B = ::ndnboost::detail::empty_base<T> > \
+     struct template_name : ::template_name<T, U, B> {};
+
+#    define NDNBOOST_IMPORT_TEMPLATE1(template_name)                  \
+     template <class T, class B = ::ndnboost::detail::empty_base<T> > \
+     struct template_name : ::template_name<T, B> {};
+
+#  endif // NDNBOOST_NO_USING_TEMPLATE
+
+#endif // NDNBOOST_NO_OPERATORS_IN_NAMESPACE
+
+//
+// Here's where we put it all together, defining the xxxx forms of the templates
+// in namespace ndnboost. We also define specializations of is_chained_base<> for
+// the xxxx, xxxx1, and xxxx2 templates, importing them into ndnboost:: as
+// necessary.
+//
+#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+// is_chained_base<> - a traits class used to distinguish whether an operator
+// template argument is being used for base class chaining, or is specifying a
+// 2nd argument type.
+
+namespace ndnboost {
+// A type parameter is used instead of a plain bool because Borland's compiler
+// didn't cope well with the more obvious non-type template parameter.
+namespace detail {
+  struct true_t {};
+  struct false_t {};
+} // namespace detail
+
+// Unspecialized version assumes that most types are not being used for base
+// class chaining. We specialize for the operator templates defined in this
+// library.
+template<class T> struct is_chained_base {
+  typedef ::ndnboost::detail::false_t value;
+};
+
+} // namespace ndnboost
+
+// Import a 4-type-argument operator template into boost (if necessary) and
+// provide a specialization of 'is_chained_base<>' for it.
+# define NDNBOOST_OPERATOR_TEMPLATE4(template_name4)                     \
+  NDNBOOST_IMPORT_TEMPLATE4(template_name4)                              \
+  template<class T, class U, class V, class W, class B>               \
+  struct is_chained_base< ::ndnboost::template_name4<T, U, V, W, B> > {  \
+    typedef ::ndnboost::detail::true_t value;                            \
+  };
+
+// Import a 3-type-argument operator template into boost (if necessary) and
+// provide a specialization of 'is_chained_base<>' for it.
+# define NDNBOOST_OPERATOR_TEMPLATE3(template_name3)                     \
+  NDNBOOST_IMPORT_TEMPLATE3(template_name3)                              \
+  template<class T, class U, class V, class B>                        \
+  struct is_chained_base< ::ndnboost::template_name3<T, U, V, B> > {     \
+    typedef ::ndnboost::detail::true_t value;                            \
+  };
+
+// Import a 2-type-argument operator template into boost (if necessary) and
+// provide a specialization of 'is_chained_base<>' for it.
+# define NDNBOOST_OPERATOR_TEMPLATE2(template_name2)                  \
+  NDNBOOST_IMPORT_TEMPLATE2(template_name2)                           \
+  template<class T, class U, class B>                              \
+  struct is_chained_base< ::ndnboost::template_name2<T, U, B> > {     \
+    typedef ::ndnboost::detail::true_t value;                         \
+  };
+
+// Import a 1-type-argument operator template into boost (if necessary) and
+// provide a specialization of 'is_chained_base<>' for it.
+# define NDNBOOST_OPERATOR_TEMPLATE1(template_name1)                  \
+  NDNBOOST_IMPORT_TEMPLATE1(template_name1)                           \
+  template<class T, class B>                                       \
+  struct is_chained_base< ::ndnboost::template_name1<T, B> > {        \
+    typedef ::ndnboost::detail::true_t value;                         \
+  };
+
+// NDNBOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
+// can be used for specifying both 1-argument and 2-argument forms. Requires the
+// existence of two previously defined class templates named '<template_name>1'
+// and '<template_name>2' which must implement the corresponding 1- and 2-
+// argument forms.
+//
+// The template type parameter O == is_chained_base<U>::value is used to
+// distinguish whether the 2nd argument to <template_name> is being used for
+// base class chaining from another boost operator template or is describing a
+// 2nd operand type. O == true_t only when U is actually an another operator
+// template from the library. Partial specialization is used to select an
+// implementation in terms of either '<template_name>1' or '<template_name>2'.
+//
+
+# define NDNBOOST_OPERATOR_TEMPLATE(template_name)                    \
+template <class T                                                  \
+         ,class U = T                                              \
+         ,class B = ::ndnboost::detail::empty_base<T>                 \
+         ,class O = typename is_chained_base<U>::value             \
+         >                                                         \
+struct template_name : template_name##2<T, U, B> {};               \
+                                                                   \
+template<class T, class U, class B>                                \
+struct template_name<T, U, B, ::ndnboost::detail::true_t>             \
+  : template_name##1<T, U> {};                                     \
+                                                                   \
+template <class T, class B>                                        \
+struct template_name<T, T, B, ::ndnboost::detail::false_t>            \
+  : template_name##1<T, B> {};                                     \
+                                                                   \
+template<class T, class U, class B, class O>                       \
+struct is_chained_base< ::ndnboost::template_name<T, U, B, O> > {     \
+  typedef ::ndnboost::detail::true_t value;                           \
+};                                                                 \
+                                                                   \
+NDNBOOST_OPERATOR_TEMPLATE2(template_name##2)                         \
+NDNBOOST_OPERATOR_TEMPLATE1(template_name##1)
+
+
+#else // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#  define NDNBOOST_OPERATOR_TEMPLATE4(template_name4) \
+        NDNBOOST_IMPORT_TEMPLATE4(template_name4)
+#  define NDNBOOST_OPERATOR_TEMPLATE3(template_name3) \
+        NDNBOOST_IMPORT_TEMPLATE3(template_name3)
+#  define NDNBOOST_OPERATOR_TEMPLATE2(template_name2) \
+        NDNBOOST_IMPORT_TEMPLATE2(template_name2)
+#  define NDNBOOST_OPERATOR_TEMPLATE1(template_name1) \
+        NDNBOOST_IMPORT_TEMPLATE1(template_name1)
+
+   // In this case we can only assume that template_name<> is equivalent to the
+   // more commonly needed template_name1<> form.
+#  define NDNBOOST_OPERATOR_TEMPLATE(template_name)                   \
+   template <class T, class B = ::ndnboost::detail::empty_base<T> >   \
+   struct template_name : template_name##1<T, B> {};
+
+#endif // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+namespace ndnboost {
+    
+NDNBOOST_OPERATOR_TEMPLATE(less_than_comparable)
+NDNBOOST_OPERATOR_TEMPLATE(equality_comparable)
+NDNBOOST_OPERATOR_TEMPLATE(multipliable)
+NDNBOOST_OPERATOR_TEMPLATE(addable)
+NDNBOOST_OPERATOR_TEMPLATE(subtractable)
+NDNBOOST_OPERATOR_TEMPLATE2(subtractable2_left)
+NDNBOOST_OPERATOR_TEMPLATE(dividable)
+NDNBOOST_OPERATOR_TEMPLATE2(dividable2_left)
+NDNBOOST_OPERATOR_TEMPLATE(modable)
+NDNBOOST_OPERATOR_TEMPLATE2(modable2_left)
+NDNBOOST_OPERATOR_TEMPLATE(xorable)
+NDNBOOST_OPERATOR_TEMPLATE(andable)
+NDNBOOST_OPERATOR_TEMPLATE(orable)
+
+NDNBOOST_OPERATOR_TEMPLATE1(incrementable)
+NDNBOOST_OPERATOR_TEMPLATE1(decrementable)
+
+NDNBOOST_OPERATOR_TEMPLATE2(dereferenceable)
+NDNBOOST_OPERATOR_TEMPLATE3(indexable)
+
+NDNBOOST_OPERATOR_TEMPLATE(left_shiftable)
+NDNBOOST_OPERATOR_TEMPLATE(right_shiftable)
+NDNBOOST_OPERATOR_TEMPLATE(equivalent)
+NDNBOOST_OPERATOR_TEMPLATE(partially_ordered)
+
+NDNBOOST_OPERATOR_TEMPLATE(totally_ordered)
+NDNBOOST_OPERATOR_TEMPLATE(additive)
+NDNBOOST_OPERATOR_TEMPLATE(multiplicative)
+NDNBOOST_OPERATOR_TEMPLATE(integer_multiplicative)
+NDNBOOST_OPERATOR_TEMPLATE(arithmetic)
+NDNBOOST_OPERATOR_TEMPLATE(integer_arithmetic)
+NDNBOOST_OPERATOR_TEMPLATE(bitwise)
+NDNBOOST_OPERATOR_TEMPLATE1(unit_steppable)
+NDNBOOST_OPERATOR_TEMPLATE(shiftable)
+NDNBOOST_OPERATOR_TEMPLATE(ring_operators)
+NDNBOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
+NDNBOOST_OPERATOR_TEMPLATE(field_operators)
+NDNBOOST_OPERATOR_TEMPLATE(ordered_field_operators)
+NDNBOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
+NDNBOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
+NDNBOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
+NDNBOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
+NDNBOOST_OPERATOR_TEMPLATE2(input_iteratable)
+NDNBOOST_OPERATOR_TEMPLATE1(output_iteratable)
+NDNBOOST_OPERATOR_TEMPLATE2(forward_iteratable)
+NDNBOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
+NDNBOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
+
+#undef NDNBOOST_OPERATOR_TEMPLATE
+#undef NDNBOOST_OPERATOR_TEMPLATE4
+#undef NDNBOOST_OPERATOR_TEMPLATE3
+#undef NDNBOOST_OPERATOR_TEMPLATE2
+#undef NDNBOOST_OPERATOR_TEMPLATE1
+#undef NDNBOOST_IMPORT_TEMPLATE1
+#undef NDNBOOST_IMPORT_TEMPLATE2
+#undef NDNBOOST_IMPORT_TEMPLATE3
+#undef NDNBOOST_IMPORT_TEMPLATE4
+
+// The following 'operators' classes can only be used portably if the derived class
+// declares ALL of the required member operators.
+template <class T, class U>
+struct operators2
+    : totally_ordered2<T,U
+    , integer_arithmetic2<T,U
+    , bitwise2<T,U
+      > > > {};
+
+#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <class T, class U = T>
+struct operators : operators2<T, U> {};
+
+template <class T> struct operators<T, T>
+#else
+template <class T> struct operators
+#endif
+    : totally_ordered<T
+    , integer_arithmetic<T
+    , bitwise<T
+    , unit_steppable<T
+      > > > > {};
+
+//  Iterator helper classes (contributed by Jeremy Siek) -------------------//
+//  (Input and output iterator helpers contributed by Daryle Walker) -------//
+//  (Changed to use combined operator classes by Daryle Walker) ------------//
+template <class T,
+          class V,
+          class D = std::ptrdiff_t,
+          class P = V const *,
+          class R = V const &>
+struct input_iterator_helper
+  : input_iteratable<T, P
+  , ndnboost::iterator<std::input_iterator_tag, V, D, P, R
+    > > {};
+
+template<class T>
+struct output_iterator_helper
+  : output_iteratable<T
+  , ndnboost::iterator<std::output_iterator_tag, void, void, void, void
+  > >
+{
+  T& operator*()  { return static_cast<T&>(*this); }
+  T& operator++() { return static_cast<T&>(*this); }
+};
+
+template <class T,
+          class V,
+          class D = std::ptrdiff_t,
+          class P = V*,
+          class R = V&>
+struct forward_iterator_helper
+  : forward_iteratable<T, P
+  , ndnboost::iterator<std::forward_iterator_tag, V, D, P, R
+    > > {};
+
+template <class T,
+          class V,
+          class D = std::ptrdiff_t,
+          class P = V*,
+          class R = V&>
+struct bidirectional_iterator_helper
+  : bidirectional_iteratable<T, P
+  , ndnboost::iterator<std::bidirectional_iterator_tag, V, D, P, R
+    > > {};
+
+template <class T,
+          class V, 
+          class D = std::ptrdiff_t,
+          class P = V*,
+          class R = V&>
+struct random_access_iterator_helper
+  : random_access_iteratable<T, P, D, R
+  , ndnboost::iterator<std::random_access_iterator_tag, V, D, P, R
+    > >
+{
+  friend D requires_difference_operator(const T& x, const T& y) {
+    return x - y;
+  }
+}; // random_access_iterator_helper
+
+} // namespace ndnboost
+
+#if defined(__sgi) && !defined(__GNUC__)
+#pragma reset woff 1234
+#endif
+
+#endif // NDNBOOST_OPERATORS_HPP
diff --git a/include/ndnboost/pending/integer_log2.hpp b/include/ndnboost/pending/integer_log2.hpp
new file mode 100644
index 0000000..d8504db
--- /dev/null
+++ b/include/ndnboost/pending/integer_log2.hpp
@@ -0,0 +1,112 @@
+// -----------------------------------------------------------
+// integer_log2.hpp
+//
+//   Gives the integer part of the logarithm, in base 2, of a
+// given number. Behavior is undefined if the argument is <= 0.
+//
+//         Copyright (c) 2003-2004, 2008 Gennaro Prota
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// -----------------------------------------------------------
+
+#ifndef NDNBOOST_INTEGER_LOG2_HPP_GP_20030301
+#define NDNBOOST_INTEGER_LOG2_HPP_GP_20030301
+
+#include <assert.h>
+#ifdef __BORLANDC__
+#include <climits>
+#endif
+#include "ndnboost/limits.hpp"
+#include "ndnboost/config.hpp"
+
+
+namespace ndnboost {
+ namespace detail {
+
+  template <typename T>
+  int integer_log2_impl(T x, int n) {
+
+      int result = 0;
+
+      while (x != 1) {
+
+          const T t = static_cast<T>(x >> n);
+          if (t) {
+              result += n;
+              x = t;
+          }
+          n /= 2;
+
+      }
+
+      return result;
+  }
+
+
+
+  // helper to find the maximum power of two
+  // less than p (more involved than necessary,
+  // to avoid PTS)
+  //
+  template <int p, int n>
+  struct max_pow2_less {
+
+      enum { c = 2*n < p };
+
+      NDNBOOST_STATIC_CONSTANT(int, value =
+          c ? (max_pow2_less< c*p, 2*c*n>::value) : n);
+
+  };
+
+  template <>
+  struct max_pow2_less<0, 0> {
+
+      NDNBOOST_STATIC_CONSTANT(int, value = 0);
+  };
+
+  // this template is here just for Borland :(
+  // we could simply rely on numeric_limits but sometimes
+  // Borland tries to use numeric_limits<const T>, because
+  // of its usual const-related problems in argument deduction
+  // - gps
+  template <typename T>
+  struct width {
+
+#ifdef __BORLANDC__
+      NDNBOOST_STATIC_CONSTANT(int, value = sizeof(T) * CHAR_BIT);
+#else
+      NDNBOOST_STATIC_CONSTANT(int, value = (std::numeric_limits<T>::digits));
+#endif
+
+  };
+
+ } // detail
+
+
+ // ---------
+ // integer_log2
+ // ---------------
+ //
+ template <typename T>
+ int integer_log2(T x) {
+
+     assert(x > 0);
+
+     const int n = detail::max_pow2_less<
+                     detail::width<T> :: value, 4
+                   > :: value;
+
+     return detail::integer_log2_impl(x, n);
+
+ }
+
+
+
+}
+
+
+
+#endif // include guard
diff --git a/include/ndnboost/random/detail/config.hpp b/include/ndnboost/random/detail/config.hpp
new file mode 100644
index 0000000..0d7f7bb
--- /dev/null
+++ b/include/ndnboost/random/detail/config.hpp
@@ -0,0 +1,18 @@
+/* boost random/detail/config.hpp header file
+ *
+ * Copyright Steven Watanabe 2009
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: config.hpp 52492 2009-04-19 14:55:57Z steven_watanabe $
+ */
+
+#include <ndnboost/config.hpp>
+
+#if (defined(NDNBOOST_NO_OPERATORS_IN_NAMESPACE) || defined(NDNBOOST_NO_MEMBER_TEMPLATE_FRIENDS)) \
+    && !defined(NDNBOOST_MSVC)
+    #define NDNBOOST_RANDOM_NO_STREAM_OPERATORS
+#endif
diff --git a/include/ndnboost/random/detail/const_mod.hpp b/include/ndnboost/random/detail/const_mod.hpp
new file mode 100644
index 0000000..20277f2
--- /dev/null
+++ b/include/ndnboost/random/detail/const_mod.hpp
@@ -0,0 +1,216 @@
+/* boost random/detail/const_mod.hpp header file
+ *
+ * Copyright Jens Maurer 2000-2001
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: const_mod.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ * Revision history
+ *  2001-02-18  moved to individual header files
+ */
+
+#ifndef NDNBOOST_RANDOM_CONST_MOD_HPP
+#define NDNBOOST_RANDOM_CONST_MOD_HPP
+
+#include <ndnboost/assert.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/integer_traits.hpp>
+#include <ndnboost/type_traits/make_unsigned.hpp>
+#include <ndnboost/random/detail/large_arithmetic.hpp>
+
+#include <ndnboost/random/detail/disable_warnings.hpp>
+
+namespace ndnboost {
+namespace random {
+
+template<class IntType, IntType m>
+class const_mod
+{
+public:
+  static IntType apply(IntType x)
+  {
+    if(((unsigned_m() - 1) & unsigned_m()) == 0)
+      return (unsigned_type(x)) & (unsigned_m() - 1);
+    else {
+      IntType supress_warnings = (m == 0);
+      NDNBOOST_ASSERT(supress_warnings == 0);
+      return x % (m + supress_warnings);
+    }
+  }
+
+  static IntType add(IntType x, IntType c)
+  {
+    if(((unsigned_m() - 1) & unsigned_m()) == 0)
+      return (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1);
+    else if(c == 0)
+      return x;
+    else if(x < m - c)
+      return x + c;
+    else
+      return x - (m - c);
+  }
+
+  static IntType mult(IntType a, IntType x)
+  {
+    if(((unsigned_m() - 1) & unsigned_m()) == 0)
+      return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1);
+    else if(a == 0)
+      return 0;
+    else if(a == 1)
+      return x;
+    else if(m <= traits::const_max/a)      // i.e. a*m <= max
+      return mult_small(a, x);
+    else if(traits::is_signed && (m%a < m/a))
+      return mult_schrage(a, x);
+    else
+      return mult_general(a, x);
+  }
+
+  static IntType mult_add(IntType a, IntType x, IntType c)
+  {
+    if(((unsigned_m() - 1) & unsigned_m()) == 0)
+      return (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1);
+    else if(a == 0)
+      return c;
+    else if(m <= (traits::const_max-c)/a) {  // i.e. a*m+c <= max
+      IntType supress_warnings = (m == 0);
+      NDNBOOST_ASSERT(supress_warnings == 0);
+      return (a*x+c) % (m + supress_warnings);
+    } else
+      return add(mult(a, x), c);
+  }
+
+  static IntType pow(IntType a, ndnboost::uintmax_t exponent)
+  {
+      IntType result = 1;
+      while(exponent != 0) {
+          if(exponent % 2 == 1) {
+              result = mult(result, a);
+          }
+          a = mult(a, a);
+          exponent /= 2;
+      }
+      return result;
+  }
+
+  static IntType invert(IntType x)
+  { return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); }
+
+private:
+  typedef integer_traits<IntType> traits;
+  typedef typename make_unsigned<IntType>::type unsigned_type;
+
+  const_mod();      // don't instantiate
+
+  static IntType mult_small(IntType a, IntType x)
+  {
+    IntType supress_warnings = (m == 0);
+    NDNBOOST_ASSERT(supress_warnings == 0);
+    return a*x % (m + supress_warnings);
+  }
+
+  static IntType mult_schrage(IntType a, IntType value)
+  {
+    const IntType q = m / a;
+    const IntType r = m % a;
+
+    NDNBOOST_ASSERT(r < q);        // check that overflow cannot happen
+
+    return sub(a*(value%q), r*(value/q));
+  }
+
+  static IntType mult_general(IntType a, IntType b)
+  {
+    IntType suppress_warnings = (m == 0);
+    NDNBOOST_ASSERT(suppress_warnings == 0);
+    IntType modulus = m + suppress_warnings;
+    NDNBOOST_ASSERT(modulus == m);
+    if(::ndnboost::uintmax_t(modulus) <=
+        (::std::numeric_limits< ::ndnboost::uintmax_t>::max)() / modulus)
+    {
+      return static_cast<IntType>(ndnboost::uintmax_t(a) * b % modulus);
+    } else {
+      return static_cast<IntType>(detail::mulmod(a, b, modulus));
+    }
+  }
+
+  static IntType sub(IntType a, IntType b)
+  {
+    if(a < b)
+      return m - (b - a);
+    else
+      return a - b;
+  }
+
+  static unsigned_type unsigned_m()
+  {
+      if(m == 0) {
+          return unsigned_type((std::numeric_limits<IntType>::max)()) + 1;
+      } else {
+          return unsigned_type(m);
+      }
+  }
+
+  // invert c in the finite field (mod m) (m must be prime)
+  static IntType invert_euclidian(IntType c)
+  {
+    // we are interested in the gcd factor for c, because this is our inverse
+    NDNBOOST_ASSERT(c > 0);
+    IntType l1 = 0;
+    IntType l2 = 1;
+    IntType n = c;
+    IntType p = m;
+    for(;;) {
+      IntType q = p / n;
+      l1 += q * l2;
+      p -= q * n;
+      if(p == 0)
+        return l2;
+      IntType q2 = n / p;
+      l2 += q2 * l1;
+      n -= q2 * p;
+      if(n == 0)
+        return m - l1;
+    }
+  }
+
+  // invert c in the finite field (mod m) (c must be relatively prime to m)
+  static IntType invert_euclidian0(IntType c)
+  {
+    // we are interested in the gcd factor for c, because this is our inverse
+    NDNBOOST_ASSERT(c > 0);
+    if(c == 1) return 1;
+    IntType l1 = 0;
+    IntType l2 = 1;
+    IntType n = c;
+    IntType p = m;
+    IntType max = (std::numeric_limits<IntType>::max)();
+    IntType q = max / n;
+    NDNBOOST_ASSERT(max % n != n - 1 && "c must be relatively prime to m.");
+    l1 += q * l2;
+    p = max - q * n + 1;
+    for(;;) {
+      if(p == 0)
+        return l2;
+      IntType q2 = n / p;
+      l2 += q2 * l1;
+      n -= q2 * p;
+      if(n == 0)
+        return m - l1;
+      q = p / n;
+      l1 += q * l2;
+      p -= q * n;
+    }
+  }
+};
+
+} // namespace random
+} // namespace ndnboost
+
+#include <ndnboost/random/detail/enable_warnings.hpp>
+
+#endif // NDNBOOST_RANDOM_CONST_MOD_HPP
diff --git a/include/ndnboost/random/detail/disable_warnings.hpp b/include/ndnboost/random/detail/disable_warnings.hpp
new file mode 100644
index 0000000..4f707d0
--- /dev/null
+++ b/include/ndnboost/random/detail/disable_warnings.hpp
@@ -0,0 +1,23 @@
+/* boost random/detail/disable_warnings.hpp header file
+ *
+ * Copyright Steven Watanabe 2009
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: disable_warnings.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $
+ *
+ */
+
+// No #include guard.  This header is intended to be included multiple times.
+
+#include <ndnboost/config.hpp>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4512)
+#pragma warning(disable:4127)
+#pragma warning(disable:4724)
+#endif
diff --git a/include/ndnboost/random/detail/enable_warnings.hpp b/include/ndnboost/random/detail/enable_warnings.hpp
new file mode 100644
index 0000000..68535e2
--- /dev/null
+++ b/include/ndnboost/random/detail/enable_warnings.hpp
@@ -0,0 +1,18 @@
+/* boost random/detail/enable_warnings.hpp header file
+ *
+ * Copyright Steven Watanabe 2009
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: enable_warnings.hpp 58649 2010-01-02 21:23:17Z steven_watanabe $
+ *
+ */
+
+// No #include guard.  This header is intended to be included multiple times.
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
diff --git a/include/ndnboost/random/detail/generator_bits.hpp b/include/ndnboost/random/detail/generator_bits.hpp
new file mode 100644
index 0000000..94d49d6
--- /dev/null
+++ b/include/ndnboost/random/detail/generator_bits.hpp
@@ -0,0 +1,36 @@
+/* boost random/detail/generator_bits.hpp header file
+ *
+ * Copyright Steven Watanabe 2011
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: generator_bits.hpp 72951 2011-07-07 04:57:37Z steven_watanabe $
+ *
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP
+#define NDNBOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP
+
+#include <ndnboost/limits.hpp>
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+// This is a temporary measure that retains backwards
+// compatibility.
+template<class URNG>
+struct generator_bits {
+    static std::size_t value() {
+        return std::numeric_limits<typename URNG::result_type>::digits;
+    }
+};
+
+} // namespace detail
+} // namespace random
+} // namespace ndnboost
+
+#endif // NDNBOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP
diff --git a/include/ndnboost/random/detail/integer_log2.hpp b/include/ndnboost/random/detail/integer_log2.hpp
new file mode 100644
index 0000000..f7429af
--- /dev/null
+++ b/include/ndnboost/random/detail/integer_log2.hpp
@@ -0,0 +1,84 @@
+/* boost random/detail/integer_log2.hpp header file
+ *
+ * Copyright Steven Watanabe 2011
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: integer_log2.hpp 83381 2013-03-09 22:55:05Z eric_niebler $
+ *
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
+#define NDNBOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/pending/integer_log2.hpp>
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+#if !defined(NDNBOOST_NO_CXX11_CONSTEXPR)
+#define NDNBOOST_RANDOM_DETAIL_CONSTEXPR constexpr
+#elif defined(NDNBOOST_MSVC)
+#define NDNBOOST_RANDOM_DETAIL_CONSTEXPR __forceinline
+#elif defined(__GNUC__) && __GNUC__ >= 4
+#define NDNBOOST_RANDOM_DETAIL_CONSTEXPR inline __attribute__((const)) __attribute__((always_inline))
+#else
+#define NDNBOOST_RANDOM_DETAIL_CONSTEXPR inline
+#endif
+
+template<int Shift>
+struct integer_log2_impl
+{
+#if defined(NDNBOOST_NO_CXX11_CONSTEXPR)
+    template<class T>
+    NDNBOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
+    {
+        int update = ((t >> Shift) != 0) * Shift;
+        return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
+    }
+#else
+    template<class T>
+    NDNBOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update)
+    {
+        return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
+    }
+
+    template<class T>
+    NDNBOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
+    {
+        return apply2(t, accum, ((t >> Shift) != 0) * Shift);
+    }
+#endif
+};
+
+template<>
+struct integer_log2_impl<1>
+{
+    template<class T>
+    NDNBOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
+    {
+        return int(t >> 1) + accum;
+    }
+};
+
+template<class T>
+NDNBOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t)
+{
+    return integer_log2_impl<
+        ::ndnboost::detail::max_pow2_less<
+            ::std::numeric_limits<T>::digits, 4
+        >::value
+    >::apply(t, 0);
+}
+
+} // namespace detail
+} // namespace random
+} // namespace ndnboost
+
+#endif // NDNBOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
diff --git a/include/ndnboost/random/detail/large_arithmetic.hpp b/include/ndnboost/random/detail/large_arithmetic.hpp
new file mode 100644
index 0000000..c9c6434
--- /dev/null
+++ b/include/ndnboost/random/detail/large_arithmetic.hpp
@@ -0,0 +1,122 @@
+/* boost random/detail/large_arithmetic.hpp header file
+ *
+ * Copyright Steven Watanabe 2011
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: large_arithmetic.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
+#define NDNBOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
+
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/integer.hpp>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/random/detail/integer_log2.hpp>
+
+#include <ndnboost/random/detail/disable_warnings.hpp>
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+struct div_t {
+    ndnboost::uintmax_t quotient;
+    ndnboost::uintmax_t remainder;
+};
+
+inline div_t muldivmod(ndnboost::uintmax_t a, ndnboost::uintmax_t b, ndnboost::uintmax_t m)
+{
+    static const int bits =
+        ::std::numeric_limits< ::ndnboost::uintmax_t>::digits / 2;
+    static const ::ndnboost::uintmax_t mask = (::ndnboost::uintmax_t(1) << bits) - 1;
+    typedef ::ndnboost::uint_t<bits>::fast digit_t;
+
+    int shift = std::numeric_limits< ::ndnboost::uintmax_t>::digits - 1
+        - detail::integer_log2(m);
+
+    a <<= shift;
+    m <<= shift;
+
+    digit_t product[4] = { 0, 0, 0, 0 };
+    digit_t a_[2] = { digit_t(a & mask), digit_t((a >> bits) & mask) };
+    digit_t b_[2] = { digit_t(b & mask), digit_t((b >> bits) & mask) };
+    digit_t m_[2] = { digit_t(m & mask), digit_t((m >> bits) & mask) };
+
+    // multiply a * b
+    for(int i = 0; i < 2; ++i) {
+        digit_t carry = 0;
+        for(int j = 0; j < 2; ++j) {
+            ::ndnboost::uint64_t temp = ::ndnboost::uintmax_t(a_[i]) * b_[j] +
+                carry + product[i + j];
+            product[i + j] = digit_t(temp & mask);
+            carry = digit_t(temp >> bits);
+        }
+        if(carry != 0) {
+            product[i + 2] += carry;
+        }
+    }
+
+    digit_t quotient[2];
+
+    if(m == 0) {
+        div_t result = {
+            ((::ndnboost::uintmax_t(product[3]) << bits) | product[2]),
+            ((::ndnboost::uintmax_t(product[1]) << bits) | product[0]) >> shift,
+        };
+        return result;
+    }
+
+    // divide product / m
+    for(int i = 3; i >= 2; --i) {
+        ::ndnboost::uintmax_t temp =
+            ::ndnboost::uintmax_t(product[i]) << bits | product[i - 1];
+
+        digit_t q = digit_t((product[i] == m_[1]) ? mask : temp / m_[1]);
+
+        ::ndnboost::uintmax_t rem =
+            ((temp - ::ndnboost::uintmax_t(q) * m_[1]) << bits) + product[i - 2];
+
+        ::ndnboost::uintmax_t diff = m_[0] * ::ndnboost::uintmax_t(q);
+
+        int error = 0;
+        if(diff > rem) {
+            if(diff - rem > m) {
+                error = 2;
+            } else {
+                error = 1;
+            }
+        }
+        q -= error;
+        rem = rem + error * m - diff;
+
+        quotient[i - 2] = q;
+        product[i] = 0;
+        product[i-1] = (rem >> bits) & mask;
+        product[i-2] = rem & mask;
+    }
+
+    div_t result = {
+        ((::ndnboost::uintmax_t(quotient[1]) << bits) | quotient[0]),
+        ((::ndnboost::uintmax_t(product[1]) << bits) | product[0]) >> shift,
+    };
+    return result;
+}
+
+inline ndnboost::uintmax_t muldiv(ndnboost::uintmax_t a, ndnboost::uintmax_t b, ndnboost::uintmax_t m)
+{ return detail::muldivmod(a, b, m).quotient; }
+
+inline ndnboost::uintmax_t mulmod(ndnboost::uintmax_t a, ndnboost::uintmax_t b, ndnboost::uintmax_t m)
+{ return detail::muldivmod(a, b, m).remainder; }
+
+} // namespace detail
+} // namespace random
+} // namespace ndnboost
+
+#include <ndnboost/random/detail/enable_warnings.hpp>
+
+#endif // NDNBOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
diff --git a/include/ndnboost/random/detail/operators.hpp b/include/ndnboost/random/detail/operators.hpp
new file mode 100644
index 0000000..4df4881
--- /dev/null
+++ b/include/ndnboost/random/detail/operators.hpp
@@ -0,0 +1,84 @@
+/* boost random/detail/operators.hpp header file
+ *
+ * Copyright Steven Watanabe 2010-2011
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: operators.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_OPERATORS_HPP
+#define NDNBOOST_RANDOM_DETAIL_OPERATORS_HPP
+
+#include <ndnboost/random/detail/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1310)   \
+    || NDNBOOST_WORKAROUND(__SUNPRO_CC, NDNBOOST_TESTED_AT(0x5100))
+
+#define NDNBOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t)                  \
+    template<class CharT, class Traits>                                 \
+    friend std::basic_ostream<CharT,Traits>&                            \
+    operator<<(std::basic_ostream<CharT,Traits>& os, const T& t) {      \
+        t.print(os, t);                                                 \
+        return os;                                                      \
+    }                                                                   \
+    template<class CharT, class Traits>                                 \
+    static std::basic_ostream<CharT,Traits>&                            \
+    print(std::basic_ostream<CharT,Traits>& os, const T& t)
+
+#define NDNBOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t)                  \
+    template<class CharT, class Traits>                                 \
+    friend std::basic_istream<CharT,Traits>&                            \
+    operator>>(std::basic_istream<CharT,Traits>& is, T& t) {            \
+        t.read(is, t);                                                  \
+        return is;                                                      \
+    }                                                                   \
+    template<class CharT, class Traits>                                 \
+    static std::basic_istream<CharT,Traits>&                            \
+    read(std::basic_istream<CharT,Traits>& is, T& t)
+
+#endif
+
+#if defined(__BORLANDC__)
+
+#define NDNBOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs)              \
+    bool operator==(const T& rhs) const                                 \
+    { return T::is_equal(*this, rhs); }                                 \
+    static bool is_equal(const T& lhs, const T& rhs)
+
+#define NDNBOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T)                      \
+    bool operator!=(const T& rhs) const                                 \
+    { return !T::is_equal(*this, rhs); }
+
+#endif
+
+#ifndef NDNBOOST_RANDOM_DETAIL_OSTREAM_OPERATOR
+#define NDNBOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t)                  \
+    template<class CharT, class Traits>                                 \
+    friend std::basic_ostream<CharT,Traits>&                            \
+    operator<<(std::basic_ostream<CharT,Traits>& os, const T& t)
+#endif
+
+#ifndef NDNBOOST_RANDOM_DETAIL_ISTREAM_OPERATOR
+#define NDNBOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t)                  \
+    template<class CharT, class Traits>                                 \
+    friend std::basic_istream<CharT,Traits>&                            \
+    operator>>(std::basic_istream<CharT,Traits>& is, T& t)
+#endif
+
+#ifndef NDNBOOST_RANDOM_DETAIL_EQUALITY_OPERATOR
+#define NDNBOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs)              \
+    friend bool operator==(const T& lhs, const T& rhs)
+#endif
+
+#ifndef NDNBOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR
+#define NDNBOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T)                      \
+    friend bool operator!=(const T& lhs, const T& rhs)                  \
+    { return !(lhs == rhs); }
+#endif
+
+#endif
diff --git a/include/ndnboost/random/detail/ptr_helper.hpp b/include/ndnboost/random/detail/ptr_helper.hpp
new file mode 100644
index 0000000..c07a88a
--- /dev/null
+++ b/include/ndnboost/random/detail/ptr_helper.hpp
@@ -0,0 +1,94 @@
+/* boost random/detail/ptr_helper.hpp header file
+ *
+ * Copyright Jens Maurer 2002
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: ptr_helper.hpp 24096 2004-07-27 03:43:34Z dgregor $
+ *
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_PTR_HELPER_HPP
+#define NDNBOOST_RANDOM_DETAIL_PTR_HELPER_HPP
+
+#include <ndnboost/config.hpp>
+
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+// type_traits could help here, but I don't want to depend on type_traits.
+template<class T>
+struct ptr_helper
+{
+  typedef T value_type;
+  typedef T& reference_type;
+  typedef const T& rvalue_type;
+  static reference_type ref(T& r) { return r; }
+  static const T& ref(const T& r) { return r; }
+};
+
+#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template<class T>
+struct ptr_helper<T&>
+{
+  typedef T value_type;
+  typedef T& reference_type;
+  typedef T& rvalue_type;
+  static reference_type ref(T& r) { return r; }
+  static const T& ref(const T& r) { return r; }
+};
+
+template<class T>
+struct ptr_helper<T*>
+{
+  typedef T value_type;
+  typedef T& reference_type;
+  typedef T* rvalue_type;
+  static reference_type ref(T * p) { return *p; }
+  static const T& ref(const T * p) { return *p; }
+};
+#endif
+
+} // namespace detail
+} // namespace random
+} // namespace ndnboost
+
+//
+// NDNBOOST_RANDOM_PTR_HELPER_SPEC --
+//
+//  Helper macro for broken compilers defines specializations of
+//  ptr_helper.
+//
+#ifdef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+# define NDNBOOST_RANDOM_PTR_HELPER_SPEC(T)                \
+namespace ndnboost { namespace random { namespace detail { \
+template<>                                              \
+struct ptr_helper<T&>                                   \
+{                                                       \
+  typedef T value_type;                                 \
+  typedef T& reference_type;                            \
+  typedef T& rvalue_type;                               \
+  static reference_type ref(T& r) { return r; }         \
+  static const T& ref(const T& r) { return r; }         \
+};                                                      \
+                                                        \
+template<>                                              \
+struct ptr_helper<T*>                                   \
+{                                                       \
+  typedef T value_type;                                 \
+  typedef T& reference_type;                            \
+  typedef T* rvalue_type;                               \
+  static reference_type ref(T * p) { return *p; }       \
+  static const T& ref(const T * p) { return *p; }       \
+};                                                      \
+}}}
+#else
+# define NDNBOOST_RANDOM_PTR_HELPER_SPEC(T)
+#endif 
+
+#endif // NDNBOOST_RANDOM_DETAIL_PTR_HELPER_HPP
diff --git a/include/ndnboost/random/detail/seed.hpp b/include/ndnboost/random/detail/seed.hpp
new file mode 100644
index 0000000..7f5ac2b
--- /dev/null
+++ b/include/ndnboost/random/detail/seed.hpp
@@ -0,0 +1,114 @@
+/* boost random/detail/seed.hpp header file
+ *
+ * Copyright Steven Watanabe 2009
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: seed.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_SEED_HPP
+#define NDNBOOST_RANDOM_DETAIL_SEED_HPP
+
+#include <ndnboost/config.hpp>
+
+// Sun seems to have trouble with the use of SFINAE for the
+// templated constructor.  So does Borland.
+#if !defined(NDNBOOST_NO_SFINAE) && !defined(__SUNPRO_CC) && !defined(__BORLANDC__)
+
+#include <ndnboost/utility/enable_if.hpp>
+#include <ndnboost/type_traits/is_arithmetic.hpp>
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+template<class T>
+struct disable_seed : ndnboost::disable_if<ndnboost::is_arithmetic<T> > {};
+
+template<class Engine, class T>
+struct disable_constructor : disable_seed<T> {};
+
+template<class Engine>
+struct disable_constructor<Engine, Engine> {};
+
+#define NDNBOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \
+    template<class Generator>                                           \
+    explicit Self(Generator& gen, typename ::ndnboost::random::detail::disable_constructor<Self, Generator>::type* = 0)
+
+#define NDNBOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen)    \
+    template<class Generator>                                       \
+    void seed(Generator& gen, typename ::ndnboost::random::detail::disable_seed<Generator>::type* = 0)
+
+#define NDNBOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq)    \
+    template<class SeedSeq>                                             \
+    explicit Self(SeedSeq& seq, typename ::ndnboost::random::detail::disable_constructor<Self, SeedSeq>::type* = 0)
+
+#define NDNBOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq)   \
+    template<class SeedSeq>                                     \
+    void seed(SeedSeq& seq, typename ::ndnboost::random::detail::disable_seed<SeedSeq>::type* = 0)
+
+#define NDNBOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x)  \
+    explicit Self(const T& x)
+
+#define NDNBOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \
+    void seed(const T& x)
+}
+}
+}
+
+#else
+
+#include <ndnboost/type_traits/is_arithmetic.hpp>
+#include <ndnboost/mpl/bool.hpp>
+
+#define NDNBOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \
+    Self(Self& other) { *this = other; }                                \
+    Self(const Self& other) { *this = other; }                          \
+    template<class Generator>                                           \
+    explicit Self(Generator& gen) {                                     \
+        boost_random_constructor_impl(gen, ::ndnboost::is_arithmetic<Generator>());\
+    }                                                                   \
+    template<class Generator>                                           \
+    void boost_random_constructor_impl(Generator& gen, ::ndnboost::mpl::false_)
+
+#define NDNBOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen)    \
+    template<class Generator>                                       \
+    void seed(Generator& gen) {                                     \
+        boost_random_seed_impl(gen, ::ndnboost::is_arithmetic<Generator>());\
+    }\
+    template<class Generator>\
+    void boost_random_seed_impl(Generator& gen, ::ndnboost::mpl::false_)
+
+#define NDNBOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq)    \
+    Self(Self& other) { *this = other; }                                \
+    Self(const Self& other) { *this = other; }                          \
+    template<class SeedSeq>                                             \
+    explicit Self(SeedSeq& seq) {                                       \
+        boost_random_constructor_impl(seq, ::ndnboost::is_arithmetic<SeedSeq>());\
+    }                                                                   \
+    template<class SeedSeq>                                             \
+    void boost_random_constructor_impl(SeedSeq& seq, ::ndnboost::mpl::false_)
+
+#define NDNBOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq)           \
+    template<class SeedSeq>                                             \
+    void seed(SeedSeq& seq) {                                           \
+        boost_random_seed_impl(seq, ::ndnboost::is_arithmetic<SeedSeq>()); \
+    }                                                                   \
+    template<class SeedSeq>                                             \
+    void boost_random_seed_impl(SeedSeq& seq, ::ndnboost::mpl::false_)
+
+#define NDNBOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x)  \
+    explicit Self(const T& x) { boost_random_constructor_impl(x, ::ndnboost::mpl::true_()); }\
+    void boost_random_constructor_impl(const T& x, ::ndnboost::mpl::true_)
+
+#define NDNBOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \
+    void seed(const T& x) { boost_random_seed_impl(x, ::ndnboost::mpl::true_()); }\
+    void boost_random_seed_impl(const T& x, ::ndnboost::mpl::true_)
+
+#endif
+
+#endif
diff --git a/include/ndnboost/random/detail/seed_impl.hpp b/include/ndnboost/random/detail/seed_impl.hpp
new file mode 100644
index 0000000..7184edc
--- /dev/null
+++ b/include/ndnboost/random/detail/seed_impl.hpp
@@ -0,0 +1,397 @@
+/* boost random/detail/seed.hpp header file
+ *
+ * Copyright Steven Watanabe 2009
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: seed_impl.hpp 72951 2011-07-07 04:57:37Z steven_watanabe $
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_SEED_IMPL_HPP
+#define NDNBOOST_RANDOM_DETAIL_SEED_IMPL_HPP
+
+#include <stdexcept>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/config/no_tr1/cmath.hpp>
+#include <ndnboost/integer/integer_mask.hpp>
+#include <ndnboost/integer/static_log2.hpp>
+#include <ndnboost/type_traits/is_signed.hpp>
+#include <ndnboost/type_traits/is_integral.hpp>
+#include <ndnboost/type_traits/make_unsigned.hpp>
+#include <ndnboost/mpl/bool.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/mpl/int.hpp>
+#include <ndnboost/random/detail/const_mod.hpp>
+#include <ndnboost/random/detail/integer_log2.hpp>
+#include <ndnboost/random/detail/signed_unsigned_tools.hpp>
+#include <ndnboost/random/detail/generator_bits.hpp>
+
+#include <ndnboost/random/detail/disable_warnings.hpp>
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+// finds the seed type of an engine, given its
+// result_type.  If the result_type is integral
+// the seed type is the same.  If the result_type
+// is floating point, the seed type is uint32_t
+template<class T>
+struct seed_type
+{
+    typedef typename ndnboost::mpl::if_<ndnboost::is_integral<T>,
+        T,
+        ndnboost::uint32_t
+    >::type type;
+};
+
+template<int N>
+struct const_pow_impl
+{
+    template<class T>
+    static T call(T arg, int n, T result)
+    {
+        return const_pow_impl<N / 2>::call(arg * arg, n / 2,
+            n%2 == 0? result : result * arg);
+    }
+};
+
+template<>
+struct const_pow_impl<0>
+{
+    template<class T>
+    static T call(T, int, T result)
+    {
+        return result;
+    }
+};
+
+// requires N is an upper bound on n
+template<int N, class T>
+inline T const_pow(T arg, int n) { return const_pow_impl<N>::call(arg, n, T(1)); }
+
+template<class T>
+inline T pow2(int n)
+{
+    typedef unsigned int_type;
+    const int max_bits = std::numeric_limits<int_type>::digits;
+    T multiplier = T(int_type(1) << (max_bits - 1)) * 2;
+    return (int_type(1) << (n % max_bits)) *
+        const_pow<std::numeric_limits<T>::digits / max_bits>(multiplier, n / max_bits);
+}
+
+template<class Engine, class Iter>
+void generate_from_real(Engine& eng, Iter begin, Iter end)
+{
+    using std::fmod;
+    typedef typename Engine::result_type RealType;
+    const int Bits = detail::generator_bits<Engine>::value();
+    int remaining_bits = 0;
+    ndnboost::uint_least32_t saved_bits = 0;
+    RealType multiplier = pow2<RealType>( Bits);
+    RealType mult32 = RealType(4294967296.0); // 2^32
+    while(true) {
+        RealType val = eng() * multiplier;
+        int available_bits = Bits;
+        // Make sure the compiler can optimize this out
+        // if it isn't possible.
+        if(Bits < 32 && available_bits < 32 - remaining_bits) {
+            saved_bits |= ndnboost::uint_least32_t(val) << remaining_bits;
+            remaining_bits += Bits;
+        } else {
+            // If Bits < 32, then remaining_bits != 0, since
+            // if remaining_bits == 0, available_bits < 32 - 0,
+            // and we won't get here to begin with.
+            if(Bits < 32 || remaining_bits != 0) {
+                ndnboost::uint_least32_t divisor =
+                    (ndnboost::uint_least32_t(1) << (32 - remaining_bits));
+                ndnboost::uint_least32_t extra_bits = ndnboost::uint_least32_t(fmod(val, mult32)) & (divisor - 1);
+                val = val / divisor;
+                *begin++ = saved_bits | (extra_bits << remaining_bits);
+                if(begin == end) return;
+                available_bits -= 32 - remaining_bits;
+                remaining_bits = 0;
+            }
+            // If Bits < 32 we should never enter this loop
+            if(Bits >= 32) {
+                for(; available_bits >= 32; available_bits -= 32) {
+                    ndnboost::uint_least32_t word = ndnboost::uint_least32_t(fmod(val, mult32));
+                    val /= mult32;
+                    *begin++ = word;
+                    if(begin == end) return;
+                }
+            }
+            remaining_bits = available_bits;
+            saved_bits = static_cast<ndnboost::uint_least32_t>(val);
+        }
+    }
+}
+
+template<class Engine, class Iter>
+void generate_from_int(Engine& eng, Iter begin, Iter end)
+{
+    typedef typename Engine::result_type IntType;
+    typedef typename ndnboost::make_unsigned<IntType>::type unsigned_type;
+    int remaining_bits = 0;
+    ndnboost::uint_least32_t saved_bits = 0;
+    unsigned_type range = ndnboost::random::detail::subtract<IntType>()((eng.max)(), (eng.min)());
+
+    int bits =
+        (range == (std::numeric_limits<unsigned_type>::max)()) ?
+            std::numeric_limits<unsigned_type>::digits :
+            detail::integer_log2(range + 1);
+
+    {
+        int discarded_bits = detail::integer_log2(bits);
+        unsigned_type excess = (range + 1) >> (bits - discarded_bits);
+        if(excess != 0) {
+            int extra_bits = detail::integer_log2((excess - 1) ^ excess);
+            bits = bits - discarded_bits + extra_bits;
+        }
+    }
+
+    unsigned_type mask = (static_cast<unsigned_type>(2) << (bits - 1)) - 1;
+    unsigned_type limit = ((range + 1) & ~mask) - 1;
+
+    while(true) {
+        unsigned_type val;
+        do {
+            val = ndnboost::random::detail::subtract<IntType>()(eng(), (eng.min)());
+        } while(limit != range && val > limit);
+        val &= mask;
+        int available_bits = bits;
+        if(available_bits == 32) {
+            *begin++ = static_cast<ndnboost::uint_least32_t>(val) & 0xFFFFFFFFu;
+            if(begin == end) return;
+        } else if(available_bits % 32 == 0) {
+            for(int i = 0; i < available_bits / 32; ++i) {
+                ndnboost::uint_least32_t word = ndnboost::uint_least32_t(val) & 0xFFFFFFFFu;
+                int supress_warning = (bits >= 32);
+                NDNBOOST_ASSERT(supress_warning == 1);
+                val >>= (32 * supress_warning);
+                *begin++ = word;
+                if(begin == end) return;
+            }
+        } else if(bits < 32 && available_bits < 32 - remaining_bits) {
+            saved_bits |= ndnboost::uint_least32_t(val) << remaining_bits;
+            remaining_bits += bits;
+        } else {
+            if(bits < 32 || remaining_bits != 0) {
+                ndnboost::uint_least32_t extra_bits = ndnboost::uint_least32_t(val) & ((ndnboost::uint_least32_t(1) << (32 - remaining_bits)) - 1);
+                val >>= 32 - remaining_bits;
+                *begin++ = saved_bits | (extra_bits << remaining_bits);
+                if(begin == end) return;
+                available_bits -= 32 - remaining_bits;
+                remaining_bits = 0;
+            }
+            if(bits >= 32) {
+                for(; available_bits >= 32; available_bits -= 32) {
+                    ndnboost::uint_least32_t word = ndnboost::uint_least32_t(val) & 0xFFFFFFFFu;
+                    int supress_warning = (bits >= 32);
+                    NDNBOOST_ASSERT(supress_warning == 1);
+                    val >>= (32 * supress_warning);
+                    *begin++ = word;
+                    if(begin == end) return;
+                }
+            }
+            remaining_bits = available_bits;
+            saved_bits = static_cast<ndnboost::uint_least32_t>(val);
+        }
+    }
+}
+
+template<class Engine, class Iter>
+void generate_impl(Engine& eng, Iter first, Iter last, ndnboost::mpl::true_)
+{
+    return detail::generate_from_int(eng, first, last);
+}
+
+template<class Engine, class Iter>
+void generate_impl(Engine& eng, Iter first, Iter last, ndnboost::mpl::false_)
+{
+    return detail::generate_from_real(eng, first, last);
+}
+
+template<class Engine, class Iter>
+void generate(Engine& eng, Iter first, Iter last)
+{
+    return detail::generate_impl(eng, first, last, ndnboost::is_integral<typename Engine::result_type>());
+}
+
+
+
+template<class IntType, IntType m, class SeedSeq>
+IntType seed_one_int(SeedSeq& seq)
+{
+    static const int log = ::ndnboost::mpl::if_c<(m == 0),
+        ::ndnboost::mpl::int_<(::std::numeric_limits<IntType>::digits)>,
+        ::ndnboost::static_log2<m> >::type::value;
+    static const int k =
+        (log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32;
+    ::ndnboost::uint_least32_t array[log / 32 + 4];
+    seq.generate(&array[0], &array[0] + k + 3);
+    IntType s = 0;
+    for(int j = 0; j < k; ++j) {
+        IntType digit = const_mod<IntType, m>::apply(IntType(array[j+3]));
+        IntType mult = IntType(1) << 32*j;
+        s = const_mod<IntType, m>::mult_add(mult, digit, s);
+    }
+    return s;
+}
+
+template<class IntType, IntType m, class Iter>
+IntType get_one_int(Iter& first, Iter last)
+{
+    static const int log = ::ndnboost::mpl::if_c<(m == 0),
+        ::ndnboost::mpl::int_<(::std::numeric_limits<IntType>::digits)>,
+        ::ndnboost::static_log2<m> >::type::value;
+    static const int k =
+        (log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32;
+    IntType s = 0;
+    for(int j = 0; j < k; ++j) {
+        if(first == last) {
+            throw ::std::invalid_argument("Not enough elements in call to seed.");
+        }
+        IntType digit = const_mod<IntType, m>::apply(IntType(*first++));
+        IntType mult = IntType(1) << 32*j;
+        s = const_mod<IntType, m>::mult_add(mult, digit, s);
+    }
+    return s;
+}
+
+// TODO: work in-place whenever possible
+template<int w, std::size_t n, class SeedSeq, class UIntType>
+void seed_array_int_impl(SeedSeq& seq, UIntType (&x)[n])
+{
+    ndnboost::uint_least32_t storage[((w+31)/32) * n];
+    seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n);
+    for(std::size_t j = 0; j < n; j++) {
+        UIntType val = 0;
+        for(std::size_t k = 0; k < (w+31)/32; ++k) {
+            val += static_cast<UIntType>(storage[(w+31)/32*j + k]) << 32*k;
+        }
+        x[j] = val & ::ndnboost::low_bits_mask_t<w>::sig_bits;
+    }
+}
+
+template<int w, std::size_t n, class SeedSeq, class IntType>
+inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], ndnboost::mpl::true_)
+{
+    typedef typename ndnboost::make_unsigned<IntType>::type unsigned_array[n];
+    seed_array_int_impl<w>(seq, reinterpret_cast<unsigned_array&>(x));
+}
+
+template<int w, std::size_t n, class SeedSeq, class IntType>
+inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], ndnboost::mpl::false_)
+{
+    seed_array_int_impl<w>(seq, x);
+}
+
+template<int w, std::size_t n, class SeedSeq, class IntType>
+inline void seed_array_int(SeedSeq& seq, IntType (&x)[n])
+{
+    seed_array_int_impl<w>(seq, x, ndnboost::is_signed<IntType>());
+}
+
+template<int w, std::size_t n, class Iter, class UIntType>
+void fill_array_int_impl(Iter& first, Iter last, UIntType (&x)[n])
+{
+    for(std::size_t j = 0; j < n; j++) {
+        UIntType val = 0;
+        for(std::size_t k = 0; k < (w+31)/32; ++k) {
+            if(first == last) {
+                throw std::invalid_argument("Not enough elements in call to seed.");
+            }
+            val += static_cast<UIntType>(*first++) << 32*k;
+        }
+        x[j] = val & ::ndnboost::low_bits_mask_t<w>::sig_bits;
+    }
+}
+
+template<int w, std::size_t n, class Iter, class IntType>
+inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], ndnboost::mpl::true_)
+{
+    typedef typename ndnboost::make_unsigned<IntType>::type unsigned_array[n];
+    fill_array_int_impl<w>(first, last, reinterpret_cast<unsigned_array&>(x));
+}
+
+template<int w, std::size_t n, class Iter, class IntType>
+inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], ndnboost::mpl::false_)
+{
+    fill_array_int_impl<w>(first, last, x);
+}
+
+template<int w, std::size_t n, class Iter, class IntType>
+inline void fill_array_int(Iter& first, Iter last, IntType (&x)[n])
+{
+    fill_array_int_impl<w>(first, last, x, ndnboost::is_signed<IntType>());
+}
+
+template<int w, std::size_t n, class RealType>
+void seed_array_real_impl(const ndnboost::uint_least32_t* storage, RealType (&x)[n])
+{
+    ndnboost::uint_least32_t mask = ~((~ndnboost::uint_least32_t(0)) << (w%32));
+    RealType two32 = 4294967296.0;
+    const RealType divisor = RealType(1)/detail::pow2<RealType>(w);
+    unsigned int j;
+    for(j = 0; j < n; ++j) {
+        RealType val = RealType(0);
+        RealType mult = divisor;
+        for(int k = 0; k < w/32; ++k) {
+            val += *storage++ * mult;
+            mult *= two32;
+        }
+        if(mask != 0) {
+            val += (*storage++ & mask) * mult;
+        }
+        NDNBOOST_ASSERT(val >= 0);
+        NDNBOOST_ASSERT(val < 1);
+        x[j] = val;
+    }
+}
+
+template<int w, std::size_t n, class SeedSeq, class RealType>
+void seed_array_real(SeedSeq& seq, RealType (&x)[n])
+{
+    using std::pow;
+    ndnboost::uint_least32_t storage[((w+31)/32) * n];
+    seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n);
+    seed_array_real_impl<w>(storage, x);
+}
+
+template<int w, std::size_t n, class Iter, class RealType>
+void fill_array_real(Iter& first, Iter last, RealType (&x)[n])
+{
+    ndnboost::uint_least32_t mask = ~((~ndnboost::uint_least32_t(0)) << (w%32));
+    RealType two32 = 4294967296.0;
+    const RealType divisor = RealType(1)/detail::pow2<RealType>(w);
+    unsigned int j;
+    for(j = 0; j < n; ++j) {
+        RealType val = RealType(0);
+        RealType mult = divisor;
+        for(int k = 0; k < w/32; ++k, ++first) {
+            if(first == last) throw std::invalid_argument("Not enough elements in call to seed.");
+            val += *first * mult;
+            mult *= two32;
+        }
+        if(mask != 0) {
+            if(first == last) throw std::invalid_argument("Not enough elements in call to seed.");
+            val += (*first & mask) * mult;
+            ++first;
+        }
+        NDNBOOST_ASSERT(val >= 0);
+        NDNBOOST_ASSERT(val < 1);
+        x[j] = val;
+    }
+}
+
+}
+}
+}
+
+#include <ndnboost/random/detail/enable_warnings.hpp>
+
+#endif
diff --git a/include/ndnboost/random/detail/signed_unsigned_tools.hpp b/include/ndnboost/random/detail/signed_unsigned_tools.hpp
new file mode 100644
index 0000000..8fcb1b6
--- /dev/null
+++ b/include/ndnboost/random/detail/signed_unsigned_tools.hpp
@@ -0,0 +1,89 @@
+/* boost random/detail/signed_unsigned_tools.hpp header file
+ *
+ * Copyright Jens Maurer 2006
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ */
+
+#ifndef NDNBOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
+#define NDNBOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
+
+#include <ndnboost/limits.hpp>
+#include <ndnboost/config.hpp>
+#include <ndnboost/type_traits/make_unsigned.hpp>
+
+namespace ndnboost {
+namespace random {
+namespace detail {
+
+
+/*
+ * Compute x - y, we know that x >= y, return an unsigned value.
+ */
+
+template<class T, bool sgn = std::numeric_limits<T>::is_signed>
+struct subtract { };
+
+template<class T>
+struct subtract<T, /* signed */ false>
+{
+  typedef T result_type;
+  result_type operator()(T x, T y) { return x - y; }
+};
+
+template<class T>
+struct subtract<T, /* signed */ true>
+{
+  typedef typename make_unsigned<T>::type result_type;
+  result_type operator()(T x, T y)
+  {
+    if (y >= 0)   // because x >= y, it follows that x >= 0, too
+      return result_type(x) - result_type(y);
+    if (x >= 0)   // y < 0
+      // avoid the nasty two's complement case for y == min()
+      return result_type(x) + result_type(-(y+1)) + 1;
+    // both x and y are negative: no signed overflow
+    return result_type(x - y);
+  }
+};
+
+/*
+ * Compute x + y, x is unsigned, result fits in type of "y".
+ */
+
+template<class T1, class T2, bool sgn = std::numeric_limits<T2>::is_signed>
+struct add { };
+
+template<class T1, class T2>
+struct add<T1, T2, /* signed */ false>
+{
+  typedef T2 result_type;
+  result_type operator()(T1 x, T2 y) { return T2(x) + y; }
+};
+
+template<class T1, class T2>
+struct add<T1, T2, /* signed */ true>
+{
+  typedef T2 result_type;
+  result_type operator()(T1 x, T2 y)
+  {
+    if (y >= 0)
+      return T2(x) + y;
+    // y < 0
+    if (x > T1(-(y+1)))  // result >= 0 after subtraction
+      // avoid the nasty two's complement edge case for y == min()
+      return T2(x - T1(-(y+1)) - 1);
+    // abs(x) < abs(y), thus T2 able to represent x
+    return T2(x) + y;
+  }
+};
+
+} // namespace detail
+} // namespace random
+} // namespace ndnboost
+
+#endif // NDNBOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
+
diff --git a/include/ndnboost/random/linear_congruential.hpp b/include/ndnboost/random/linear_congruential.hpp
new file mode 100644
index 0000000..b4c69d8
--- /dev/null
+++ b/include/ndnboost/random/linear_congruential.hpp
@@ -0,0 +1,466 @@
+/* boost random/linear_congruential.hpp header file
+ *
+ * Copyright Jens Maurer 2000-2001
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: linear_congruential.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ * Revision history
+ *  2001-02-18  moved to individual header files
+ */
+
+#ifndef NDNBOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
+#define NDNBOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
+
+#include <iostream>
+#include <stdexcept>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/config.hpp>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/integer/static_log2.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/type_traits/is_arithmetic.hpp>
+#include <ndnboost/random/detail/config.hpp>
+#include <ndnboost/random/detail/const_mod.hpp>
+#include <ndnboost/random/detail/seed.hpp>
+#include <ndnboost/random/detail/seed_impl.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+#include <ndnboost/random/detail/disable_warnings.hpp>
+
+namespace ndnboost {
+namespace random {
+
+/**
+ * Instantiations of class template linear_congruential_engine model a
+ * \pseudo_random_number_generator. Linear congruential pseudo-random
+ * number generators are described in:
+ *
+ *  @blockquote
+ *  "Mathematical methods in large-scale computing units", D. H. Lehmer,
+ *  Proc. 2nd Symposium on Large-Scale Digital Calculating Machines,
+ *  Harvard University Press, 1951, pp. 141-146
+ *  @endblockquote
+ *
+ * Let x(n) denote the sequence of numbers returned by some pseudo-random
+ * number generator. Then for the linear congruential generator,
+ * x(n+1) := (a * x(n) + c) mod m. Parameters for the generator are
+ * x(0), a, c, m. The template parameter IntType shall denote an integral
+ * type. It must be large enough to hold values a, c, and m. The template
+ * parameters a and c must be smaller than m.
+ *
+ * Note: The quality of the generator crucially depends on the choice of
+ * the parameters. User code should use one of the sensibly parameterized
+ * generators such as minstd_rand instead.
+ */
+template<class IntType, IntType a, IntType c, IntType m>
+class linear_congruential_engine
+{
+public:
+    typedef IntType result_type;
+
+    // Required for old Boost.Random concept
+    NDNBOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+    NDNBOOST_STATIC_CONSTANT(IntType, multiplier = a);
+    NDNBOOST_STATIC_CONSTANT(IntType, increment = c);
+    NDNBOOST_STATIC_CONSTANT(IntType, modulus = m);
+    NDNBOOST_STATIC_CONSTANT(IntType, default_seed = 1);
+    
+    NDNBOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
+    NDNBOOST_STATIC_ASSERT(m == 0 || a < m);
+    NDNBOOST_STATIC_ASSERT(m == 0 || c < m);
+    
+    /**
+     * Constructs a @c linear_congruential_engine, using the default seed
+     */
+    linear_congruential_engine() { seed(); }
+
+    /**
+     * Constructs a @c linear_congruential_engine, seeding it with @c x0.
+     */
+    NDNBOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_congruential_engine,
+                                               IntType, x0)
+    { seed(x0); }
+    
+    /**
+     * Constructs a @c linear_congruential_engine, seeding it with values
+     * produced by a call to @c seq.generate().
+     */
+    NDNBOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_congruential_engine,
+                                             SeedSeq, seq)
+    { seed(seq); }
+
+    /**
+     * Constructs a @c linear_congruential_engine  and seeds it
+     * with values taken from the itrator range [first, last)
+     * and adjusts first to point to the element after the last one
+     * used.  If there are not enough elements, throws @c std::invalid_argument.
+     *
+     * first and last must be input iterators.
+     */
+    template<class It>
+    linear_congruential_engine(It& first, It last)
+    {
+        seed(first, last);
+    }
+
+    // compiler-generated copy constructor and assignment operator are fine
+
+    /**
+     * Calls seed(default_seed)
+     */
+    void seed() { seed(default_seed); }
+
+    /**
+     * If c mod m is zero and x0 mod m is zero, changes the current value of
+     * the generator to 1. Otherwise, changes it to x0 mod m. If c is zero,
+     * distinct seeds in the range [1,m) will leave the generator in distinct
+     * states. If c is not zero, the range is [0,m).
+     */
+    NDNBOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_congruential_engine, IntType, x0)
+    {
+        // wrap _x if it doesn't fit in the destination
+        if(modulus == 0) {
+            _x = x0;
+        } else {
+            _x = x0 % modulus;
+        }
+        // handle negative seeds
+        if(_x <= 0 && _x != 0) {
+            _x += modulus;
+        }
+        // adjust to the correct range
+        if(increment == 0 && _x == 0) {
+            _x = 1;
+        }
+        NDNBOOST_ASSERT(_x >= (min)());
+        NDNBOOST_ASSERT(_x <= (max)());
+    }
+
+    /**
+     * Seeds a @c linear_congruential_engine using values from a SeedSeq.
+     */
+    NDNBOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_congruential_engine, SeedSeq, seq)
+    { seed(detail::seed_one_int<IntType, m>(seq)); }
+
+    /**
+     * seeds a @c linear_congruential_engine with values taken
+     * from the itrator range [first, last) and adjusts @c first to
+     * point to the element after the last one used.  If there are
+     * not enough elements, throws @c std::invalid_argument.
+     *
+     * @c first and @c last must be input iterators.
+     */
+    template<class It>
+    void seed(It& first, It last)
+    { seed(detail::get_one_int<IntType, m>(first, last)); }
+
+    /**
+     * Returns the smallest value that the @c linear_congruential_engine
+     * can produce.
+     */
+    static result_type min NDNBOOST_PREVENT_MACRO_SUBSTITUTION ()
+    { return c == 0 ? 1 : 0; }
+    /**
+     * Returns the largest value that the @c linear_congruential_engine
+     * can produce.
+     */
+    static result_type max NDNBOOST_PREVENT_MACRO_SUBSTITUTION ()
+    { return modulus-1; }
+
+    /** Returns the next value of the @c linear_congruential_engine. */
+    IntType operator()()
+    {
+        _x = const_mod<IntType, m>::mult_add(a, _x, c);
+        return _x;
+    }
+  
+    /** Fills a range with random values */
+    template<class Iter>
+    void generate(Iter first, Iter last)
+    { detail::generate_from_int(*this, first, last); }
+
+    /** Advances the state of the generator by @c z. */
+    void discard(ndnboost::uintmax_t z)
+    {
+        typedef const_mod<IntType, m> mod_type;
+        IntType b_inv = mod_type::invert(a-1);
+        IntType b_gcd = mod_type::mult(a-1, b_inv);
+        if(b_gcd == 1) {
+            IntType a_z = mod_type::pow(a, z);
+            _x = mod_type::mult_add(a_z, _x, 
+                mod_type::mult(mod_type::mult(c, b_inv), a_z - 1));
+        } else {
+            // compute (a^z - 1)*c % (b_gcd * m) / (b / b_gcd) * inv(b / b_gcd)
+            // we're storing the intermediate result / b_gcd
+            IntType a_zm1_over_gcd = 0;
+            IntType a_km1_over_gcd = (a - 1) / b_gcd;
+            ndnboost::uintmax_t exponent = z;
+            while(exponent != 0) {
+                if(exponent % 2 == 1) {
+                    a_zm1_over_gcd =
+                        mod_type::mult_add(
+                            b_gcd,
+                            mod_type::mult(a_zm1_over_gcd, a_km1_over_gcd),
+                            mod_type::add(a_zm1_over_gcd, a_km1_over_gcd));
+                }
+                a_km1_over_gcd = mod_type::mult_add(
+                    b_gcd,
+                    mod_type::mult(a_km1_over_gcd, a_km1_over_gcd),
+                    mod_type::add(a_km1_over_gcd, a_km1_over_gcd));
+                exponent /= 2;
+            }
+            
+            IntType a_z = mod_type::mult_add(b_gcd, a_zm1_over_gcd, 1);
+            IntType num = mod_type::mult(c, a_zm1_over_gcd);
+            b_inv = mod_type::invert((a-1)/b_gcd);
+            _x = mod_type::mult_add(a_z, _x, mod_type::mult(b_inv, num));
+        }
+    }
+
+    friend bool operator==(const linear_congruential_engine& x,
+                           const linear_congruential_engine& y)
+    { return x._x == y._x; }
+    friend bool operator!=(const linear_congruential_engine& x,
+                           const linear_congruential_engine& y)
+    { return !(x == y); }
+    
+#if !defined(NDNBOOST_RANDOM_NO_STREAM_OPERATORS)
+    /** Writes a @c linear_congruential_engine to a @c std::ostream. */
+    template<class CharT, class Traits>
+    friend std::basic_ostream<CharT,Traits>&
+    operator<<(std::basic_ostream<CharT,Traits>& os,
+               const linear_congruential_engine& lcg)
+    {
+        return os << lcg._x;
+    }
+
+    /** Reads a @c linear_congruential_engine from a @c std::istream. */
+    template<class CharT, class Traits>
+    friend std::basic_istream<CharT,Traits>&
+    operator>>(std::basic_istream<CharT,Traits>& is,
+               linear_congruential_engine& lcg)
+    {
+        lcg.read(is);
+        return is;
+    }
+#endif
+
+private:
+
+    /// \cond show_private
+
+    template<class CharT, class Traits>
+    void read(std::basic_istream<CharT, Traits>& is) {
+        IntType x;
+        if(is >> x) {
+            if(x >= (min)() && x <= (max)()) {
+                _x = x;
+            } else {
+                is.setstate(std::ios_base::failbit);
+            }
+        }
+    }
+
+    /// \endcond
+
+    IntType _x;
+};
+
+#ifndef NDNBOOST_NO_INCLASS_MEMBER_INITIALIZATION
+//  A definition is required even for integral static constants
+template<class IntType, IntType a, IntType c, IntType m>
+const bool linear_congruential_engine<IntType, a, c, m>::has_fixed_range;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::multiplier;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::increment;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::modulus;
+template<class IntType, IntType a, IntType c, IntType m>
+const IntType linear_congruential_engine<IntType,a,c,m>::default_seed;
+#endif
+
+/// \cond show_deprecated
+
+// provided for backwards compatibility
+template<class IntType, IntType a, IntType c, IntType m, IntType val = 0>
+class linear_congruential : public linear_congruential_engine<IntType, a, c, m>
+{
+    typedef linear_congruential_engine<IntType, a, c, m> base_type;
+public:
+    linear_congruential(IntType x0 = 1) : base_type(x0) {}
+    template<class It>
+    linear_congruential(It& first, It last) : base_type(first, last) {}
+};
+
+/// \endcond
+
+/**
+ * The specialization \minstd_rand0 was originally suggested in
+ *
+ *  @blockquote
+ *  A pseudo-random number generator for the System/360, P.A. Lewis,
+ *  A.S. Goodman, J.M. Miller, IBM Systems Journal, Vol. 8, No. 2,
+ *  1969, pp. 136-146
+ *  @endblockquote
+ *
+ * It is examined more closely together with \minstd_rand in
+ *
+ *  @blockquote
+ *  "Random Number Generators: Good ones are hard to find",
+ *  Stephen K. Park and Keith W. Miller, Communications of
+ *  the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201 
+ *  @endblockquote
+ */
+typedef linear_congruential_engine<uint32_t, 16807, 0, 2147483647> minstd_rand0;
+
+/** The specialization \minstd_rand was suggested in
+ *
+ *  @blockquote
+ *  "Random Number Generators: Good ones are hard to find",
+ *  Stephen K. Park and Keith W. Miller, Communications of
+ *  the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201
+ *  @endblockquote
+ */
+typedef linear_congruential_engine<uint32_t, 48271, 0, 2147483647> minstd_rand;
+
+
+#if !defined(NDNBOOST_NO_INT64_T) && !defined(NDNBOOST_NO_INTEGRAL_INT64_T)
+/**
+ * Class @c rand48 models a \pseudo_random_number_generator. It uses
+ * the linear congruential algorithm with the parameters a = 0x5DEECE66D,
+ * c = 0xB, m = 2**48. It delivers identical results to the @c lrand48()
+ * function available on some systems (assuming lcong48 has not been called).
+ *
+ * It is only available on systems where @c uint64_t is provided as an
+ * integral type, so that for example static in-class constants and/or
+ * enum definitions with large @c uint64_t numbers work.
+ */
+class rand48 
+{
+public:
+    typedef ndnboost::uint32_t result_type;
+
+    NDNBOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+    /**
+     * Returns the smallest value that the generator can produce
+     */
+    static uint32_t min NDNBOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
+    /**
+     * Returns the largest value that the generator can produce
+     */
+    static uint32_t max NDNBOOST_PREVENT_MACRO_SUBSTITUTION ()
+    { return 0x7FFFFFFF; }
+  
+    /** Seeds the generator with the default seed. */
+    rand48() : lcf(cnv(static_cast<uint32_t>(1))) {}
+    /**
+     * Constructs a \rand48 generator with x(0) := (x0 << 16) | 0x330e.
+     */
+    NDNBOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(rand48, result_type, x0)
+    { seed(x0); }
+    /**
+     * Seeds the generator with values produced by @c seq.generate().
+     */
+    NDNBOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(rand48, SeedSeq, seq)
+    { seed(seq); }
+    /**
+     * Seeds the generator using values from an iterator range,
+     * and updates first to point one past the last value consumed.
+     */
+    template<class It> rand48(It& first, It last) : lcf(first, last) { }
+
+    // compiler-generated copy ctor and assignment operator are fine
+
+    /** Seeds the generator with the default seed. */
+    void seed() { seed(static_cast<uint32_t>(1)); }
+    /**
+     * Changes the current value x(n) of the generator to (x0 << 16) | 0x330e.
+     */
+    NDNBOOST_RANDOM_DETAIL_ARITHMETIC_SEED(rand48, result_type, x0)
+    { lcf.seed(cnv(x0)); }
+    /**
+     * Seeds the generator using values from an iterator range,
+     * and updates first to point one past the last value consumed.
+     */
+    template<class It> void seed(It& first, It last) { lcf.seed(first,last); }
+    /**
+     * Seeds the generator with values produced by @c seq.generate().
+     */
+    NDNBOOST_RANDOM_DETAIL_SEED_SEQ_SEED(rand48, SeedSeq, seq)
+    { lcf.seed(seq); }
+
+    /**  Returns the next value of the generator. */
+    uint32_t operator()() { return static_cast<uint32_t>(lcf() >> 17); }
+    
+    /** Advances the state of the generator by @c z. */
+    void discard(ndnboost::uintmax_t z) { lcf.discard(z); }
+  
+    /** Fills a range with random values */
+    template<class Iter>
+    void generate(Iter first, Iter last)
+    {
+        for(; first != last; ++first) {
+            *first = (*this)();
+        }
+    }
+
+#ifndef NDNBOOST_RANDOM_NO_STREAM_OPERATORS
+    /**  Writes a @c rand48 to a @c std::ostream. */
+    template<class CharT,class Traits>
+    friend std::basic_ostream<CharT,Traits>&
+    operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)
+    { os << r.lcf; return os; }
+
+    /** Reads a @c rand48 from a @c std::istream. */
+    template<class CharT,class Traits>
+    friend std::basic_istream<CharT,Traits>&
+    operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)
+    { is >> r.lcf; return is; }
+#endif
+
+    /**
+     * Returns true if the two generators will produce identical
+     * sequences of values.
+     */
+    friend bool operator==(const rand48& x, const rand48& y)
+    { return x.lcf == y.lcf; }
+    /**
+     * Returns true if the two generators will produce different
+     * sequences of values.
+     */
+    friend bool operator!=(const rand48& x, const rand48& y)
+    { return !(x == y); }
+private:
+    /// \cond show_private
+    typedef random::linear_congruential_engine<uint64_t,
+        // xxxxULL is not portable
+        uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32),
+        0xB, uint64_t(1)<<48> lcf_t;
+    lcf_t lcf;
+
+    static ndnboost::uint64_t cnv(ndnboost::uint32_t x)
+    { return (static_cast<uint64_t>(x) << 16) | 0x330e; }
+    /// \endcond
+};
+#endif /* !NDNBOOST_NO_INT64_T && !NDNBOOST_NO_INTEGRAL_INT64_T */
+
+} // namespace random
+
+using random::minstd_rand0;
+using random::minstd_rand;
+using random::rand48;
+
+} // namespace ndnboost
+
+#include <ndnboost/random/detail/enable_warnings.hpp>
+
+#endif // NDNBOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
diff --git a/include/ndnboost/random/uniform_01.hpp b/include/ndnboost/random/uniform_01.hpp
new file mode 100644
index 0000000..1a14110
--- /dev/null
+++ b/include/ndnboost/random/uniform_01.hpp
@@ -0,0 +1,277 @@
+/* boost random/uniform_01.hpp header file
+ *
+ * Copyright Jens Maurer 2000-2001
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: uniform_01.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ * Revision history
+ *  2001-02-18  moved to individual header files
+ */
+
+#ifndef NDNBOOST_RANDOM_UNIFORM_01_HPP
+#define NDNBOOST_RANDOM_UNIFORM_01_HPP
+
+#include <iostream>
+#include <ndnboost/config.hpp>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/random/detail/config.hpp>
+#include <ndnboost/random/detail/ptr_helper.hpp>
+
+#include <ndnboost/random/detail/disable_warnings.hpp>
+
+namespace ndnboost {
+namespace random {
+
+#ifdef NDNBOOST_RANDOM_DOXYGEN
+
+/**
+ * The distribution function uniform_01 models a \random_distribution.
+ * On each invocation, it returns a random floating-point value
+ * uniformly distributed in the range [0..1).
+ *
+ * The template parameter RealType shall denote a float-like value type
+ * with support for binary operators +, -, and /.
+ *
+ * Note: The current implementation is buggy, because it may not fill
+ * all of the mantissa with random bits. I'm unsure how to fill a
+ * (to-be-invented) @c ndnboost::bigfloat class with random bits efficiently.
+ * It's probably time for a traits class.
+ */
+template<class RealType = double>
+class uniform_01
+{
+public:
+  typedef RealType input_type;
+  typedef RealType result_type;
+  result_type min NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const;
+  result_type max NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const;
+  void reset();
+
+  template<class Engine>
+  result_type operator()(Engine& eng);
+
+#ifndef NDNBOOST_RANDOM_NO_STREAM_OPERATORS
+  template<class CharT, class Traits>
+  friend std::basic_ostream<CharT,Traits>&
+  operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
+  {
+    return os;
+  }
+
+  template<class CharT, class Traits>
+  friend std::basic_istream<CharT,Traits>&
+  operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
+  {
+    return is;
+  }
+#endif
+};
+
+#else
+
+namespace detail {
+
+template<class RealType>
+class new_uniform_01
+{
+public:
+  typedef RealType input_type;
+  typedef RealType result_type;
+  // compiler-generated copy ctor and copy assignment are fine
+  result_type min NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
+  result_type max NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
+  void reset() { }
+
+  template<class Engine>
+  result_type operator()(Engine& eng) {
+    for (;;) {
+      typedef typename Engine::result_type base_result;
+      result_type factor = result_type(1) /
+              (result_type((eng.max)()-(eng.min)()) +
+               result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0));
+      result_type result = result_type(eng() - (eng.min)()) * factor;
+      if (result < result_type(1))
+        return result;
+    }
+  }
+
+#ifndef NDNBOOST_RANDOM_NO_STREAM_OPERATORS
+  template<class CharT, class Traits>
+  friend std::basic_ostream<CharT,Traits>&
+  operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
+  {
+    return os;
+  }
+
+  template<class CharT, class Traits>
+  friend std::basic_istream<CharT,Traits>&
+  operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
+  {
+    return is;
+  }
+#endif
+};
+
+template<class UniformRandomNumberGenerator, class RealType>
+class backward_compatible_uniform_01
+{
+  typedef ndnboost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
+public:
+  typedef UniformRandomNumberGenerator base_type;
+  typedef RealType result_type;
+
+  NDNBOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+#if !defined(NDNBOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(NDNBOOST_MSVC) && NDNBOOST_MSVC <= 1300)
+  NDNBOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
+#endif
+
+  explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)
+    : _rng(rng),
+      _factor(result_type(1) /
+              (result_type((base().max)()-(base().min)()) +
+               result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
+  {
+  }
+  // compiler-generated copy ctor and copy assignment are fine
+
+  result_type min NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
+  result_type max NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
+  typename traits::value_type& base() { return traits::ref(_rng); }
+  const typename traits::value_type& base() const { return traits::ref(_rng); }
+  void reset() { }
+
+  result_type operator()() {
+    for (;;) {
+      result_type result = result_type(base()() - (base().min)()) * _factor;
+      if (result < result_type(1))
+        return result;
+    }
+  }
+
+#if !defined(NDNBOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(NDNBOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+  template<class CharT, class Traits>
+  friend std::basic_ostream<CharT,Traits>&
+  operator<<(std::basic_ostream<CharT,Traits>& os, const backward_compatible_uniform_01& u)
+  {
+    os << u._rng;
+    return os;
+  }
+
+  template<class CharT, class Traits>
+  friend std::basic_istream<CharT,Traits>&
+  operator>>(std::basic_istream<CharT,Traits>& is, backward_compatible_uniform_01& u)
+  {
+    is >> u._rng;
+    return is;
+  }
+#endif
+
+private:
+  typedef typename traits::value_type::result_type base_result;
+  UniformRandomNumberGenerator _rng;
+  result_type _factor;
+};
+
+#ifndef NDNBOOST_NO_INCLASS_MEMBER_INITIALIZATION
+//  A definition is required even for integral static constants
+template<class UniformRandomNumberGenerator, class RealType>
+const bool backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;
+#endif
+
+template<class UniformRandomNumberGenerator>
+struct select_uniform_01
+{
+  template<class RealType>
+  struct apply
+  {
+    typedef backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType> type;
+  };
+};
+
+template<>
+struct select_uniform_01<float>
+{
+  template<class RealType>
+  struct apply
+  {
+    typedef new_uniform_01<float> type;
+  };
+};
+
+template<>
+struct select_uniform_01<double>
+{
+  template<class RealType>
+  struct apply
+  {
+    typedef new_uniform_01<double> type;
+  };
+};
+
+template<>
+struct select_uniform_01<long double>
+{
+  template<class RealType>
+  struct apply
+  {
+    typedef new_uniform_01<long double> type;
+  };
+};
+
+}
+
+// Because it is so commonly used: uniform distribution on the real [0..1)
+// range.  This allows for specializations to avoid a costly int -> float
+// conversion plus float multiplication
+template<class UniformRandomNumberGenerator = double, class RealType = double>
+class uniform_01
+  : public detail::select_uniform_01<UniformRandomNumberGenerator>::NDNBOOST_NESTED_TEMPLATE apply<RealType>::type
+{
+  typedef typename detail::select_uniform_01<UniformRandomNumberGenerator>::NDNBOOST_NESTED_TEMPLATE apply<RealType>::type impl_type;
+  typedef ndnboost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
+public:
+
+  uniform_01() {}
+
+  explicit uniform_01(typename traits::rvalue_type rng)
+    : impl_type(rng)
+  {
+  }
+
+#if !defined(NDNBOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(NDNBOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+  template<class CharT, class Traits>
+  friend std::basic_ostream<CharT,Traits>&
+  operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)
+  {
+    os << static_cast<const impl_type&>(u);
+    return os;
+  }
+
+  template<class CharT, class Traits>
+  friend std::basic_istream<CharT,Traits>&
+  operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)
+  {
+    is >> static_cast<impl_type&>(u);
+    return is;
+  }
+#endif
+};
+
+#endif
+
+} // namespace random
+
+using random::uniform_01;
+
+} // namespace ndnboost
+
+#include <ndnboost/random/detail/enable_warnings.hpp>
+
+#endif // NDNBOOST_RANDOM_UNIFORM_01_HPP
diff --git a/include/ndnboost/random/uniform_smallint.hpp b/include/ndnboost/random/uniform_smallint.hpp
new file mode 100644
index 0000000..190e100
--- /dev/null
+++ b/include/ndnboost/random/uniform_smallint.hpp
@@ -0,0 +1,288 @@
+/* boost random/uniform_smallint.hpp header file
+ *
+ * Copyright Jens Maurer 2000-2001
+ * 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)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id: uniform_smallint.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $
+ *
+ * Revision history
+ *  2001-04-08  added min<max assertion (N. Becker)
+ *  2001-02-18  moved to individual header files
+ */
+
+#ifndef NDNBOOST_RANDOM_UNIFORM_SMALLINT_HPP
+#define NDNBOOST_RANDOM_UNIFORM_SMALLINT_HPP
+
+#include <istream>
+#include <iosfwd>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/config.hpp>
+#include <ndnboost/limits.hpp>
+#include <ndnboost/type_traits/is_integral.hpp>
+#include <ndnboost/random/detail/config.hpp>
+#include <ndnboost/random/detail/operators.hpp>
+#include <ndnboost/random/detail/signed_unsigned_tools.hpp>
+#include <ndnboost/random/uniform_01.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+namespace ndnboost {
+namespace random {
+
+// uniform integer distribution on a small range [min, max]
+
+/**
+ * The distribution function uniform_smallint models a \random_distribution.
+ * On each invocation, it returns a random integer value uniformly distributed
+ * in the set of integer numbers {min, min+1, min+2, ..., max}. It assumes
+ * that the desired range (max-min+1) is small compared to the range of the
+ * underlying source of random numbers and thus makes no attempt to limit
+ * quantization errors.
+ *
+ * Let \f$r_{\mathtt{out}} = (\mbox{max}-\mbox{min}+1)\f$ the desired range of
+ * integer numbers, and
+ * let \f$r_{\mathtt{base}}\f$ be the range of the underlying source of random
+ * numbers. Then, for the uniform distribution, the theoretical probability
+ * for any number i in the range \f$r_{\mathtt{out}}\f$ will be
+ * \f$\displaystyle p_{\mathtt{out}}(i) = \frac{1}{r_{\mathtt{out}}}\f$.
+ * Likewise, assume a uniform distribution on \f$r_{\mathtt{base}}\f$ for
+ * the underlying source of random numbers, i.e.
+ * \f$\displaystyle p_{\mathtt{base}}(i) = \frac{1}{r_{\mathtt{base}}}\f$.
+ * Let \f$p_{\mathtt{out\_s}}(i)\f$ denote the random
+ * distribution generated by @c uniform_smallint. Then the sum over all
+ * i in \f$r_{\mathtt{out}}\f$ of
+ * \f$\displaystyle
+ * \left(\frac{p_{\mathtt{out\_s}}(i)}{p_{\mathtt{out}}(i)} - 1\right)^2\f$
+ * shall not exceed
+ * \f$\displaystyle \frac{r_{\mathtt{out}}}{r_{\mathtt{base}}^2}
+ * (r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
+ * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$.
+ *
+ * The template parameter IntType shall denote an integer-like value type.
+ *
+ * @xmlnote
+ * The property above is the square sum of the relative differences
+ * in probabilities between the desired uniform distribution
+ * \f$p_{\mathtt{out}}(i)\f$ and the generated distribution
+ * \f$p_{\mathtt{out\_s}}(i)\f$.
+ * The property can be fulfilled with the calculation
+ * \f$(\mbox{base\_rng} \mbox{ mod } r_{\mathtt{out}})\f$, as follows:
+ * Let \f$r = r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}\f$.
+ * The base distribution on \f$r_{\mathtt{base}}\f$ is folded onto the
+ * range \f$r_{\mathtt{out}}\f$. The numbers i < r have assigned
+ * \f$\displaystyle
+ * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor+1\f$
+ * numbers of the base distribution, the rest has only \f$\displaystyle
+ * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor\f$.
+ * Therefore,
+ * \f$\displaystyle p_{\mathtt{out\_s}}(i) =
+ * \left(\left\lfloor\frac{r_{\mathtt{base}}}
+ * {r_{\mathtt{out}}}\right\rfloor+1\right) /
+ * r_{\mathtt{base}}\f$ for i < r and \f$\displaystyle p_{\mathtt{out\_s}}(i) =
+ * \left\lfloor\frac{r_{\mathtt{base}}}
+ * {r_{\mathtt{out}}}\right\rfloor/r_{\mathtt{base}}\f$ otherwise.
+ * Substituting this in the
+ * above sum formula leads to the desired result.
+ * @endxmlnote
+ *
+ * Note: The upper bound for
+ * \f$(r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
+ * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$ is
+ * \f$\displaystyle \frac{r_{\mathtt{out}}^2}{4}\f$.  Regarding the upper bound
+ * for the square sum of the relative quantization error of
+ * \f$\displaystyle \frac{r_\mathtt{out}^3}{4r_{\mathtt{base}}^2}\f$, it
+ * seems wise to either choose \f$r_{\mathtt{base}}\f$ so that
+ * \f$r_{\mathtt{base}} > 10r_{\mathtt{out}}^2\f$ or ensure that
+ * \f$r_{\mathtt{base}}\f$ is
+ * divisible by \f$r_{\mathtt{out}}\f$.
+ */
+template<class IntType = int>
+class uniform_smallint
+{
+public:
+    typedef IntType input_type;
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+
+        typedef uniform_smallint distribution_type;
+
+        /** constructs the parameters of a @c uniform_smallint distribution. */
+        param_type(IntType min_arg = 0, IntType max_arg = 9)
+          : _min(min_arg), _max(max_arg)
+        {
+            NDNBOOST_ASSERT(_min <= _max);
+        }
+
+        /** Returns the minimum value. */
+        IntType a() const { return _min; }
+        /** Returns the maximum value. */
+        IntType b() const { return _max; }
+        
+
+        /** Writes the parameters to a @c std::ostream. */
+        NDNBOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
+        {
+            os << parm._min << " " << parm._max;
+            return os;
+        }
+    
+        /** Reads the parameters from a @c std::istream. */
+        NDNBOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
+        {
+            is >> parm._min >> std::ws >> parm._max;
+            return is;
+        }
+
+        /** Returns true if the two sets of parameters are equal. */
+        NDNBOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
+        { return lhs._min == rhs._min && lhs._max == rhs._max; }
+
+        /** Returns true if the two sets of parameters are different. */
+        NDNBOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
+
+    private:
+        IntType _min;
+        IntType _max;
+    };
+
+    /**
+     * Constructs a @c uniform_smallint. @c min and @c max are the
+     * lower and upper bounds of the output range, respectively.
+     */
+    explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9)
+      : _min(min_arg), _max(max_arg) {}
+
+    /**
+     * Constructs a @c uniform_smallint from its parameters.
+     */
+    explicit uniform_smallint(const param_type& parm)
+      : _min(parm.a()), _max(parm.b()) {}
+
+    /** Returns the minimum value of the distribution. */
+    result_type a() const { return _min; }
+    /** Returns the maximum value of the distribution. */
+    result_type b() const { return _max; }
+    /** Returns the minimum value of the distribution. */
+    result_type min NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
+    /** Returns the maximum value of the distribution. */
+    result_type max NDNBOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
+
+    /** Returns the parameters of the distribution. */
+    param_type param() const { return param_type(_min, _max); }
+    /** Sets the parameters of the distribution. */
+    void param(const param_type& parm)
+    {
+        _min = parm.a();
+        _max = parm.b();
+    }
+
+    /**
+     * Effects: Subsequent uses of the distribution do not depend
+     * on values produced by any engine prior to invoking reset.
+     */
+    void reset() { }
+
+    /** Returns a value uniformly distributed in the range [min(), max()]. */
+    template<class Engine>
+    result_type operator()(Engine& eng) const
+    {
+        typedef typename Engine::result_type base_result;
+        return generate(eng, ndnboost::is_integral<base_result>());
+    }
+
+    /** Returns a value uniformly distributed in the range [param.a(), param.b()]. */
+    template<class Engine>
+    result_type operator()(Engine& eng, const param_type& parm) const
+    { return uniform_smallint(parm)(eng); }
+
+    /** Writes the distribution to a @c std::ostream. */
+    NDNBOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud)
+    {
+        os << ud._min << " " << ud._max;
+        return os;
+    }
+    
+    /** Reads the distribution from a @c std::istream. */
+    NDNBOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud)
+    {
+        is >> ud._min >> std::ws >> ud._max;
+        return is;
+    }
+
+    /**
+     * Returns true if the two distributions will produce identical
+     * sequences of values given equal generators.
+     */
+    NDNBOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs)
+    { return lhs._min == rhs._min && lhs._max == rhs._max; }
+    
+    /**
+     * Returns true if the two distributions may produce different
+     * sequences of values given equal generators.
+     */
+    NDNBOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint)
+
+private:
+    
+    // \cond show_private
+    template<class Engine>
+    result_type generate(Engine& eng, ndnboost::mpl::true_) const
+    {
+        // equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min,
+        // but guarantees no overflow.
+        typedef typename Engine::result_type base_result;
+        typedef typename ndnboost::make_unsigned<base_result>::type base_unsigned;
+        typedef typename ndnboost::make_unsigned<result_type>::type range_type;
+        range_type range = random::detail::subtract<result_type>()(_max, _min);
+        base_unsigned base_range =
+            random::detail::subtract<result_type>()((eng.max)(), (eng.min)());
+        base_unsigned val =
+            random::detail::subtract<base_result>()(eng(), (eng.min)());
+        if(range >= base_range) {
+            return ndnboost::random::detail::add<range_type, result_type>()(
+                static_cast<range_type>(val), _min);
+        } else {
+            base_unsigned modulus = static_cast<base_unsigned>(range) + 1;
+            return ndnboost::random::detail::add<range_type, result_type>()(
+                static_cast<range_type>(val % modulus), _min);
+        }
+    }
+    
+    template<class Engine>
+    result_type generate(Engine& eng, ndnboost::mpl::false_) const
+    {
+        typedef typename Engine::result_type base_result;
+        typedef typename ndnboost::make_unsigned<result_type>::type range_type;
+        range_type range = random::detail::subtract<result_type>()(_max, _min);
+        base_result val = ndnboost::uniform_01<base_result>()(eng);
+        // what is the worst that can possibly happen here?
+        // base_result may not be able to represent all the values in [0, range]
+        // exactly.  If this happens, it will cause round off error and we
+        // won't be able to produce all the values in the range.  We don't
+        // care about this because the user has already told us not to by
+        // using uniform_smallint.  However, we do need to be careful
+        // to clamp the result, or floating point rounding can produce
+        // an out of range result.
+        range_type offset = static_cast<range_type>(val * (static_cast<base_result>(range) + 1));
+        if(offset > range) return _max;
+        return ndnboost::random::detail::add<range_type, result_type>()(offset , _min);
+    }
+    // \endcond
+
+    result_type _min;
+    result_type _max;
+};
+
+} // namespace random
+
+using random::uniform_smallint;
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_RANDOM_UNIFORM_SMALLINT_HPP
diff --git a/include/ndnboost/regex.hpp b/include/ndnboost/regex.hpp
new file mode 100644
index 0000000..5b1c7a5
--- /dev/null
+++ b/include/ndnboost/regex.hpp
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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/libs/regex for documentation.
+  *   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.
+  */
+
+
+/* start with C compatibility API */
+
+#ifndef NDNBOOST_RE_REGEX_HPP
+#define NDNBOOST_RE_REGEX_HPP
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+
+#include <ndnboost/regex/v4/regex.hpp>
+
+#endif  // include
+
+
+
+
diff --git a/include/ndnboost/regex/config.hpp b/include/ndnboost/regex/config.hpp
new file mode 100644
index 0000000..a8168b6
--- /dev/null
+++ b/include/ndnboost/regex/config.hpp
@@ -0,0 +1,435 @@
+/*
+ *
+ * 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         config.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: regex extended config setup.
+  */
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#define NDNBOOST_REGEX_CONFIG_HPP
+/*
+ * Borland C++ Fix/error check
+ * this has to go *before* we include any std lib headers:
+ */
+#if defined(__BORLANDC__)
+#  include <ndnboost/regex/config/borland.hpp>
+#endif
+
+/*****************************************************************************
+ *
+ *  Include all the headers we need here:
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+
+#  ifndef NDNBOOST_REGEX_USER_CONFIG
+#     define NDNBOOST_REGEX_USER_CONFIG <ndnboost/regex/user.hpp>
+#  endif
+
+#  include NDNBOOST_REGEX_USER_CONFIG
+
+#  include <ndnboost/config.hpp>
+
+#else
+   /*
+    * C build,
+    * don't include <ndnboost/config.hpp> because that may
+    * do C++ specific things in future...
+    */
+#  include <stdlib.h>
+#  include <stddef.h>
+#  ifdef _MSC_VER
+#     define NDNBOOST_MSVC _MSC_VER
+#  endif
+#endif
+
+/*****************************************************************************
+ *
+ *  Boilerplate regex config options:
+ *
+ ****************************************************************************/
+
+/* Obsolete macro, use NDNBOOST_VERSION instead: */
+#define NDNBOOST_RE_VERSION 320
+
+/* fix: */
+#if defined(_UNICODE) && !defined(UNICODE)
+#define UNICODE
+#endif
+
+/*
+ * Fix for gcc prior to 3.4: std::ctype<wchar_t> doesn't allow
+ * masks to be combined, for example:
+ * std::use_facet<std::ctype<wchar_t> >.is(std::ctype_base::lower|std::ctype_base::upper, L'a');
+ * returns *false*.
+ */
+#ifdef __GLIBCPP__
+#  define NDNBOOST_REGEX_BUGGY_CTYPE_FACET
+#endif
+
+/*
+ * Intel C++ before 8.0 ends up with unresolved externals unless we turn off
+ * extern template support:
+ */
+#if defined(NDNBOOST_INTEL) && defined(__cplusplus) && (NDNBOOST_INTEL <= 800)
+#  define NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#endif
+/*
+ * Visual C++ doesn't support external templates with C++ extensions turned off:
+ */
+#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
+#  define NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#endif
+/*
+ * Shared regex lib will crash without this, frankly it looks a lot like a gcc bug:
+ */
+#if defined(__MINGW32__)
+#  define NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#endif
+
+/*
+ * If there isn't good enough wide character support then there will
+ * be no wide character regular expressions:
+ */
+#if (defined(NDNBOOST_NO_CWCHAR) || defined(NDNBOOST_NO_CWCTYPE) || defined(NDNBOOST_NO_STD_WSTRING))
+#  if !defined(NDNBOOST_NO_WREGEX)
+#     define NDNBOOST_NO_WREGEX
+#  endif
+#else
+#  if defined(__sgi) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
+      /* STLPort on IRIX is misconfigured: <cwctype> does not compile
+       * as a temporary fix include <wctype.h> instead and prevent inclusion
+       * of STLPort version of <cwctype> */
+#     include <wctype.h>
+#     define __STLPORT_CWCTYPE
+#     define _STLP_CWCTYPE
+#  endif
+
+#ifdef __cplusplus
+#  include <ndnboost/regex/config/cwchar.hpp>
+#endif
+
+#endif
+
+/*
+ * If Win32 support has been disabled for boost in general, then
+ * it is for regex in particular:
+ */
+#if defined(NDNBOOST_DISABLE_WIN32) && !defined(NDNBOOST_REGEX_NO_W32)
+#  define NDNBOOST_REGEX_NO_W32
+#endif
+
+/* disable our own file-iterators and mapfiles if we can't
+ * support them: */
+#if !defined(NDNBOOST_HAS_DIRENT_H) && !(defined(_WIN32) && !defined(NDNBOOST_REGEX_NO_W32))
+#  define NDNBOOST_REGEX_NO_FILEITER
+#endif
+
+/* backwards compatibitity: */
+#if defined(NDNBOOST_RE_NO_LIB)
+#  define NDNBOOST_REGEX_NO_LIB
+#endif
+
+#if defined(__GNUC__) && (defined(_WIN32) || defined(__CYGWIN__))
+/* gcc on win32 has problems if you include <windows.h>
+   (sporadically generates bad code). */
+#  define NDNBOOST_REGEX_NO_W32
+#endif
+#if defined(__COMO__) && !defined(NDNBOOST_REGEX_NO_W32) && !defined(_MSC_EXTENSIONS)
+#  define NDNBOOST_REGEX_NO_W32
+#endif
+
+/*****************************************************************************
+ *
+ *  Wide character workarounds:
+ *
+ ****************************************************************************/
+
+/*
+ * define NDNBOOST_REGEX_HAS_OTHER_WCHAR_T when wchar_t is a native type, but the users
+ * code may be built with wchar_t as unsigned short: basically when we're building
+ * with MSVC and the /Zc:wchar_t option we place some extra unsigned short versions
+ * of the non-inline functions in the library, so that users can still link to the lib,
+ * irrespective of whether their own code is built with /Zc:wchar_t.
+ * Note that this does NOT WORK with VC10 when the C++ locale is in effect as
+ * the locale's <unsigned short> facets simply do not compile in that case.
+ */
+#if defined(__cplusplus) && (defined(NDNBOOST_MSVC) || defined(__ICL)) && !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T) && defined(NDNBOOST_WINDOWS) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && !defined(NDNBOOST_RWSTD_VER) && ((_MSC_VER < 1600) || !defined(NDNBOOST_REGEX_USE_CPP_LOCALE))
+#  define NDNBOOST_REGEX_HAS_OTHER_WCHAR_T
+#  ifdef NDNBOOST_MSVC
+#     pragma warning(push)
+#     pragma warning(disable : 4251 4231)
+#     if NDNBOOST_MSVC < 1600
+#        pragma warning(disable : 4660)
+#     endif
+#  endif
+#  if defined(_DLL) && defined(NDNBOOST_MSVC) && (NDNBOOST_MSVC < 1600)
+#     include <string>
+      extern template class __declspec(dllimport) std::basic_string<unsigned short>;
+#  endif
+#  ifdef NDNBOOST_MSVC
+#     pragma warning(pop)
+#  endif
+#endif
+
+
+/*****************************************************************************
+ *
+ *  Set up dll import/export options:
+ *
+ ****************************************************************************/
+
+#ifndef NDNBOOST_SYMBOL_EXPORT
+#  define NDNBOOST_SYMBOL_EXPORT
+#  define NDNBOOST_SYMBOL_IMPORT
+#endif
+
+#if (defined(NDNBOOST_REGEX_DYN_LINK) || defined(NDNBOOST_ALL_DYN_LINK)) && !defined(NDNBOOST_REGEX_STATIC_LINK)
+#  if defined(NDNBOOST_REGEX_SOURCE)
+#     define NDNBOOST_REGEX_DECL NDNBOOST_SYMBOL_EXPORT
+#     define NDNBOOST_REGEX_BUILD_DLL
+#  else
+#     define NDNBOOST_REGEX_DECL NDNBOOST_SYMBOL_IMPORT
+#  endif
+#else
+#  define NDNBOOST_REGEX_DECL
+#endif
+
+#if !defined(NDNBOOST_REGEX_NO_LIB) && !defined(NDNBOOST_REGEX_SOURCE) && !defined(NDNBOOST_ALL_NO_LIB) && defined(__cplusplus)
+#  define NDNBOOST_LIB_NAME ndnboost_regex
+#  if defined(NDNBOOST_REGEX_DYN_LINK) || defined(NDNBOOST_ALL_DYN_LINK)
+#     define NDNBOOST_DYN_LINK
+#  endif
+#  ifdef NDNBOOST_REGEX_DIAG
+#     define NDNBOOST_LIB_DIAGNOSTIC
+#  endif
+#  include <ndnboost/config/auto_link.hpp>
+#endif
+
+/*****************************************************************************
+ *
+ *  Set up function call type:
+ *
+ ****************************************************************************/
+
+#if defined(NDNBOOST_MSVC) && (NDNBOOST_MSVC >= 1200) && defined(_MSC_EXTENSIONS)
+#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED) || defined(NDNBOOST_REGEX_NO_FASTCALL)
+#  define NDNBOOST_REGEX_CALL __cdecl
+#else
+#  define NDNBOOST_REGEX_CALL __fastcall
+#endif
+#  define NDNBOOST_REGEX_CCALL __cdecl
+#endif
+
+#if defined(__BORLANDC__) && !defined(NDNBOOST_DISABLE_WIN32)
+#  define NDNBOOST_REGEX_CALL __fastcall
+#  define NDNBOOST_REGEX_CCALL __stdcall
+#endif
+
+#ifndef NDNBOOST_REGEX_CALL
+#  define NDNBOOST_REGEX_CALL
+#endif
+#ifndef NDNBOOST_REGEX_CCALL
+#define NDNBOOST_REGEX_CCALL
+#endif
+
+/*****************************************************************************
+ *
+ *  Set up localisation model:
+ *
+ ****************************************************************************/
+
+/* backwards compatibility: */
+#ifdef NDNBOOST_RE_LOCALE_C
+#  define NDNBOOST_REGEX_USE_C_LOCALE
+#endif
+
+#ifdef NDNBOOST_RE_LOCALE_CPP
+#  define NDNBOOST_REGEX_USE_CPP_LOCALE
+#endif
+
+#if defined(__CYGWIN__)
+#  define NDNBOOST_REGEX_USE_C_LOCALE
+#endif
+
+/* Win32 defaults to native Win32 locale: */
+#if defined(_WIN32) && !defined(NDNBOOST_REGEX_USE_WIN32_LOCALE) && !defined(NDNBOOST_REGEX_USE_C_LOCALE) && !defined(NDNBOOST_REGEX_USE_CPP_LOCALE) && !defined(NDNBOOST_REGEX_NO_W32)
+#  define NDNBOOST_REGEX_USE_WIN32_LOCALE
+#endif
+/* otherwise use C++ locale if supported: */
+#if !defined(NDNBOOST_REGEX_USE_WIN32_LOCALE) && !defined(NDNBOOST_REGEX_USE_C_LOCALE) && !defined(NDNBOOST_REGEX_USE_CPP_LOCALE) && !defined(NDNBOOST_NO_STD_LOCALE)
+#  define NDNBOOST_REGEX_USE_CPP_LOCALE
+#endif
+/* otherwise use C+ locale: */
+#if !defined(NDNBOOST_REGEX_USE_WIN32_LOCALE) && !defined(NDNBOOST_REGEX_USE_C_LOCALE) && !defined(NDNBOOST_REGEX_USE_CPP_LOCALE)
+#  define NDNBOOST_REGEX_USE_C_LOCALE
+#endif
+
+#ifndef NDNBOOST_REGEX_MAX_STATE_COUNT
+#  define NDNBOOST_REGEX_MAX_STATE_COUNT 100000000
+#endif
+
+
+/*****************************************************************************
+ *
+ *  Error Handling for exception free compilers:
+ *
+ ****************************************************************************/
+
+#ifdef NDNBOOST_NO_EXCEPTIONS
+/*
+ * If there are no exceptions then we must report critical-errors
+ * the only way we know how; by terminating.
+ */
+#include <stdexcept>
+#include <string>
+#include <ndnboost/throw_exception.hpp>
+
+#  define NDNBOOST_REGEX_NOEH_ASSERT(x)\
+if(0 == (x))\
+{\
+   std::string s("Error: critical regex++ failure in: ");\
+   s.append(#x);\
+   std::runtime_error e(s);\
+   ndnboost::throw_exception(e);\
+}
+#else
+/*
+ * With exceptions then error handling is taken care of and
+ * there is no need for these checks:
+ */
+#  define NDNBOOST_REGEX_NOEH_ASSERT(x)
+#endif
+
+
+/*****************************************************************************
+ *
+ *  Stack protection under MS Windows:
+ *
+ ****************************************************************************/
+
+#if !defined(NDNBOOST_REGEX_NO_W32) && !defined(NDNBOOST_REGEX_V3)
+#  if(defined(_WIN32) || defined(_WIN64) || defined(_WINCE)) \
+        && !defined(__GNUC__) \
+        && !(defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)) \
+        && !(defined(__MWERKS__) && (__MWERKS__ <= 0x3003))
+#     define NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+#  endif
+#elif defined(NDNBOOST_REGEX_HAS_MS_STACK_GUARD)
+#  undef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+#endif
+
+#if defined(__cplusplus) && defined(NDNBOOST_REGEX_HAS_MS_STACK_GUARD)
+
+namespace ndnboost{
+namespace re_detail{
+
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL reset_stack_guard_page();
+
+}
+}
+
+#endif
+
+
+/*****************************************************************************
+ *
+ *  Algorithm selection and configuration:
+ *
+ ****************************************************************************/
+
+#if !defined(NDNBOOST_REGEX_RECURSIVE) && !defined(NDNBOOST_REGEX_NON_RECURSIVE)
+#  if defined(NDNBOOST_REGEX_HAS_MS_STACK_GUARD) && !defined(_STLP_DEBUG) && !defined(__STL_DEBUG) && !(defined(NDNBOOST_MSVC) && (NDNBOOST_MSVC >= 1400))
+#     define NDNBOOST_REGEX_RECURSIVE
+#  else
+#     define NDNBOOST_REGEX_NON_RECURSIVE
+#  endif
+#endif
+
+#ifdef NDNBOOST_REGEX_NON_RECURSIVE
+#  ifdef NDNBOOST_REGEX_RECURSIVE
+#     error "Can't set both NDNBOOST_REGEX_RECURSIVE and NDNBOOST_REGEX_NON_RECURSIVE"
+#  endif
+#  ifndef NDNBOOST_REGEX_BLOCKSIZE
+#     define NDNBOOST_REGEX_BLOCKSIZE 4096
+#  endif
+#  if NDNBOOST_REGEX_BLOCKSIZE < 512
+#     error "NDNBOOST_REGEX_BLOCKSIZE must be at least 512"
+#  endif
+#  ifndef NDNBOOST_REGEX_MAX_BLOCKS
+#     define NDNBOOST_REGEX_MAX_BLOCKS 1024
+#  endif
+#  ifdef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+#     undef NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+#  endif
+#  ifndef NDNBOOST_REGEX_MAX_CACHE_BLOCKS
+#     define NDNBOOST_REGEX_MAX_CACHE_BLOCKS 16
+#  endif
+#endif
+
+
+/*****************************************************************************
+ *
+ *  helper memory allocation functions:
+ *
+ ****************************************************************************/
+
+#if defined(__cplusplus) && defined(NDNBOOST_REGEX_NON_RECURSIVE)
+namespace ndnboost{ namespace re_detail{
+
+NDNBOOST_REGEX_DECL void* NDNBOOST_REGEX_CALL get_mem_block();
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL put_mem_block(void*);
+
+}} /* namespaces */
+#endif
+
+/*****************************************************************************
+ *
+ *  Diagnostics:
+ *
+ ****************************************************************************/
+
+#ifdef NDNBOOST_REGEX_CONFIG_INFO
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL print_regex_library_info();
+#endif
+
+#if defined(NDNBOOST_REGEX_DIAG)
+#  pragma message ("NDNBOOST_REGEX_DECL" NDNBOOST_STRINGIZE(=NDNBOOST_REGEX_DECL))
+#  pragma message ("NDNBOOST_REGEX_CALL" NDNBOOST_STRINGIZE(=NDNBOOST_REGEX_CALL))
+#  pragma message ("NDNBOOST_REGEX_CCALL" NDNBOOST_STRINGIZE(=NDNBOOST_REGEX_CCALL))
+#ifdef NDNBOOST_REGEX_USE_C_LOCALE
+#  pragma message ("Using C locale in regex traits class")
+#elif NDNBOOST_REGEX_USE_CPP_LOCALE
+#  pragma message ("Using C++ locale in regex traits class")
+#else
+#  pragma message ("Using Win32 locale in regex traits class")
+#endif
+#if defined(NDNBOOST_REGEX_DYN_LINK) || defined(NDNBOOST_ALL_DYN_LINK)
+#  pragma message ("Dynamic linking enabled")
+#endif
+#if defined(NDNBOOST_REGEX_NO_LIB) || defined(NDNBOOST_ALL_NO_LIB)
+#  pragma message ("Auto-linking disabled")
+#endif
+#ifdef NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#  pragma message ("Extern templates disabled")
+#endif
+
+#endif
+
+#endif
+
+
+
+
diff --git a/include/ndnboost/regex/config/borland.hpp b/include/ndnboost/regex/config/borland.hpp
new file mode 100644
index 0000000..6e202e1
--- /dev/null
+++ b/include/ndnboost/regex/config/borland.hpp
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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         ndnboost/regex/config/borland.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: regex borland-specific config setup.
+  */
+
+
+#if defined(__BORLANDC__)
+#  if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
+      // problems with std::basic_string and dll RTL:
+#     if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
+#        ifdef NDNBOOST_REGEX_BUILD_DLL
+#           error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
+#        else
+#           pragma message("Defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!")
+#        endif
+#     endif
+#     ifndef _RTLDLL
+         // this is harmless for a staic link:
+#        define _RWSTD_COMPILE_INSTANTIATE
+#     endif
+      // external templates cause problems for some reason:
+#     define NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#  endif
+#  if (__BORLANDC__ <= 0x540) && !defined(NDNBOOST_REGEX_NO_LIB) && !defined(_NO_VCL)
+      // C++ Builder 4 and earlier, we can't tell whether we should be using
+      // the VCL runtime or not, do a static link instead:
+#     define NDNBOOST_REGEX_STATIC_LINK
+#  endif
+   //
+   // VCL support:
+   // if we're building a console app then there can't be any VCL (can there?)
+#  if !defined(__CONSOLE__) && !defined(_NO_VCL)
+#     define NDNBOOST_REGEX_USE_VCL
+#  endif
+   //
+   // if this isn't Win32 then don't automatically select link
+   // libraries:
+   //
+#  ifndef _Windows
+#     ifndef NDNBOOST_REGEX_NO_LIB
+#        define NDNBOOST_REGEX_NO_LIB
+#     endif
+#     ifndef NDNBOOST_REGEX_STATIC_LINK
+#        define NDNBOOST_REGEX_STATIC_LINK
+#     endif
+#  endif
+
+#if __BORLANDC__ < 0x600
+//
+// string workarounds:
+//
+#include <cstring>
+#undef strcmp
+#undef strcpy
+#endif
+
+#endif
+
+
diff --git a/include/ndnboost/regex/config/cwchar.hpp b/include/ndnboost/regex/config/cwchar.hpp
new file mode 100644
index 0000000..7165c1f
--- /dev/null
+++ b/include/ndnboost/regex/config/cwchar.hpp
@@ -0,0 +1,207 @@
+/*
+ *
+ * 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         ndnboost/regex/config/cwchar.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: regex wide character string fixes.
+  */
+
+#ifndef NDNBOOST_REGEX_CONFIG_CWCHAR_HPP
+#define NDNBOOST_REGEX_CONFIG_CWCHAR_HPP
+
+#include <cwchar>
+#include <cwctype>
+#include <ndnboost/config.hpp>
+
+#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
+// apparently this is required for the RW STL on Linux:
+#undef iswalnum
+#undef iswalpha
+#undef iswblank
+#undef iswcntrl
+#undef iswdigit
+#undef iswgraph
+#undef iswlower
+#undef iswprint
+#undef iswprint
+#undef iswpunct
+#undef iswspace
+#undef iswupper
+#undef iswxdigit
+#undef iswctype
+#undef towlower
+#undef towupper
+#undef towctrans
+#undef wctrans
+#undef wctype
+#endif
+
+namespace std{
+
+#ifndef NDNBOOST_NO_STDC_NAMESPACE
+extern "C"{
+#endif
+
+#ifdef iswalnum
+inline int (iswalnum)(wint_t i)
+{ return iswalnum(i); }
+#undef iswalnum
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswalnum;
+#endif
+
+#ifdef iswalpha
+inline int (iswalpha)(wint_t i)
+{ return iswalpha(i); }
+#undef iswalpha
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswalpha;
+#endif
+
+#ifdef iswcntrl
+inline int (iswcntrl)(wint_t i)
+{ return iswcntrl(i); }
+#undef iswcntrl
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswcntrl;
+#endif
+
+#ifdef iswdigit
+inline int (iswdigit)(wint_t i)
+{ return iswdigit(i); }
+#undef iswdigit
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswdigit;
+#endif
+
+#ifdef iswgraph
+inline int (iswgraph)(wint_t i)
+{ return iswgraph(i); }
+#undef iswgraph
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswgraph;
+#endif
+
+#ifdef iswlower
+inline int (iswlower)(wint_t i)
+{ return iswlower(i); }
+#undef iswlower
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswlower;
+#endif
+
+#ifdef iswprint
+inline int (iswprint)(wint_t i)
+{ return iswprint(i); }
+#undef iswprint
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswprint;
+#endif
+
+#ifdef iswpunct
+inline int (iswpunct)(wint_t i)
+{ return iswpunct(i); }
+#undef iswpunct
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswpunct;
+#endif
+
+#ifdef iswspace
+inline int (iswspace)(wint_t i)
+{ return iswspace(i); }
+#undef iswspace
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswspace;
+#endif
+
+#ifdef iswupper
+inline int (iswupper)(wint_t i)
+{ return iswupper(i); }
+#undef iswupper
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswupper;
+#endif
+
+#ifdef iswxdigit
+inline int (iswxdigit)(wint_t i)
+{ return iswxdigit(i); }
+#undef iswxdigit
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::iswxdigit;
+#endif
+
+#ifdef towlower
+inline wint_t (towlower)(wint_t i)
+{ return towlower(i); }
+#undef towlower
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::towlower;
+#endif
+
+#ifdef towupper
+inline wint_t (towupper)(wint_t i)
+{ return towupper(i); }
+#undef towupper
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using :: towupper;
+#endif
+
+#ifdef wcscmp
+inline int (wcscmp)(const wchar_t *p1, const wchar_t *p2)
+{ return wcscmp(p1,p2); }
+#undef wcscmp
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::wcscmp;
+#endif
+
+#ifdef wcscoll
+inline int (wcscoll)(const wchar_t *p1, const wchar_t *p2)
+{ return wcscoll(p1,p2); }
+#undef wcscoll
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE) && !defined(UNDER_CE)
+using ::wcscoll;
+#endif
+
+#ifdef wcscpy
+inline wchar_t *(wcscpy)(wchar_t *p1, const wchar_t *p2)
+{ return wcscpy(p1,p2); }
+#undef wcscpy
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::wcscpy;
+#endif
+
+#ifdef wcslen
+inline size_t (wcslen)(const wchar_t *p)
+{ return wcslen(p); }
+#undef wcslen
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::wcslen;
+#endif
+
+#ifdef wcsxfrm
+size_t wcsxfrm(wchar_t *p1, const wchar_t *p2, size_t s)
+{ return wcsxfrm(p1,p2,s); }
+#undef wcsxfrm
+#elif defined(NDNBOOST_NO_STDC_NAMESPACE)
+using ::wcsxfrm;
+#endif
+
+
+#ifndef NDNBOOST_NO_STDC_NAMESPACE
+} // extern "C"
+#endif
+
+} // namespace std
+
+#endif
+
diff --git a/include/ndnboost/regex/icu.hpp b/include/ndnboost/regex/icu.hpp
new file mode 100644
index 0000000..6328520
--- /dev/null
+++ b/include/ndnboost/regex/icu.hpp
@@ -0,0 +1,1031 @@
+/*
+ *
+ * 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         icu.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Unicode regular expressions on top of the ICU Library.
+  */
+
+#ifndef NDNBOOST_REGEX_ICU_HPP
+#define NDNBOOST_REGEX_ICU_HPP
+
+#include <unicode/utypes.h>
+#include <unicode/uchar.h>
+#include <unicode/coll.h>
+#include <ndnboost/regex.hpp>
+#include <ndnboost/regex/pending/unicode_iterator.hpp>
+#include <ndnboost/mpl/int_fwd.hpp>
+#include <bitset>
+
+#ifdef NDNBOOST_MSVC
+#pragma warning (push)
+#pragma warning (disable: 4251)
+#endif
+
+namespace ndnboost{
+
+namespace re_detail{
+
+// 
+// Implementation details:
+//
+class NDNBOOST_REGEX_DECL icu_regex_traits_implementation
+{
+   typedef UChar32                      char_type;
+   typedef std::size_t                  size_type;
+   typedef std::vector<char_type>       string_type;
+   typedef U_NAMESPACE_QUALIFIER Locale locale_type;
+   typedef ndnboost::uint_least32_t        char_class_type;
+public:
+   icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& l)
+      : m_locale(l)
+   {
+      UErrorCode success = U_ZERO_ERROR;
+      m_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
+      if(U_SUCCESS(success) == 0)
+         init_error();
+      m_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::IDENTICAL);
+      success = U_ZERO_ERROR;
+      m_primary_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
+      if(U_SUCCESS(success) == 0)
+         init_error();
+      m_primary_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::PRIMARY);
+   }
+   U_NAMESPACE_QUALIFIER Locale getloc()const
+   {
+      return m_locale;
+   }
+   string_type do_transform(const char_type* p1, const char_type* p2, const U_NAMESPACE_QUALIFIER Collator* pcoll) const;
+   string_type transform(const char_type* p1, const char_type* p2) const
+   {
+      return do_transform(p1, p2, m_collator.get());
+   }
+   string_type transform_primary(const char_type* p1, const char_type* p2) const
+   {
+      return do_transform(p1, p2, m_primary_collator.get());
+   }
+private:
+   void init_error()
+   {
+      std::runtime_error e("Could not initialize ICU resources");
+      ndnboost::throw_exception(e);
+   }
+   U_NAMESPACE_QUALIFIER Locale m_locale;                                  // The ICU locale that we're using
+   ndnboost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_collator;          // The full collation object
+   ndnboost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_primary_collator;  // The primary collation object
+};
+
+inline ndnboost::shared_ptr<icu_regex_traits_implementation> get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& loc)
+{
+   return ndnboost::shared_ptr<icu_regex_traits_implementation>(new icu_regex_traits_implementation(loc));
+}
+
+}
+
+class NDNBOOST_REGEX_DECL icu_regex_traits
+{
+public:
+   typedef UChar32                      char_type;
+   typedef std::size_t                  size_type;
+   typedef std::vector<char_type>       string_type;
+   typedef U_NAMESPACE_QUALIFIER Locale locale_type;
+#ifdef NDNBOOST_NO_INT64_T
+   typedef std::bitset<64>              char_class_type;
+#else
+   typedef ndnboost::uint64_t              char_class_type;
+#endif
+
+   struct boost_extensions_tag{};
+
+   icu_regex_traits()
+      : m_pimpl(re_detail::get_icu_regex_traits_implementation(U_NAMESPACE_QUALIFIER Locale()))
+   {
+   }
+   static size_type length(const char_type* p);
+
+   ::ndnboost::regex_constants::syntax_type syntax_type(char_type c)const
+   {
+      return ((c < 0x7f) && (c > 0)) ? re_detail::get_default_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
+   }
+   ::ndnboost::regex_constants::escape_syntax_type escape_syntax_type(char_type c) const
+   {
+      return ((c < 0x7f) && (c > 0)) ? re_detail::get_default_escape_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
+   }
+   char_type translate(char_type c) const
+   {
+      return c;
+   }
+   char_type translate_nocase(char_type c) const
+   {
+      return ::u_tolower(c);
+   }
+   char_type translate(char_type c, bool icase) const
+   {
+      return icase ? translate_nocase(c) : translate(c);
+   }
+   char_type tolower(char_type c) const
+   {
+      return ::u_tolower(c);
+   }
+   char_type toupper(char_type c) const
+   {
+      return ::u_toupper(c);
+   }
+   string_type transform(const char_type* p1, const char_type* p2) const
+   {
+      return m_pimpl->transform(p1, p2);
+   }
+   string_type transform_primary(const char_type* p1, const char_type* p2) const
+   {
+      return m_pimpl->transform_primary(p1, p2);
+   }
+   char_class_type lookup_classname(const char_type* p1, const char_type* p2) const;
+   string_type lookup_collatename(const char_type* p1, const char_type* p2) const;
+   bool isctype(char_type c, char_class_type f) const;
+   int toi(const char_type*& p1, const char_type* p2, int radix)const
+   {
+      return re_detail::global_toi(p1, p2, radix, *this);
+   }
+   int value(char_type c, int radix)const
+   {
+      return u_digit(c, static_cast< ::int8_t>(radix));
+   }
+   locale_type imbue(locale_type l)
+   {
+      locale_type result(m_pimpl->getloc());
+      m_pimpl = re_detail::get_icu_regex_traits_implementation(l);
+      return result;
+   }
+   locale_type getloc()const
+   {
+      return locale_type();
+   }
+   std::string error_string(::ndnboost::regex_constants::error_type n) const
+   {
+      return re_detail::get_default_error_string(n);
+   }
+private:
+   icu_regex_traits(const icu_regex_traits&);
+   icu_regex_traits& operator=(const icu_regex_traits&);
+
+   //
+   // define the bitmasks offsets we need for additional character properties:
+   //
+   enum{
+      offset_blank = U_CHAR_CATEGORY_COUNT,
+      offset_space = U_CHAR_CATEGORY_COUNT+1,
+      offset_xdigit = U_CHAR_CATEGORY_COUNT+2,
+      offset_underscore = U_CHAR_CATEGORY_COUNT+3,
+      offset_unicode = U_CHAR_CATEGORY_COUNT+4,
+      offset_any = U_CHAR_CATEGORY_COUNT+5,
+      offset_ascii = U_CHAR_CATEGORY_COUNT+6,
+      offset_horizontal = U_CHAR_CATEGORY_COUNT+7,
+      offset_vertical = U_CHAR_CATEGORY_COUNT+8
+   };
+
+   //
+   // and now the masks:
+   //
+   static const char_class_type mask_blank;
+   static const char_class_type mask_space;
+   static const char_class_type mask_xdigit;
+   static const char_class_type mask_underscore;
+   static const char_class_type mask_unicode;
+   static const char_class_type mask_any;
+   static const char_class_type mask_ascii;
+   static const char_class_type mask_horizontal;
+   static const char_class_type mask_vertical;
+
+   static char_class_type lookup_icu_mask(const ::UChar32* p1, const ::UChar32* p2);
+
+   ndnboost::shared_ptr< ::ndnboost::re_detail::icu_regex_traits_implementation> m_pimpl;
+};
+
+} // namespace ndnboost
+
+//
+// template instances:
+//
+#define NDNBOOST_REGEX_CHAR_T UChar32
+#undef NDNBOOST_REGEX_TRAITS_T
+#define NDNBOOST_REGEX_TRAITS_T , icu_regex_traits
+#define NDNBOOST_REGEX_ICU_INSTANCES
+#ifdef NDNBOOST_REGEX_ICU_INSTANTIATE
+#  define NDNBOOST_REGEX_INSTANTIATE
+#endif
+#include <ndnboost/regex/v4/instances.hpp>
+#undef NDNBOOST_REGEX_CHAR_T
+#undef NDNBOOST_REGEX_TRAITS_T
+#undef NDNBOOST_REGEX_ICU_INSTANCES
+#ifdef NDNBOOST_REGEX_INSTANTIATE
+#  undef NDNBOOST_REGEX_INSTANTIATE
+#endif
+
+namespace ndnboost{
+
+// types:
+typedef basic_regex< ::UChar32, icu_regex_traits> u32regex;
+typedef match_results<const ::UChar32*> u32match;
+typedef match_results<const ::UChar*> u16match;
+
+//
+// Construction of 32-bit regex types from UTF-8 and UTF-16 primitives:
+//
+namespace re_detail{
+
+#if !defined(NDNBOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt, 
+                              const ndnboost::mpl::int_<1>*)
+{
+   typedef ndnboost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
+   return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt, 
+                              const ndnboost::mpl::int_<2>*)
+{
+   typedef ndnboost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
+   return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt, 
+                              const ndnboost::mpl::int_<4>*)
+{
+   return u32regex(i, j, opt);
+}
+#else
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt, 
+                              const ndnboost::mpl::int_<1>*)
+{
+   typedef ndnboost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
+   typedef std::vector<UChar32> vector_type;
+   vector_type v;
+   conv_type a(i, i, j), b(j, i, j);
+   while(a != b)
+   {
+      v.push_back(*a);
+      ++a;
+   }
+   if(v.size())
+      return u32regex(&*v.begin(), v.size(), opt);
+   return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt, 
+                              const ndnboost::mpl::int_<2>*)
+{
+   typedef ndnboost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
+   typedef std::vector<UChar32> vector_type;
+   vector_type v;
+   conv_type a(i, i, j), b(j, i, j);
+   while(a != b)
+   {
+      v.push_back(*a);
+      ++a;
+   }
+   if(v.size())
+      return u32regex(&*v.begin(), v.size(), opt);
+   return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt, 
+                              const ndnboost::mpl::int_<4>*)
+{
+   typedef std::vector<UChar32> vector_type;
+   vector_type v;
+   while(i != j)
+   {
+      v.push_back((UChar32)(*i));
+      ++i;
+   }
+   if(v.size())
+      return u32regex(&*v.begin(), v.size(), opt);
+   return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
+}
+#endif
+}
+
+//
+// Construction from an iterator pair:
+//
+template <class InputIterator>
+inline u32regex make_u32regex(InputIterator i, 
+                              InputIterator j, 
+                              ndnboost::regex_constants::syntax_option_type opt)
+{
+   return re_detail::do_make_u32regex(i, j, opt, static_cast<ndnboost::mpl::int_<sizeof(*i)> const*>(0));
+}
+//
+// construction from UTF-8 nul-terminated strings:
+//
+inline u32regex make_u32regex(const char* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
+{
+   return re_detail::do_make_u32regex(p, p + std::strlen(p), opt, static_cast<ndnboost::mpl::int_<1> const*>(0));
+}
+inline u32regex make_u32regex(const unsigned char* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
+{
+   return re_detail::do_make_u32regex(p, p + std::strlen(reinterpret_cast<const char*>(p)), opt, static_cast<ndnboost::mpl::int_<1> const*>(0));
+}
+//
+// construction from UTF-16 nul-terminated strings:
+//
+#ifndef NDNBOOST_NO_WREGEX
+inline u32regex make_u32regex(const wchar_t* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
+{
+   return re_detail::do_make_u32regex(p, p + std::wcslen(p), opt, static_cast<ndnboost::mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex make_u32regex(const UChar* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
+{
+   return re_detail::do_make_u32regex(p, p + u_strlen(p), opt, static_cast<ndnboost::mpl::int_<2> const*>(0));
+}
+#endif
+//
+// construction from basic_string class-template:
+//
+template<class C, class T, class A>
+inline u32regex make_u32regex(const std::basic_string<C, T, A>& s, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
+{
+   return re_detail::do_make_u32regex(s.begin(), s.end(), opt, static_cast<ndnboost::mpl::int_<sizeof(C)> const*>(0));
+}
+//
+// Construction from ICU string type:
+//
+inline u32regex make_u32regex(const U_NAMESPACE_QUALIFIER UnicodeString& s, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
+{
+   return re_detail::do_make_u32regex(s.getBuffer(), s.getBuffer() + s.length(), opt, static_cast<ndnboost::mpl::int_<2> const*>(0));
+}
+
+//
+// regex_match overloads that widen the character type as appropriate:
+//
+namespace re_detail{
+template<class MR1, class MR2>
+void copy_results(MR1& out, MR2 const& in)
+{
+   // copy results from an adapted MR2 match_results:
+   out.set_size(in.size(), in.prefix().first.base(), in.suffix().second.base());
+   out.set_base(in.base().base());
+   for(int i = 0; i < (int)in.size(); ++i)
+   {
+      if(in[i].matched)
+      {
+         out.set_first(in[i].first.base(), i);
+         out.set_second(in[i].second.base(), i);
+      }
+   }
+}
+
+template <class BidiIterator, class Allocator>
+inline bool do_regex_match(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 ndnboost::mpl::int_<4> const*)
+{
+   return ::ndnboost::regex_match(first, last, m, e, flags);
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_match(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 ndnboost::mpl::int_<2> const*)
+{
+   typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
+   typedef match_results<conv_type>                   match_type;
+   //typedef typename match_type::allocator_type        alloc_type;
+   match_type what;
+   bool result = ::ndnboost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
+   // copy results across to m:
+   if(result) copy_results(m, what);
+   return result;
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_match(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 ndnboost::mpl::int_<1> const*)
+{
+   typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
+   typedef match_results<conv_type>                   match_type;
+   //typedef typename match_type::allocator_type        alloc_type;
+   match_type what;
+   bool result = ::ndnboost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
+   // copy results across to m:
+   if(result) copy_results(m, what);
+   return result;
+}
+} // namespace re_detail
+
+template <class BidiIterator, class Allocator>
+inline bool u32regex_match(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_match(const UChar* p, 
+                 match_results<const UChar*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
+inline bool u32regex_match(const wchar_t* p, 
+                 match_results<const wchar_t*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const char* p, 
+                 match_results<const char*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const unsigned char* p, 
+                 match_results<const unsigned char*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const std::string& s, 
+                        match_results<std::string::const_iterator>& m, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef NDNBOOST_NO_STD_WSTRING
+inline bool u32regex_match(const std::wstring& s, 
+                        match_results<std::wstring::const_iterator>& m, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
+                        match_results<const UChar*>& m, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+//
+// regex_match overloads that do not return what matched:
+//
+template <class BidiIterator>
+inline bool u32regex_match(BidiIterator first, BidiIterator last, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<BidiIterator> m;
+   return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_match(const UChar* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const UChar*> m;
+   return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
+inline bool u32regex_match(const wchar_t* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const wchar_t*> m;
+   return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const char* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const char*> m;
+   return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const unsigned char* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const unsigned char*> m;
+   return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const std::string& s, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::string::const_iterator> m;
+   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef NDNBOOST_NO_STD_WSTRING
+inline bool u32regex_match(const std::wstring& s, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::wstring::const_iterator> m;
+   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const UChar*> m;
+   return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+
+//
+// regex_search overloads that widen the character type as appropriate:
+//
+namespace re_detail{
+template <class BidiIterator, class Allocator>
+inline bool do_regex_search(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 BidiIterator base,
+                 ndnboost::mpl::int_<4> const*)
+{
+   return ::ndnboost::regex_search(first, last, m, e, flags, base);
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_search(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 BidiIterator base,
+                 ndnboost::mpl::int_<2> const*)
+{
+   typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
+   typedef match_results<conv_type>                   match_type;
+   //typedef typename match_type::allocator_type        alloc_type;
+   match_type what;
+   bool result = ::ndnboost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
+   // copy results across to m:
+   if(result) copy_results(m, what);
+   return result;
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_search(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 BidiIterator base,
+                 ndnboost::mpl::int_<1> const*)
+{
+   typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
+   typedef match_results<conv_type>                   match_type;
+   //typedef typename match_type::allocator_type        alloc_type;
+   match_type what;
+   bool result = ::ndnboost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
+   // copy results across to m:
+   if(result) copy_results(m, what);
+   return result;
+}
+}
+
+template <class BidiIterator, class Allocator>
+inline bool u32regex_search(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+template <class BidiIterator, class Allocator>
+inline bool u32regex_search(BidiIterator first, BidiIterator last, 
+                 match_results<BidiIterator, Allocator>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags,
+                 BidiIterator base)
+{
+   return re_detail::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_search(const UChar* p, 
+                 match_results<const UChar*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
+inline bool u32regex_search(const wchar_t* p, 
+                 match_results<const wchar_t*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const char* p, 
+                 match_results<const char*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const unsigned char* p, 
+                 match_results<const unsigned char*>& m, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const std::string& s, 
+                        match_results<std::string::const_iterator>& m, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef NDNBOOST_NO_STD_WSTRING
+inline bool u32regex_search(const std::wstring& s, 
+                        match_results<std::wstring::const_iterator>& m, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
+                        match_results<const UChar*>& m, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+template <class BidiIterator>
+inline bool u32regex_search(BidiIterator first, BidiIterator last, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<BidiIterator> m;
+   return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_search(const UChar* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const UChar*> m;
+   return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
+inline bool u32regex_search(const wchar_t* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const wchar_t*> m;
+   return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const char* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const char*> m;
+   return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const unsigned char* p, 
+                 const u32regex& e, 
+                 match_flag_type flags = match_default)
+{
+   match_results<const unsigned char*> m;
+   return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const std::string& s, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::string::const_iterator> m;
+   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef NDNBOOST_NO_STD_WSTRING
+inline bool u32regex_search(const std::wstring& s, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<std::wstring::const_iterator> m;
+   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
+                        const u32regex& e, 
+                        match_flag_type flags = match_default)
+{
+   match_results<const UChar*> m;
+   return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+
+//
+// overloads for regex_replace with utf-8 and utf-16 data types:
+//
+namespace re_detail{
+template <class I>
+inline std::pair< ndnboost::u8_to_u32_iterator<I>, ndnboost::u8_to_u32_iterator<I> >
+   make_utf32_seq(I i, I j, mpl::int_<1> const*)
+{
+   return std::pair< ndnboost::u8_to_u32_iterator<I>, ndnboost::u8_to_u32_iterator<I> >(ndnboost::u8_to_u32_iterator<I>(i, i, j), ndnboost::u8_to_u32_iterator<I>(j, i, j));
+}
+template <class I>
+inline std::pair< ndnboost::u16_to_u32_iterator<I>, ndnboost::u16_to_u32_iterator<I> >
+   make_utf32_seq(I i, I j, mpl::int_<2> const*)
+{
+   return std::pair< ndnboost::u16_to_u32_iterator<I>, ndnboost::u16_to_u32_iterator<I> >(ndnboost::u16_to_u32_iterator<I>(i, i, j), ndnboost::u16_to_u32_iterator<I>(j, i, j));
+}
+template <class I>
+inline std::pair< I, I >
+   make_utf32_seq(I i, I j, mpl::int_<4> const*)
+{
+   return std::pair< I, I >(i, j);
+}
+template <class charT>
+inline std::pair< ndnboost::u8_to_u32_iterator<const charT*>, ndnboost::u8_to_u32_iterator<const charT*> >
+   make_utf32_seq(const charT* p, mpl::int_<1> const*)
+{
+   std::size_t len = std::strlen((const char*)p);
+   return std::pair< ndnboost::u8_to_u32_iterator<const charT*>, ndnboost::u8_to_u32_iterator<const charT*> >(ndnboost::u8_to_u32_iterator<const charT*>(p, p, p+len), ndnboost::u8_to_u32_iterator<const charT*>(p+len, p, p+len));
+}
+template <class charT>
+inline std::pair< ndnboost::u16_to_u32_iterator<const charT*>, ndnboost::u16_to_u32_iterator<const charT*> >
+   make_utf32_seq(const charT* p, mpl::int_<2> const*)
+{
+   std::size_t len = u_strlen((const UChar*)p);
+   return std::pair< ndnboost::u16_to_u32_iterator<const charT*>, ndnboost::u16_to_u32_iterator<const charT*> >(ndnboost::u16_to_u32_iterator<const charT*>(p, p, p + len), ndnboost::u16_to_u32_iterator<const charT*>(p+len, p, p + len));
+}
+template <class charT>
+inline std::pair< const charT*, const charT* >
+   make_utf32_seq(const charT* p, mpl::int_<4> const*)
+{
+   return std::pair< const charT*, const charT* >(p, p+icu_regex_traits::length((UChar32 const*)p));
+}
+template <class OutputIterator>
+inline OutputIterator make_utf32_out(OutputIterator o, mpl::int_<4> const*)
+{
+   return o;
+}
+template <class OutputIterator>
+inline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<2> const*)
+{
+   return o;
+}
+template <class OutputIterator>
+inline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<1> const*)
+{
+   return o;
+}
+
+template <class OutputIterator, class I1, class I2>
+OutputIterator do_regex_replace(OutputIterator out,
+                                 std::pair<I1, I1> const& in,
+                                 const u32regex& e, 
+                                 const std::pair<I2, I2>& fmt, 
+                                 match_flag_type flags
+                                 )
+{
+   // unfortunately we have to copy the format string in order to pass in onward:
+   std::vector<UChar32> f;
+#ifndef NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+   f.assign(fmt.first, fmt.second);
+#else
+   f.clear();
+   I2 pos = fmt.first;
+   while(pos != fmt.second)
+      f.push_back(*pos++);
+#endif
+   
+   regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);
+   regex_iterator<I1, UChar32, icu_regex_traits> j;
+   if(i == j)
+   {
+      if(!(flags & regex_constants::format_no_copy))
+         out = re_detail::copy(in.first, in.second, out);
+   }
+   else
+   {
+      I1 last_m = in.first;
+      while(i != j)
+      {
+         if(!(flags & regex_constants::format_no_copy))
+            out = re_detail::copy(i->prefix().first, i->prefix().second, out); 
+         if(f.size())
+            out = ::ndnboost::re_detail::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());
+         else
+            out = ::ndnboost::re_detail::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());
+         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, in.second, out);
+   }
+   return out;
+}
+template <class BaseIterator>
+inline const BaseIterator& extract_output_base(const BaseIterator& b)
+{
+   return b;
+}
+template <class BaseIterator>
+inline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)
+{
+   return b.base();
+}
+template <class BaseIterator>
+inline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)
+{
+   return b.base();
+}
+}  // re_detail
+
+template <class OutputIterator, class BidirectionalIterator, class charT>
+inline OutputIterator u32regex_replace(OutputIterator out,
+                         BidirectionalIterator first,
+                         BidirectionalIterator last,
+                         const u32regex& e, 
+                         const charT* fmt, 
+                         match_flag_type flags = match_default)
+{
+   return re_detail::extract_output_base
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+   <OutputIterator>
+#endif
+    (
+      re_detail::do_regex_replace(
+         re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+         re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+         e,
+         re_detail::make_utf32_seq(fmt, static_cast<mpl::int_<sizeof(*fmt)> const*>(0)),
+         flags)
+      );
+}
+
+template <class OutputIterator, class Iterator, class charT>
+inline OutputIterator u32regex_replace(OutputIterator out,
+                         Iterator first,
+                         Iterator last,
+                         const u32regex& e, 
+                         const std::basic_string<charT>& fmt,
+                         match_flag_type flags = match_default)
+{
+   return re_detail::extract_output_base
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+   <OutputIterator>
+#endif
+    (
+      re_detail::do_regex_replace(
+         re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+         re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+         e,
+         re_detail::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<mpl::int_<sizeof(charT)> const*>(0)),
+         flags)
+      );
+}
+
+template <class OutputIterator, class Iterator>
+inline OutputIterator u32regex_replace(OutputIterator out,
+                         Iterator first,
+                         Iterator last,
+                         const u32regex& e, 
+                         const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
+                         match_flag_type flags = match_default)
+{
+   return re_detail::extract_output_base
+#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
+   <OutputIterator>
+#endif
+   (
+      re_detail::do_regex_replace(
+         re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+         re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+         e,
+         re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
+         flags)
+      );
+}
+
+template <class charT>
+std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
+                         const u32regex& e, 
+                         const charT* fmt,
+                         match_flag_type flags = match_default)
+{
+   std::basic_string<charT> result;
+   re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+   u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);
+   return result;
+}
+
+template <class charT>
+std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
+                         const u32regex& e, 
+                         const std::basic_string<charT>& fmt,
+                         match_flag_type flags = match_default)
+{
+   std::basic_string<charT> result;
+   re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+   u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);
+   return result;
+}
+
+namespace re_detail{
+
+class unicode_string_out_iterator
+{
+   U_NAMESPACE_QUALIFIER UnicodeString* out;
+public:
+   unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString& s) : out(&s) {}
+   unicode_string_out_iterator& operator++() { return *this; }
+   unicode_string_out_iterator& operator++(int) { return *this; }
+   unicode_string_out_iterator& operator*() { return *this; }
+   unicode_string_out_iterator& operator=(UChar v) 
+   { 
+      *out += v; 
+      return *this; 
+   }
+   typedef std::ptrdiff_t difference_type;
+   typedef UChar value_type;
+   typedef value_type* pointer;
+   typedef value_type& reference;
+   typedef std::output_iterator_tag iterator_category;
+};
+
+}
+
+inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
+                         const u32regex& e, 
+                         const UChar* fmt,
+                         match_flag_type flags = match_default)
+{
+   U_NAMESPACE_QUALIFIER UnicodeString result;
+   re_detail::unicode_string_out_iterator i(result);
+   u32regex_replace(i, s.getBuffer(), s.getBuffer()+s.length(), e, fmt, flags);
+   return result;
+}
+
+inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
+                         const u32regex& e, 
+                         const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
+                         match_flag_type flags = match_default)
+{
+   U_NAMESPACE_QUALIFIER UnicodeString result;
+   re_detail::unicode_string_out_iterator i(result);
+   re_detail::do_regex_replace(
+         re_detail::make_utf32_out(i, static_cast<mpl::int_<2> const*>(0)),
+         re_detail::make_utf32_seq(s.getBuffer(), s.getBuffer()+s.length(), static_cast<mpl::int_<2> const*>(0)),
+         e,
+         re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
+         flags);
+   return result;
+}
+
+} // namespace ndnboost.
+
+#ifdef NDNBOOST_MSVC
+#pragma warning (pop)
+#endif
+
+#include <ndnboost/regex/v4/u32regex_iterator.hpp>
+#include <ndnboost/regex/v4/u32regex_token_iterator.hpp>
+
+#endif
diff --git a/include/ndnboost/regex/pattern_except.hpp b/include/ndnboost/regex/pattern_except.hpp
new file mode 100644
index 0000000..7ec0d45
--- /dev/null
+++ b/include/ndnboost/regex/pattern_except.hpp
@@ -0,0 +1,100 @@
+/*
+ *
+ * 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         pattern_except.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares pattern-matching exception classes.
+  */
+
+#ifndef NDNBOOST_RE_PAT_EXCEPT_HPP
+#define NDNBOOST_RE_PAT_EXCEPT_HPP
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+
+#include <stdexcept>
+#include <cstddef>
+#include <ndnboost/regex/v4/error_type.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 : 4275)
+#endif
+class NDNBOOST_REGEX_DECL regex_error : public std::runtime_error
+{
+public:
+   explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0);
+   explicit regex_error(regex_constants::error_type err);
+   ~regex_error() throw();
+   regex_constants::error_type code()const
+   { return m_error_code; }
+   std::ptrdiff_t position()const
+   { return m_position; }
+   void raise()const;
+private:
+   regex_constants::error_type m_error_code;
+   std::ptrdiff_t m_position;
+};
+
+typedef regex_error bad_pattern;
+typedef regex_error bad_expression;
+
+namespace re_detail{
+
+NDNBOOST_REGEX_DECL void NDNBOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex);
+
+template <class traits>
+void raise_error(const traits& t, regex_constants::error_type code)
+{
+   (void)t;  // warning suppression
+   std::runtime_error e(t.error_string(code));
+   ::ndnboost::re_detail::raise_runtime_error(e);
+}
+
+}
+
+#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/pending/object_cache.hpp b/include/ndnboost/regex/pending/object_cache.hpp
new file mode 100644
index 0000000..d0a088c
--- /dev/null
+++ b/include/ndnboost/regex/pending/object_cache.hpp
@@ -0,0 +1,165 @@
+/*
+ *
+ * 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         object_cache.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Implements a generic object cache.
+  */
+
+#ifndef NDNBOOST_REGEX_OBJECT_CACHE_HPP
+#define NDNBOOST_REGEX_OBJECT_CACHE_HPP
+
+#include <map>
+#include <list>
+#include <stdexcept>
+#include <string>
+#include <ndnboost/config.hpp>
+#include <ndnboost/shared_ptr.hpp>
+#ifdef NDNBOOST_HAS_THREADS
+#include <ndnboost/regex/pending/static_mutex.hpp>
+#endif
+
+namespace ndnboost{
+
+template <class Key, class Object>
+class object_cache
+{
+public:
+   typedef std::pair< ::ndnboost::shared_ptr<Object const>, Key const*> value_type;
+   typedef std::list<value_type> list_type;
+   typedef typename list_type::iterator list_iterator;
+   typedef std::map<Key, list_iterator> map_type;
+   typedef typename map_type::iterator map_iterator;
+   typedef typename list_type::size_type size_type;
+   static ndnboost::shared_ptr<Object const> get(const Key& k, size_type l_max_cache_size);
+
+private:
+   static ndnboost::shared_ptr<Object const> do_get(const Key& k, size_type l_max_cache_size);
+
+   struct data
+   {
+      list_type   cont;
+      map_type    index;
+   };
+
+   // Needed by compilers not implementing the resolution to DR45. For reference,
+   // see http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
+   friend struct data;
+};
+
+template <class Key, class Object>
+ndnboost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type l_max_cache_size)
+{
+#ifdef NDNBOOST_HAS_THREADS
+   static ndnboost::static_mutex mut = NDNBOOST_STATIC_MUTEX_INIT;
+
+   ndnboost::static_mutex::scoped_lock l(mut);
+   if(l)
+   {
+      return do_get(k, l_max_cache_size);
+   }
+   //
+   // what do we do if the lock fails?
+   // for now just throw, but we should never really get here...
+   //
+   ::ndnboost::throw_exception(std::runtime_error("Error in thread safety code: could not acquire a lock"));
+#if defined(NDNBOOST_NO_UNREACHABLE_RETURN_DETECTION) || defined(NDNBOOST_NO_EXCEPTIONS)
+   return ndnboost::shared_ptr<Object>();
+#endif
+#else
+   return do_get(k, l_max_cache_size);
+#endif
+}
+
+template <class Key, class Object>
+ndnboost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type l_max_cache_size)
+{
+   typedef typename object_cache<Key, Object>::data object_data;
+   typedef typename map_type::size_type map_size_type;
+   static object_data s_data;
+
+   //
+   // see if the object is already in the cache:
+   //
+   map_iterator mpos = s_data.index.find(k);
+   if(mpos != s_data.index.end())
+   {
+      //
+      // Eureka! 
+      // We have a cached item, bump it up the list and return it:
+      //
+      if(--(s_data.cont.end()) != mpos->second)
+      {
+         // splice out the item we want to move:
+         list_type temp;
+         temp.splice(temp.end(), s_data.cont, mpos->second);
+         // and now place it at the end of the list:
+         s_data.cont.splice(s_data.cont.end(), temp, temp.begin());
+         NDNBOOST_ASSERT(*(s_data.cont.back().second) == k);
+         // update index with new position:
+         mpos->second = --(s_data.cont.end());
+         NDNBOOST_ASSERT(&(mpos->first) == mpos->second->second);
+         NDNBOOST_ASSERT(&(mpos->first) == s_data.cont.back().second);
+      }
+      return s_data.cont.back().first;
+   }
+   //
+   // if we get here then the item is not in the cache,
+   // so create it:
+   //
+   ndnboost::shared_ptr<Object const> result(new Object(k));
+   //
+   // Add it to the list, and index it:
+   //
+   s_data.cont.push_back(value_type(result, static_cast<Key const*>(0)));
+   s_data.index.insert(std::make_pair(k, --(s_data.cont.end())));
+   s_data.cont.back().second = &(s_data.index.find(k)->first);
+   map_size_type s = s_data.index.size();
+   NDNBOOST_ASSERT(s_data.index[k]->first.get() == result.get());
+   NDNBOOST_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
+   NDNBOOST_ASSERT(s_data.index.find(k)->first == k);
+   if(s > l_max_cache_size)
+   {
+      //
+      // We have too many items in the list, so we need to start
+      // popping them off the back of the list, but only if they're
+      // being held uniquely by us:
+      //
+      list_iterator pos = s_data.cont.begin();
+      list_iterator last = s_data.cont.end();
+      while((pos != last) && (s > l_max_cache_size))
+      {
+         if(pos->first.unique())
+         {
+            list_iterator condemmed(pos);
+            ++pos;
+            // now remove the items from our containers, 
+            // then order has to be as follows:
+            NDNBOOST_ASSERT(s_data.index.find(*(condemmed->second)) != s_data.index.end());
+            s_data.index.erase(*(condemmed->second));
+            s_data.cont.erase(condemmed); 
+            --s;
+         }
+         else
+            ++pos;
+      }
+      NDNBOOST_ASSERT(s_data.index[k]->first.get() == result.get());
+      NDNBOOST_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
+      NDNBOOST_ASSERT(s_data.index.find(k)->first == k);
+   }
+   return result;
+}
+
+}
+
+#endif
diff --git a/include/ndnboost/regex/pending/static_mutex.hpp b/include/ndnboost/regex/pending/static_mutex.hpp
new file mode 100644
index 0000000..c7d2659
--- /dev/null
+++ b/include/ndnboost/regex/pending/static_mutex.hpp
@@ -0,0 +1,179 @@
+/*
+ *
+ * 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         static_mutex.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares static_mutex lock type, there are three different
+  *                implementations: POSIX pthreads, WIN32 threads, and portable,
+  *                these are described in more detail below.
+  */
+
+#ifndef NDNBOOST_REGEX_STATIC_MUTEX_HPP
+#define NDNBOOST_REGEX_STATIC_MUTEX_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/regex/config.hpp> // dll import/export options.
+
+#ifdef NDNBOOST_HAS_PTHREADS
+#include <pthread.h>
+#endif
+
+#if defined(NDNBOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
+//
+// pthreads version:
+// simple wrap around a pthread_mutex_t initialized with
+// PTHREAD_MUTEX_INITIALIZER.
+//
+namespace ndnboost{
+
+class static_mutex;
+
+#define NDNBOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
+
+class NDNBOOST_REGEX_DECL scoped_static_mutex_lock
+{
+public:
+   scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
+   ~scoped_static_mutex_lock();
+   inline bool locked()const
+   {
+      return m_have_lock;
+   }
+   inline operator void const*()const
+   {
+      return locked() ? this : 0;
+   }
+   void lock();
+   void unlock();
+private:
+   static_mutex& m_mutex;
+   bool m_have_lock;
+};
+
+class static_mutex
+{
+public:
+   typedef scoped_static_mutex_lock scoped_lock;
+   pthread_mutex_t m_mutex;
+};
+
+} // namespace ndnboost
+#elif defined(NDNBOOST_HAS_WINTHREADS)
+//
+// Win32 version:
+// Use a 32-bit int as a lock, along with a test-and-set
+// implementation using InterlockedCompareExchange.
+//
+
+#include <ndnboost/cstdint.hpp>
+
+namespace ndnboost{
+
+class NDNBOOST_REGEX_DECL scoped_static_mutex_lock;
+
+class static_mutex
+{
+public:
+   typedef scoped_static_mutex_lock scoped_lock;
+   ndnboost::int32_t m_mutex;
+};
+
+#define NDNBOOST_STATIC_MUTEX_INIT { 0, }
+
+class NDNBOOST_REGEX_DECL scoped_static_mutex_lock
+{
+public:
+   scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
+   ~scoped_static_mutex_lock();
+   operator void const*()const
+   {
+      return locked() ? this : 0;
+   }
+   bool locked()const
+   {
+      return m_have_lock;
+   }
+   void lock();
+   void unlock();
+private:
+   static_mutex& m_mutex;
+   bool m_have_lock;
+   scoped_static_mutex_lock(const scoped_static_mutex_lock&);
+   scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
+};
+
+} // namespace
+
+#else
+//
+// Portable version of a static mutex based on Boost.Thread library:
+// This has to use a single mutex shared by all instances of static_mutex
+// because ndnboost::call_once doesn't alow us to pass instance information
+// down to the initialisation proceedure.  In fact the initialisation routine
+// may need to be called more than once - but only once per instance.
+//
+// Since this preprocessor path is almost never taken, we hide these header
+// dependencies so that build tools don't find them.
+//
+#define B1 <ndnboost/thread/once.hpp>
+#define B2 <ndnboost/thread/recursive_mutex.hpp>
+#include B1
+#include B2
+#undef B1
+#undef B2
+
+namespace ndnboost{
+
+class NDNBOOST_REGEX_DECL scoped_static_mutex_lock;
+extern "C" NDNBOOST_REGEX_DECL void ndnboost_regex_free_static_mutex();
+
+class NDNBOOST_REGEX_DECL static_mutex
+{
+public:
+   typedef scoped_static_mutex_lock scoped_lock;
+   static void init();
+   static ndnboost::recursive_mutex* m_pmutex;
+   static ndnboost::once_flag m_once;
+};
+
+#define NDNBOOST_STATIC_MUTEX_INIT {  }
+
+class NDNBOOST_REGEX_DECL scoped_static_mutex_lock
+{
+public:
+   scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
+   ~scoped_static_mutex_lock();
+   operator void const*()const;
+   bool locked()const;
+   void lock();
+   void unlock();
+private:
+   ndnboost::recursive_mutex::scoped_lock* m_plock;
+   bool m_have_lock;
+};
+
+inline scoped_static_mutex_lock::operator void const*()const
+{
+   return locked() ? this : 0;
+}
+
+inline bool scoped_static_mutex_lock::locked()const
+{
+   return m_have_lock;
+}
+
+} // namespace
+
+#endif
+
+#endif
diff --git a/include/ndnboost/regex/pending/unicode_iterator.hpp b/include/ndnboost/regex/pending/unicode_iterator.hpp
new file mode 100644
index 0000000..d66d3b9
--- /dev/null
+++ b/include/ndnboost/regex/pending/unicode_iterator.hpp
@@ -0,0 +1,776 @@
+/*
+ *
+ * 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         unicode_iterator.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Iterator adapters for converting between different Unicode encodings.
+  */
+
+/****************************************************************************
+
+Contents:
+~~~~~~~~~
+
+1) Read Only, Input Adapters:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+template <class BaseIterator, class U8Type = ::ndnboost::uint8_t>
+class u32_to_u8_iterator;
+
+Adapts sequence of UTF-32 code points to "look like" a sequence of UTF-8.
+
+template <class BaseIterator, class U32Type = ::ndnboost::uint32_t>
+class u8_to_u32_iterator;
+
+Adapts sequence of UTF-8 code points to "look like" a sequence of UTF-32.
+
+template <class BaseIterator, class U16Type = ::ndnboost::uint16_t>
+class u32_to_u16_iterator;
+
+Adapts sequence of UTF-32 code points to "look like" a sequence of UTF-16.
+
+template <class BaseIterator, class U32Type = ::ndnboost::uint32_t>
+class u16_to_u32_iterator;
+
+Adapts sequence of UTF-16 code points to "look like" a sequence of UTF-32.
+
+2) Single pass output iterator adapters:
+
+template <class BaseIterator>
+class utf8_output_iterator;
+
+Accepts UTF-32 code points and forwards them on as UTF-8 code points.
+
+template <class BaseIterator>
+class utf16_output_iterator;
+
+Accepts UTF-32 code points and forwards them on as UTF-16 code points.
+
+****************************************************************************/
+
+#ifndef NDNBOOST_REGEX_UNICODE_ITERATOR_HPP
+#define NDNBOOST_REGEX_UNICODE_ITERATOR_HPP
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/iterator/iterator_facade.hpp>
+#include <ndnboost/static_assert.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <stdexcept>
+#ifndef NDNBOOST_NO_STD_LOCALE
+#include <sstream>
+#include <ios>
+#endif
+#include <limits.h> // CHAR_BIT
+
+namespace ndnboost{
+
+namespace detail{
+
+static const ::ndnboost::uint16_t high_surrogate_base = 0xD7C0u;
+static const ::ndnboost::uint16_t low_surrogate_base = 0xDC00u;
+static const ::ndnboost::uint32_t ten_bit_mask = 0x3FFu;
+
+inline bool is_high_surrogate(::ndnboost::uint16_t v)
+{
+   return (v & 0xFFFFFC00u) == 0xd800u;
+}
+inline bool is_low_surrogate(::ndnboost::uint16_t v)
+{
+   return (v & 0xFFFFFC00u) == 0xdc00u;
+}
+template <class T>
+inline bool is_surrogate(T v)
+{
+   return (v & 0xFFFFF800u) == 0xd800;
+}
+
+inline unsigned utf8_byte_count(ndnboost::uint8_t c)
+{
+   // if the most significant bit with a zero in it is in position
+   // 8-N then there are N bytes in this UTF-8 sequence:
+   ndnboost::uint8_t mask = 0x80u;
+   unsigned result = 0;
+   while(c & mask)
+   {
+      ++result;
+      mask >>= 1;
+   }
+   return (result == 0) ? 1 : ((result > 4) ? 4 : result);
+}
+
+inline unsigned utf8_trailing_byte_count(ndnboost::uint8_t c)
+{
+   return utf8_byte_count(c) - 1;
+}
+
+#ifdef NDNBOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4100)
+#endif
+inline void invalid_utf32_code_point(::ndnboost::uint32_t val)
+{
+#ifndef NDNBOOST_NO_STD_LOCALE
+   std::stringstream ss;
+   ss << "Invalid UTF-32 code point U+" << std::showbase << std::hex << val << " encountered while trying to encode UTF-16 sequence";
+   std::out_of_range e(ss.str());
+#else
+   std::out_of_range e("Invalid UTF-32 code point encountered while trying to encode UTF-16 sequence");
+#endif
+   ndnboost::throw_exception(e);
+}
+#ifdef NDNBOOST_MSVC
+#pragma warning(pop)
+#endif
+
+
+} // namespace detail
+
+template <class BaseIterator, class U16Type = ::ndnboost::uint16_t>
+class u32_to_u16_iterator
+   : public ndnboost::iterator_facade<u32_to_u16_iterator<BaseIterator, U16Type>, U16Type, std::bidirectional_iterator_tag, const U16Type>
+{
+   typedef ndnboost::iterator_facade<u32_to_u16_iterator<BaseIterator, U16Type>, U16Type, std::bidirectional_iterator_tag, const U16Type> base_type;
+
+#if !defined(NDNBOOST_NO_STD_ITERATOR_TRAITS) && !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+   NDNBOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 32);
+   NDNBOOST_STATIC_ASSERT(sizeof(U16Type)*CHAR_BIT == 16);
+#endif
+
+public:
+   typename base_type::reference
+      dereference()const
+   {
+      if(m_current == 2)
+         extract_current();
+      return m_values[m_current];
+   }
+   bool equal(const u32_to_u16_iterator& that)const
+   {
+      if(m_position == that.m_position)
+      {
+         // Both m_currents must be equal, or both even
+         // this is the same as saying their sum must be even:
+         return (m_current + that.m_current) & 1u ? false : true;
+      }
+      return false;
+   }
+   void increment()
+   {
+      // if we have a pending read then read now, so that we know whether
+      // to skip a position, or move to a low-surrogate:
+      if(m_current == 2)
+      {
+         // pending read:
+         extract_current();
+      }
+      // move to the next surrogate position:
+      ++m_current;
+      // if we've reached the end skip a position:
+      if(m_values[m_current] == 0)
+      {
+         m_current = 2;
+         ++m_position;
+      }
+   }
+   void decrement()
+   {
+      if(m_current != 1)
+      {
+         // decrementing an iterator always leads to a valid position:
+         --m_position;
+         extract_current();
+         m_current = m_values[1] ? 1 : 0;
+      }
+      else
+      {
+         m_current = 0;
+      }
+   }
+   BaseIterator base()const
+   {
+      return m_position;
+   }
+   // construct:
+   u32_to_u16_iterator() : m_position(), m_current(0)
+   {
+      m_values[0] = 0;
+      m_values[1] = 0;
+      m_values[2] = 0;
+   }
+   u32_to_u16_iterator(BaseIterator b) : m_position(b), m_current(2)
+   {
+      m_values[0] = 0;
+      m_values[1] = 0;
+      m_values[2] = 0;
+   }
+private:
+
+   void extract_current()const
+   {
+      // begin by checking for a code point out of range:
+      ::ndnboost::uint32_t v = *m_position;
+      if(v >= 0x10000u)
+      {
+         if(v > 0x10FFFFu)
+            detail::invalid_utf32_code_point(*m_position);
+         // split into two surrogates:
+         m_values[0] = static_cast<U16Type>(v >> 10) + detail::high_surrogate_base;
+         m_values[1] = static_cast<U16Type>(v & detail::ten_bit_mask) + detail::low_surrogate_base;
+         m_current = 0;
+         NDNBOOST_ASSERT(detail::is_high_surrogate(m_values[0]));
+         NDNBOOST_ASSERT(detail::is_low_surrogate(m_values[1]));
+      }
+      else
+      {
+         // 16-bit code point:
+         m_values[0] = static_cast<U16Type>(*m_position);
+         m_values[1] = 0;
+         m_current = 0;
+         // value must not be a surrogate:
+         if(detail::is_surrogate(m_values[0]))
+            detail::invalid_utf32_code_point(*m_position);
+      }
+   }
+   BaseIterator m_position;
+   mutable U16Type m_values[3];
+   mutable unsigned m_current;
+};
+
+template <class BaseIterator, class U32Type = ::ndnboost::uint32_t>
+class u16_to_u32_iterator
+   : public ndnboost::iterator_facade<u16_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type>
+{
+   typedef ndnboost::iterator_facade<u16_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type> base_type;
+   // special values for pending iterator reads:
+   NDNBOOST_STATIC_CONSTANT(U32Type, pending_read = 0xffffffffu);
+
+#if !defined(NDNBOOST_NO_STD_ITERATOR_TRAITS) && !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+   NDNBOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 16);
+   NDNBOOST_STATIC_ASSERT(sizeof(U32Type)*CHAR_BIT == 32);
+#endif
+
+public:
+   typename base_type::reference
+      dereference()const
+   {
+      if(m_value == pending_read)
+         extract_current();
+      return m_value;
+   }
+   bool equal(const u16_to_u32_iterator& that)const
+   {
+      return m_position == that.m_position;
+   }
+   void increment()
+   {
+      // skip high surrogate first if there is one:
+      if(detail::is_high_surrogate(*m_position)) ++m_position;
+      ++m_position;
+      m_value = pending_read;
+   }
+   void decrement()
+   {
+      --m_position;
+      // if we have a low surrogate then go back one more:
+      if(detail::is_low_surrogate(*m_position)) 
+         --m_position;
+      m_value = pending_read;
+   }
+   BaseIterator base()const
+   {
+      return m_position;
+   }
+   // construct:
+   u16_to_u32_iterator() : m_position()
+   {
+      m_value = pending_read;
+   }
+   u16_to_u32_iterator(BaseIterator b) : m_position(b)
+   {
+      m_value = pending_read;
+   }
+   //
+   // Range checked version:
+   //
+   u16_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)
+   {
+      m_value = pending_read;
+      //
+      // The range must not start with a low surrogate, or end in a high surrogate,
+      // otherwise we run the risk of running outside the underlying input range.
+      // Likewise b must not be located at a low surrogate.
+      //
+      ndnboost::uint16_t val;
+      if(start != end)
+      {
+         if((b != start) && (b != end))
+         {
+            val = *b;
+            if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))
+               invalid_code_point(val);
+         }
+         val = *start;
+         if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))
+            invalid_code_point(val);
+         val = *--end;
+         if(detail::is_high_surrogate(val))
+            invalid_code_point(val);
+      }
+   }
+private:
+   static void invalid_code_point(::ndnboost::uint16_t val)
+   {
+#ifndef NDNBOOST_NO_STD_LOCALE
+      std::stringstream ss;
+      ss << "Misplaced UTF-16 surrogate U+" << std::showbase << std::hex << val << " encountered while trying to encode UTF-32 sequence";
+      std::out_of_range e(ss.str());
+#else
+      std::out_of_range e("Misplaced UTF-16 surrogate encountered while trying to encode UTF-32 sequence");
+#endif
+      ndnboost::throw_exception(e);
+   }
+   void extract_current()const
+   {
+      m_value = static_cast<U32Type>(static_cast< ::ndnboost::uint16_t>(*m_position));
+      // if the last value is a high surrogate then adjust m_position and m_value as needed:
+      if(detail::is_high_surrogate(*m_position))
+      {
+         // precondition; next value must have be a low-surrogate:
+         BaseIterator next(m_position);
+         ::ndnboost::uint16_t t = *++next;
+         if((t & 0xFC00u) != 0xDC00u)
+            invalid_code_point(t);
+         m_value = (m_value - detail::high_surrogate_base) << 10;
+         m_value |= (static_cast<U32Type>(static_cast< ::ndnboost::uint16_t>(t)) & detail::ten_bit_mask);
+      }
+      // postcondition; result must not be a surrogate:
+      if(detail::is_surrogate(m_value))
+         invalid_code_point(static_cast< ::ndnboost::uint16_t>(m_value));
+   }
+   BaseIterator m_position;
+   mutable U32Type m_value;
+};
+
+template <class BaseIterator, class U8Type = ::ndnboost::uint8_t>
+class u32_to_u8_iterator
+   : public ndnboost::iterator_facade<u32_to_u8_iterator<BaseIterator, U8Type>, U8Type, std::bidirectional_iterator_tag, const U8Type>
+{
+   typedef ndnboost::iterator_facade<u32_to_u8_iterator<BaseIterator, U8Type>, U8Type, std::bidirectional_iterator_tag, const U8Type> base_type;
+   
+#if !defined(NDNBOOST_NO_STD_ITERATOR_TRAITS) && !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+   NDNBOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 32);
+   NDNBOOST_STATIC_ASSERT(sizeof(U8Type)*CHAR_BIT == 8);
+#endif
+
+public:
+   typename base_type::reference
+      dereference()const
+   {
+      if(m_current == 4)
+         extract_current();
+      return m_values[m_current];
+   }
+   bool equal(const u32_to_u8_iterator& that)const
+   {
+      if(m_position == that.m_position)
+      {
+         // either the m_current's must be equal, or one must be 0 and 
+         // the other 4: which means neither must have bits 1 or 2 set:
+         return (m_current == that.m_current)
+            || (((m_current | that.m_current) & 3) == 0);
+      }
+      return false;
+   }
+   void increment()
+   {
+      // if we have a pending read then read now, so that we know whether
+      // to skip a position, or move to a low-surrogate:
+      if(m_current == 4)
+      {
+         // pending read:
+         extract_current();
+      }
+      // move to the next surrogate position:
+      ++m_current;
+      // if we've reached the end skip a position:
+      if(m_values[m_current] == 0)
+      {
+         m_current = 4;
+         ++m_position;
+      }
+   }
+   void decrement()
+   {
+      if((m_current & 3) == 0)
+      {
+         --m_position;
+         extract_current();
+         m_current = 3;
+         while(m_current && (m_values[m_current] == 0))
+            --m_current;
+      }
+      else
+         --m_current;
+   }
+   BaseIterator base()const
+   {
+      return m_position;
+   }
+   // construct:
+   u32_to_u8_iterator() : m_position(), m_current(0)
+   {
+      m_values[0] = 0;
+      m_values[1] = 0;
+      m_values[2] = 0;
+      m_values[3] = 0;
+      m_values[4] = 0;
+   }
+   u32_to_u8_iterator(BaseIterator b) : m_position(b), m_current(4)
+   {
+      m_values[0] = 0;
+      m_values[1] = 0;
+      m_values[2] = 0;
+      m_values[3] = 0;
+      m_values[4] = 0;
+   }
+private:
+
+   void extract_current()const
+   {
+      ndnboost::uint32_t c = *m_position;
+      if(c > 0x10FFFFu)
+         detail::invalid_utf32_code_point(c);
+      if(c < 0x80u)
+      {
+         m_values[0] = static_cast<unsigned char>(c);
+         m_values[1] = static_cast<unsigned char>(0u);
+         m_values[2] = static_cast<unsigned char>(0u);
+         m_values[3] = static_cast<unsigned char>(0u);
+      }
+      else if(c < 0x800u)
+      {
+         m_values[0] = static_cast<unsigned char>(0xC0u + (c >> 6));
+         m_values[1] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+         m_values[2] = static_cast<unsigned char>(0u);
+         m_values[3] = static_cast<unsigned char>(0u);
+      }
+      else if(c < 0x10000u)
+      {
+         m_values[0] = static_cast<unsigned char>(0xE0u + (c >> 12));
+         m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+         m_values[2] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+         m_values[3] = static_cast<unsigned char>(0u);
+      }
+      else
+      {
+         m_values[0] = static_cast<unsigned char>(0xF0u + (c >> 18));
+         m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));
+         m_values[2] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+         m_values[3] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+      }
+      m_current= 0;
+   }
+   BaseIterator m_position;
+   mutable U8Type m_values[5];
+   mutable unsigned m_current;
+};
+
+template <class BaseIterator, class U32Type = ::ndnboost::uint32_t>
+class u8_to_u32_iterator
+   : public ndnboost::iterator_facade<u8_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type>
+{
+   typedef ndnboost::iterator_facade<u8_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type> base_type;
+   // special values for pending iterator reads:
+   NDNBOOST_STATIC_CONSTANT(U32Type, pending_read = 0xffffffffu);
+
+#if !defined(NDNBOOST_NO_STD_ITERATOR_TRAITS) && !defined(NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+   NDNBOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 8);
+   NDNBOOST_STATIC_ASSERT(sizeof(U32Type)*CHAR_BIT == 32);
+#endif
+
+public:
+   typename base_type::reference
+      dereference()const
+   {
+      if(m_value == pending_read)
+         extract_current();
+      return m_value;
+   }
+   bool equal(const u8_to_u32_iterator& that)const
+   {
+      return m_position == that.m_position;
+   }
+   void increment()
+   {
+      // We must not start with a continuation character:
+      if((static_cast<ndnboost::uint8_t>(*m_position) & 0xC0) == 0x80)
+         invalid_sequence();
+      // skip high surrogate first if there is one:
+      unsigned c = detail::utf8_byte_count(*m_position);
+      if(m_value == pending_read)
+      {
+         // Since we haven't read in a value, we need to validate the code points:
+         for(unsigned i = 0; i < c; ++i)
+         {
+            ++m_position;
+            // We must have a continuation byte:
+            if((i != c - 1) && ((static_cast<ndnboost::uint8_t>(*m_position) & 0xC0) != 0x80))
+               invalid_sequence();
+         }
+      }
+      else
+      {
+         std::advance(m_position, c);
+      }
+      m_value = pending_read;
+   }
+   void decrement()
+   {
+      // Keep backtracking until we don't have a trailing character:
+      unsigned count = 0;
+      while((*--m_position & 0xC0u) == 0x80u) ++count;
+      // now check that the sequence was valid:
+      if(count != detail::utf8_trailing_byte_count(*m_position))
+         invalid_sequence();
+      m_value = pending_read;
+   }
+   BaseIterator base()const
+   {
+      return m_position;
+   }
+   // construct:
+   u8_to_u32_iterator() : m_position()
+   {
+      m_value = pending_read;
+   }
+   u8_to_u32_iterator(BaseIterator b) : m_position(b)
+   {
+      m_value = pending_read;
+   }
+   //
+   // Checked constructor:
+   //
+   u8_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)
+   {
+      m_value = pending_read;
+      //
+      // We must not start with a continuation character, or end with a 
+      // truncated UTF-8 sequence otherwise we run the risk of going past
+      // the start/end of the underlying sequence:
+      //
+      if(start != end)
+      {
+         unsigned char v = *start;
+         if((v & 0xC0u) == 0x80u)
+            invalid_sequence();
+         if((b != start) && (b != end) && ((*b & 0xC0u) == 0x80u))
+            invalid_sequence();
+         BaseIterator pos = end;
+         do
+         {
+            v = *--pos;
+         }
+         while((start != pos) && ((v & 0xC0u) == 0x80u));
+         std::ptrdiff_t extra = detail::utf8_byte_count(v);
+         if(std::distance(pos, end) < extra)
+            invalid_sequence();
+      }
+   }
+private:
+   static void invalid_sequence()
+   {
+      std::out_of_range e("Invalid UTF-8 sequence encountered while trying to encode UTF-32 character");
+      ndnboost::throw_exception(e);
+   }
+   void extract_current()const
+   {
+      m_value = static_cast<U32Type>(static_cast< ::ndnboost::uint8_t>(*m_position));
+      // we must not have a continuation character:
+      if((m_value & 0xC0u) == 0x80u)
+         invalid_sequence();
+      // see how many extra bytes we have:
+      unsigned extra = detail::utf8_trailing_byte_count(*m_position);
+      // extract the extra bits, 6 from each extra byte:
+      BaseIterator next(m_position);
+      for(unsigned c = 0; c < extra; ++c)
+      {
+         ++next;
+         m_value <<= 6;
+         // We must have a continuation byte:
+         if((static_cast<ndnboost::uint8_t>(*next) & 0xC0) != 0x80)
+            invalid_sequence();
+         m_value += static_cast<ndnboost::uint8_t>(*next) & 0x3Fu;
+      }
+      // we now need to remove a few of the leftmost bits, but how many depends
+      // upon how many extra bytes we've extracted:
+      static const ndnboost::uint32_t masks[4] = 
+      {
+         0x7Fu,
+         0x7FFu,
+         0xFFFFu,
+         0x1FFFFFu,
+      };
+      m_value &= masks[extra];
+      // check the result:
+      if(m_value > static_cast<U32Type>(0x10FFFFu))
+         invalid_sequence();
+   }
+   BaseIterator m_position;
+   mutable U32Type m_value;
+};
+
+template <class BaseIterator>
+class utf16_output_iterator
+{
+public:
+   typedef void                                   difference_type;
+   typedef void                                   value_type;
+   typedef ndnboost::uint32_t*                       pointer;
+   typedef ndnboost::uint32_t&                       reference;
+   typedef std::output_iterator_tag               iterator_category;
+
+   utf16_output_iterator(const BaseIterator& b)
+      : m_position(b){}
+   utf16_output_iterator(const utf16_output_iterator& that)
+      : m_position(that.m_position){}
+   utf16_output_iterator& operator=(const utf16_output_iterator& that)
+   {
+      m_position = that.m_position;
+      return *this;
+   }
+   const utf16_output_iterator& operator*()const
+   {
+      return *this;
+   }
+   void operator=(ndnboost::uint32_t val)const
+   {
+      push(val);
+   }
+   utf16_output_iterator& operator++()
+   {
+      return *this;
+   }
+   utf16_output_iterator& operator++(int)
+   {
+      return *this;
+   }
+   BaseIterator base()const
+   {
+      return m_position;
+   }
+private:
+   void push(ndnboost::uint32_t v)const
+   {
+      if(v >= 0x10000u)
+      {
+         // begin by checking for a code point out of range:
+         if(v > 0x10FFFFu)
+            detail::invalid_utf32_code_point(v);
+         // split into two surrogates:
+         *m_position++ = static_cast<ndnboost::uint16_t>(v >> 10) + detail::high_surrogate_base;
+         *m_position++ = static_cast<ndnboost::uint16_t>(v & detail::ten_bit_mask) + detail::low_surrogate_base;
+      }
+      else
+      {
+         // 16-bit code point:
+         // value must not be a surrogate:
+         if(detail::is_surrogate(v))
+            detail::invalid_utf32_code_point(v);
+         *m_position++ = static_cast<ndnboost::uint16_t>(v);
+      }
+   }
+   mutable BaseIterator m_position;
+};
+
+template <class BaseIterator>
+class utf8_output_iterator
+{
+public:
+   typedef void                                   difference_type;
+   typedef void                                   value_type;
+   typedef ndnboost::uint32_t*                       pointer;
+   typedef ndnboost::uint32_t&                       reference;
+   typedef std::output_iterator_tag               iterator_category;
+
+   utf8_output_iterator(const BaseIterator& b)
+      : m_position(b){}
+   utf8_output_iterator(const utf8_output_iterator& that)
+      : m_position(that.m_position){}
+   utf8_output_iterator& operator=(const utf8_output_iterator& that)
+   {
+      m_position = that.m_position;
+      return *this;
+   }
+   const utf8_output_iterator& operator*()const
+   {
+      return *this;
+   }
+   void operator=(ndnboost::uint32_t val)const
+   {
+      push(val);
+   }
+   utf8_output_iterator& operator++()
+   {
+      return *this;
+   }
+   utf8_output_iterator& operator++(int)
+   {
+      return *this;
+   }
+   BaseIterator base()const
+   {
+      return m_position;
+   }
+private:
+   void push(ndnboost::uint32_t c)const
+   {
+      if(c > 0x10FFFFu)
+         detail::invalid_utf32_code_point(c);
+      if(c < 0x80u)
+      {
+         *m_position++ = static_cast<unsigned char>(c);
+      }
+      else if(c < 0x800u)
+      {
+         *m_position++ = static_cast<unsigned char>(0xC0u + (c >> 6));
+         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+      }
+      else if(c < 0x10000u)
+      {
+         *m_position++ = static_cast<unsigned char>(0xE0u + (c >> 12));
+         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+      }
+      else
+      {
+         *m_position++ = static_cast<unsigned char>(0xF0u + (c >> 18));
+         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));
+         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+      }
+   }
+   mutable BaseIterator m_position;
+};
+
+} // namespace ndnboost
+
+#endif // NDNBOOST_REGEX_UNICODE_ITERATOR_HPP
+
diff --git a/include/ndnboost/regex/regex_traits.hpp b/include/ndnboost/regex/regex_traits.hpp
new file mode 100644
index 0000000..2fdb874
--- /dev/null
+++ b/include/ndnboost/regex/regex_traits.hpp
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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_traits.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Declares regular expression traits classes.
+  */
+
+#ifndef NDNBOOST_REGEX_TRAITS_HPP
+#define NDNBOOST_REGEX_TRAITS_HPP
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#  include <ndnboost/regex/config.hpp>
+#endif
+
+#  ifndef NDNBOOST_REGEX_TRAITS_HPP_INCLUDED
+#     include <ndnboost/regex/v4/regex_traits.hpp>
+#  endif
+
+#endif // include
+
+
+
+
+
diff --git a/include/ndnboost/regex/user.hpp b/include/ndnboost/regex/user.hpp
new file mode 100644
index 0000000..f151fc1
--- /dev/null
+++ b/include/ndnboost/regex/user.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         user.hpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: User settable options.
+  */
+
+// define if you want the regex library to use the C locale
+// even on Win32:
+// #define NDNBOOST_REGEX_USE_C_LOCALE
+
+// define this is you want the regex library to use the C++
+// locale:
+// #define NDNBOOST_REGEX_USE_CPP_LOCALE
+
+// define this if the runtime library is a dll, and you
+// want NDNBOOST_REGEX_DYN_LINK to set up dll exports/imports
+// with __declspec(dllexport)/__declspec(dllimport.)
+// #define NDNBOOST_REGEX_HAS_DLL_RUNTIME
+
+// define this if you want to dynamically link to regex,
+// if the runtime library is also a dll (Probably Win32 specific,
+// and has no effect unless NDNBOOST_REGEX_HAS_DLL_RUNTIME is set):
+// #define NDNBOOST_REGEX_DYN_LINK
+
+// define this if you don't want the lib to automatically
+// select its link libraries:
+// #define NDNBOOST_REGEX_NO_LIB
+
+// define this if templates with switch statements cause problems:
+// #define NDNBOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE
+ 
+// define this to disable Win32 support when available:
+// #define NDNBOOST_REGEX_NO_W32
+
+// define this if bool is not a real type:
+// #define NDNBOOST_REGEX_NO_BOOL
+
+// define this if no template instances are to be placed in
+// the library rather than users object files:
+// #define NDNBOOST_REGEX_NO_EXTERNAL_TEMPLATES
+
+// define this if the forward declarations in regex_fwd.hpp
+// cause more problems than they are worth:
+// #define NDNBOOST_REGEX_NO_FWD
+
+// define this if your compiler supports MS Windows structured
+// exception handling.
+// #define NDNBOOST_REGEX_HAS_MS_STACK_GUARD
+
+// define this if you want to use the recursive algorithm
+// even if NDNBOOST_REGEX_HAS_MS_STACK_GUARD is not defined.
+// #define NDNBOOST_REGEX_RECURSIVE
+
+// define this if you want to use the non-recursive
+// algorithm, even if the recursive version would be the default.
+// #define NDNBOOST_REGEX_NON_RECURSIVE
+
+// define this if you want to set the size of the memory blocks
+// used by the non-recursive algorithm.
+// #define NDNBOOST_REGEX_BLOCKSIZE 4096
+
+// define this if you want to set the maximum number of memory blocks
+// used by the non-recursive algorithm.
+// #define NDNBOOST_REGEX_MAX_BLOCKS 1024
+
+// define this if you want to set the maximum number of memory blocks
+// cached by the non-recursive algorithm: Normally this is 16, but can be 
+// higher if you have multiple threads all using boost.regex, or lower 
+// if you don't want boost.regex to cache memory.
+// #define NDNBOOST_REGEX_MAX_CACHE_BLOCKS 16
+
+// define this if you want to be able to access extended capture
+// information in your sub_match's (caution this will slow things
+// down quite a bit).
+// #define NDNBOOST_REGEX_MATCH_EXTRA
+
+// define this if you want to enable support for Unicode via ICU.
+// #define NDNBOOST_HAS_ICU
+
+// define this if you want regex to use __cdecl calling convensions, even when __fastcall is available:
+// #define NDNBOOST_REGEX_NO_FASTCALL
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
diff --git a/include/ndnboost/regex_fwd.hpp b/include/ndnboost/regex_fwd.hpp
new file mode 100644
index 0000000..03e4ed5
--- /dev/null
+++ b/include/ndnboost/regex_fwd.hpp
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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/libs/regex for documentation.
+  *   FILE         regex_fwd.cpp
+  *   VERSION      see <ndnboost/version.hpp>
+  *   DESCRIPTION: Forward declares ndnboost::basic_regex<> and
+  *                associated typedefs.
+  */
+
+#ifndef NDNBOOST_REGEX_FWD_HPP
+#define NDNBOOST_REGEX_FWD_HPP
+
+#ifndef NDNBOOST_REGEX_CONFIG_HPP
+#include <ndnboost/regex/config.hpp>
+#endif
+
+#include <ndnboost/regex/v4/regex_fwd.hpp>
+
+#endif
+
+
+
+
diff --git a/include/ndnboost/system/api_config.hpp b/include/ndnboost/system/api_config.hpp
new file mode 100644
index 0000000..371d130
--- /dev/null
+++ b/include/ndnboost/system/api_config.hpp
@@ -0,0 +1,42 @@
+//  ndnboost/system/api_config.hpp  -------------------------------------------------------//
+
+//  Copyright Beman Dawes 2003, 2006, 2010
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+//  See http://www.boost.org/libs/system for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+//  Boost.System calls operating system API functions to implement system error category
+//  functions. Usually there is no question as to which API is to be used.
+//
+//  In the case of MinGW or Cygwin/MinGW, however, both POSIX and Windows API's are
+//  available. Chaos ensues if other code thinks one is in use when Boost.System was
+//  actually built with the other. This header centralizes the API choice and prevents
+//  user definition of API macros, thus elminating the possibility of mismatches and the
+//  need to test configurations with little or no practical value.
+//
+
+//--------------------------------------------------------------------------------------//
+
+#ifndef NDNBOOST_SYSTEM_API_CONFIG_HPP                  
+#define NDNBOOST_SYSTEM_API_CONFIG_HPP
+
+# if defined(NDNBOOST_POSIX_API) || defined(NDNBOOST_WINDOWS_API)
+#   error user defined NDNBOOST_POSIX_API or NDNBOOST_WINDOWS_API not supported
+# endif
+
+//  NDNBOOST_POSIX_API or NDNBOOST_WINDOWS_API specify which API to use
+//    Cygwin/MinGW does not predefine _WIN32.
+//    Standalone MinGW and all other known Windows compilers do predefine _WIN32
+//    Compilers that predefine _WIN32 or __MINGW32__ do so for Windows 64-bit builds too.
+
+# if defined(_WIN32) || defined(__CYGWIN__) // Windows default, including MinGW and Cygwin
+#   define NDNBOOST_WINDOWS_API
+# else
+#   define NDNBOOST_POSIX_API 
+# endif
+                                     
+#endif  // NDNBOOST_SYSTEM_API_CONFIG_HPP 
diff --git a/include/ndnboost/system/config.hpp b/include/ndnboost/system/config.hpp
new file mode 100644
index 0000000..2180de4
--- /dev/null
+++ b/include/ndnboost/system/config.hpp
@@ -0,0 +1,69 @@
+//  ndnboost/system/config.hpp  -----------------------------------------------------------//
+
+//  Copyright Beman Dawes 2003, 2006
+
+//  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)
+
+//  See http://www.boost.org/libs/system for documentation.
+
+#ifndef NDNBOOST_SYSTEM_CONFIG_HPP                  
+#define NDNBOOST_SYSTEM_CONFIG_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/system/api_config.hpp>  // for NDNBOOST_POSIX_API or NDNBOOST_WINDOWS_API
+
+// This header implements separate compilation features as described in
+// http://www.boost.org/more/separate_compilation.html
+
+//  normalize macros  ------------------------------------------------------------------//
+
+#if !defined(NDNBOOST_SYSTEM_DYN_LINK) && !defined(NDNBOOST_SYSTEM_STATIC_LINK) \
+  && !defined(NDNBOOST_ALL_DYN_LINK) && !defined(NDNBOOST_ALL_STATIC_LINK)
+# define NDNBOOST_SYSTEM_STATIC_LINK
+#endif
+
+#if defined(NDNBOOST_ALL_DYN_LINK) && !defined(NDNBOOST_SYSTEM_DYN_LINK)
+# define NDNBOOST_SYSTEM_DYN_LINK 
+#elif defined(NDNBOOST_ALL_STATIC_LINK) && !defined(NDNBOOST_SYSTEM_STATIC_LINK)
+# define NDNBOOST_SYSTEM_STATIC_LINK 
+#endif
+
+#if defined(NDNBOOST_SYSTEM_DYN_LINK) && defined(NDNBOOST_SYSTEM_STATIC_LINK)
+# error Must not define both NDNBOOST_SYSTEM_DYN_LINK and NDNBOOST_SYSTEM_STATIC_LINK
+#endif
+
+//  enable dynamic or static linking as requested --------------------------------------//
+
+#if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_SYSTEM_DYN_LINK)
+# if defined(NDNBOOST_SYSTEM_SOURCE)
+#   define NDNBOOST_SYSTEM_DECL NDNBOOST_SYMBOL_EXPORT
+# else 
+#   define NDNBOOST_SYSTEM_DECL NDNBOOST_SYMBOL_IMPORT
+# endif
+#else
+# define NDNBOOST_SYSTEM_DECL
+#endif
+
+//  enable automatic library variant selection  ----------------------------------------// 
+
+#if !defined(NDNBOOST_SYSTEM_SOURCE) && !defined(NDNBOOST_ALL_NO_LIB) && !defined(NDNBOOST_SYSTEM_NO_LIB)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define NDNBOOST_LIB_NAME ndnboost_system
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_SYSTEM_DYN_LINK)
+#  define NDNBOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <ndnboost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+
+#endif // NDNBOOST_SYSTEM_CONFIG_HPP
+
diff --git a/include/ndnboost/system/error_code.hpp b/include/ndnboost/system/error_code.hpp
new file mode 100644
index 0000000..9d92c85
--- /dev/null
+++ b/include/ndnboost/system/error_code.hpp
@@ -0,0 +1,521 @@
+//  ndnboost/system/error_code.hpp  ---------------------------------------------//
+
+//  Copyright Beman Dawes 2006, 2007
+//  Copyright Christoper Kohlhoff 2007
+
+//  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)
+
+//  See library home page at http://www.boost.org/libs/system
+
+#ifndef NDNBOOST_ERROR_CODE_HPP
+#define NDNBOOST_ERROR_CODE_HPP
+
+#include <ndnboost/system/config.hpp>
+#include <ndnboost/cstdint.hpp>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/operators.hpp>
+#include <ndnboost/noncopyable.hpp>
+#include <ndnboost/utility/enable_if.hpp>
+#include <ostream>
+#include <string>
+#include <stdexcept>
+#include <functional>
+
+// TODO: undef these macros if not already defined
+#include <ndnboost/cerrno.hpp>
+
+#if !defined(NDNBOOST_POSIX_API) && !defined(NDNBOOST_WINDOWS_API)
+#  error NDNBOOST_POSIX_API or NDNBOOST_WINDOWS_API must be defined
+#endif
+
+#include <ndnboost/config/abi_prefix.hpp> // must be the last #include
+
+#ifndef NDNBOOST_SYSTEM_NOEXCEPT
+#define NDNBOOST_SYSTEM_NOEXCEPT NDNBOOST_NOEXCEPT
+#endif
+
+namespace ndnboost
+{
+  namespace system
+  {
+
+    class error_code;
+    class error_condition;
+
+    //  "Concept" helpers  ---------------------------------------------------//
+
+    template< class T >
+    struct is_error_code_enum { static const bool value = false; };
+
+    template< class T >
+    struct is_error_condition_enum { static const bool value = false; };
+
+    //  generic error_conditions  --------------------------------------------//
+
+    namespace errc
+    {
+      enum errc_t
+      {
+        success = 0,
+        address_family_not_supported = EAFNOSUPPORT,
+        address_in_use = EADDRINUSE,
+        address_not_available = EADDRNOTAVAIL,
+        already_connected = EISCONN,
+        argument_list_too_long = E2BIG,
+        argument_out_of_domain = EDOM,
+        bad_address = EFAULT,
+        bad_file_descriptor = EBADF,
+        bad_message = EBADMSG,
+        broken_pipe = EPIPE,
+        connection_aborted = ECONNABORTED,
+        connection_already_in_progress = EALREADY,
+        connection_refused = ECONNREFUSED,
+        connection_reset = ECONNRESET,
+        cross_device_link = EXDEV,
+        destination_address_required = EDESTADDRREQ,
+        device_or_resource_busy = EBUSY,
+        directory_not_empty = ENOTEMPTY,
+        executable_format_error = ENOEXEC,
+        file_exists = EEXIST,
+        file_too_large = EFBIG,
+        filename_too_long = ENAMETOOLONG,
+        function_not_supported = ENOSYS,
+        host_unreachable = EHOSTUNREACH,
+        identifier_removed = EIDRM,
+        illegal_byte_sequence = EILSEQ,
+        inappropriate_io_control_operation = ENOTTY,
+        interrupted = EINTR,
+        invalid_argument = EINVAL,
+        invalid_seek = ESPIPE,
+        io_error = EIO,
+        is_a_directory = EISDIR,
+        message_size = EMSGSIZE,
+        network_down = ENETDOWN,
+        network_reset = ENETRESET,
+        network_unreachable = ENETUNREACH,
+        no_buffer_space = ENOBUFS,
+        no_child_process = ECHILD,
+        no_link = ENOLINK,
+        no_lock_available = ENOLCK,
+        no_message_available = ENODATA,
+        no_message = ENOMSG,
+        no_protocol_option = ENOPROTOOPT,
+        no_space_on_device = ENOSPC,
+        no_stream_resources = ENOSR,
+        no_such_device_or_address = ENXIO,
+        no_such_device = ENODEV,
+        no_such_file_or_directory = ENOENT,
+        no_such_process = ESRCH,
+        not_a_directory = ENOTDIR,
+        not_a_socket = ENOTSOCK,
+        not_a_stream = ENOSTR,
+        not_connected = ENOTCONN,
+        not_enough_memory = ENOMEM,
+        not_supported = ENOTSUP,
+        operation_canceled = ECANCELED,
+        operation_in_progress = EINPROGRESS,
+        operation_not_permitted = EPERM,
+        operation_not_supported = EOPNOTSUPP,
+        operation_would_block = EWOULDBLOCK,
+        owner_dead = EOWNERDEAD,
+        permission_denied = EACCES,
+        protocol_error = EPROTO,
+        protocol_not_supported = EPROTONOSUPPORT,
+        read_only_file_system = EROFS,
+        resource_deadlock_would_occur = EDEADLK,
+        resource_unavailable_try_again = EAGAIN,
+        result_out_of_range = ERANGE,
+        state_not_recoverable = ENOTRECOVERABLE,
+        stream_timeout = ETIME,
+        text_file_busy = ETXTBSY,
+        timed_out = ETIMEDOUT,
+        too_many_files_open_in_system = ENFILE,
+        too_many_files_open = EMFILE,
+        too_many_links = EMLINK,
+        too_many_symbolic_link_levels = ELOOP,
+        value_too_large = EOVERFLOW,
+        wrong_protocol_type = EPROTOTYPE
+      };
+
+    } // namespace errc
+
+# ifndef NDNBOOST_SYSTEM_NO_DEPRECATED
+    namespace posix = errc;
+    namespace posix_error = errc;
+# endif
+
+    template<> struct is_error_condition_enum<errc::errc_t>
+      { static const bool value = true; };
+
+
+    //  ----------------------------------------------------------------------//
+
+    //  Operating system specific interfaces  --------------------------------//
+
+
+    //  The interface is divided into general and system-specific portions to
+    //  meet these requirements:
+    //
+    //  * Code calling an operating system API can create an error_code with
+    //    a single category (system_category), even for POSIX-like operating
+    //    systems that return some POSIX errno values and some native errno
+    //    values. This code should not have to pay the cost of distinguishing
+    //    between categories, since it is not yet known if that is needed.
+    //
+    //  * Users wishing to write system-specific code should be given enums for
+    //    at least the common error cases.
+    //
+    //  * System specific code should fail at compile time if moved to another
+    //    operating system.
+
+    //  The system specific portions of the interface are located in headers
+    //  with names reflecting the operating system. For example,
+    //
+    //       <ndnboost/system/cygwin_error.hpp>
+    //       <ndnboost/system/linux_error.hpp>
+    //       <ndnboost/system/windows_error.hpp>
+    //
+    //  These headers are effectively empty for compiles on operating systems
+    //  where they are not applicable.
+
+    //  ----------------------------------------------------------------------//
+
+    //  class error_category  ------------------------------------------------//
+
+    class error_category : public noncopyable
+    {
+    public:
+      virtual ~error_category(){}
+
+      virtual const char *     name() const NDNBOOST_SYSTEM_NOEXCEPT = 0;
+      virtual std::string      message( int ev ) const = 0;
+      inline virtual error_condition  default_error_condition( int ev ) const  NDNBOOST_SYSTEM_NOEXCEPT;
+      inline virtual bool             equivalent( int code,
+                                           const error_condition & condition ) const  NDNBOOST_SYSTEM_NOEXCEPT;
+      inline virtual bool             equivalent( const error_code & code,
+                                           int condition ) const  NDNBOOST_SYSTEM_NOEXCEPT;
+
+      bool operator==(const error_category & rhs) const NDNBOOST_SYSTEM_NOEXCEPT { return this == &rhs; }
+      bool operator!=(const error_category & rhs) const NDNBOOST_SYSTEM_NOEXCEPT { return this != &rhs; }
+      bool operator<( const error_category & rhs ) const NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        return std::less<const error_category*>()( this, &rhs );
+      }
+    };
+
+    //  predefined error categories  -----------------------------------------//
+
+# ifdef NDNBOOST_ERROR_CODE_HEADER_ONLY
+    inline const error_category &  system_category() NDNBOOST_SYSTEM_NOEXCEPT;
+    inline const error_category &  generic_category() NDNBOOST_SYSTEM_NOEXCEPT;
+#else
+    NDNBOOST_SYSTEM_DECL const error_category &  system_category() NDNBOOST_SYSTEM_NOEXCEPT;
+    NDNBOOST_SYSTEM_DECL const error_category &  generic_category() NDNBOOST_SYSTEM_NOEXCEPT;
+#endif
+    //  deprecated synonyms --------------------------------------------------//
+
+# ifndef NDNBOOST_SYSTEM_NO_DEPRECATED
+    inline const error_category &  get_system_category() { return system_category(); }
+    inline const error_category &  get_generic_category() { return generic_category(); }
+    inline const error_category &  get_posix_category() { return generic_category(); }
+    static const error_category &  posix_category = generic_category();
+    static const error_category &  errno_ecat     = generic_category();
+    static const error_category &  native_ecat    = system_category();
+# endif
+
+    //  class error_condition  -----------------------------------------------//
+
+    //  error_conditions are portable, error_codes are system or library specific
+
+    class error_condition
+    {
+    public:
+
+      // constructors:
+      error_condition() NDNBOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&generic_category()) {}
+      error_condition( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT : m_val(val), m_cat(&cat) {}
+
+      template <class ErrorConditionEnum>
+        error_condition(ErrorConditionEnum e,
+          typename ndnboost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        *this = make_error_condition(e);
+      }
+
+      // modifiers:
+
+      void assign( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        m_val = val;
+        m_cat = &cat;
+      }
+
+      template<typename ErrorConditionEnum>
+        typename ndnboost::enable_if<is_error_condition_enum<ErrorConditionEnum>, error_condition>::type &
+          operator=( ErrorConditionEnum val ) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        *this = make_error_condition(val);
+        return *this;
+      }
+
+      void clear() NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        m_val = 0;
+        m_cat = &generic_category();
+      }
+
+      // observers:
+      int                     value() const NDNBOOST_SYSTEM_NOEXCEPT    { return m_val; }
+      const error_category &  category() const NDNBOOST_SYSTEM_NOEXCEPT { return *m_cat; }
+      std::string             message() const  { return m_cat->message(value()); }
+
+      typedef void (*unspecified_bool_type)();
+      static void unspecified_bool_true() {}
+
+      operator unspecified_bool_type() const NDNBOOST_SYSTEM_NOEXCEPT  // true if error
+      {
+        return m_val == 0 ? 0 : unspecified_bool_true;
+      }
+
+      bool operator!() const NDNBOOST_SYSTEM_NOEXCEPT  // true if no error
+      {
+        return m_val == 0;
+      }
+
+      // relationals:
+      //  the more symmetrical non-member syntax allows enum
+      //  conversions work for both rhs and lhs.
+      inline friend bool operator==( const error_condition & lhs,
+                                     const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
+      }
+
+      inline friend bool operator<( const error_condition & lhs,
+                                    const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+        //  the more symmetrical non-member syntax allows enum
+        //  conversions work for both rhs and lhs.
+      {
+        return lhs.m_cat < rhs.m_cat
+          || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
+      }
+
+    private:
+      int                     m_val;
+      const error_category *  m_cat;
+
+    };
+
+    //  class error_code  ----------------------------------------------------//
+
+    //  We want error_code to be a value type that can be copied without slicing
+    //  and without requiring heap allocation, but we also want it to have
+    //  polymorphic behavior based on the error category. This is achieved by
+    //  abstract base class error_category supplying the polymorphic behavior,
+    //  and error_code containing a pointer to an object of a type derived
+    //  from error_category.
+    class error_code
+    {
+    public:
+
+      // constructors:
+      error_code() NDNBOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&system_category()) {}
+      error_code( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT : m_val(val), m_cat(&cat) {}
+
+      template <class ErrorCodeEnum>
+        error_code(ErrorCodeEnum e,
+          typename ndnboost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        *this = make_error_code(e);
+      }
+
+      // modifiers:
+      void assign( int val, const error_category & cat ) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        m_val = val;
+        m_cat = &cat;
+      }
+
+      template<typename ErrorCodeEnum>
+        typename ndnboost::enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type &
+          operator=( ErrorCodeEnum val ) NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        *this = make_error_code(val);
+        return *this;
+      }
+
+      void clear() NDNBOOST_SYSTEM_NOEXCEPT
+      {
+        m_val = 0;
+        m_cat = &system_category();
+      }
+
+      // observers:
+      int                     value() const  NDNBOOST_SYSTEM_NOEXCEPT   { return m_val; }
+      const error_category &  category() const NDNBOOST_SYSTEM_NOEXCEPT { return *m_cat; }
+      error_condition         default_error_condition() const NDNBOOST_SYSTEM_NOEXCEPT  { return m_cat->default_error_condition(value()); }
+      std::string             message() const  { return m_cat->message(value()); }
+
+      typedef void (*unspecified_bool_type)();
+      static void unspecified_bool_true() {}
+
+      operator unspecified_bool_type() const  NDNBOOST_SYSTEM_NOEXCEPT // true if error
+      {
+        return m_val == 0 ? 0 : unspecified_bool_true;
+      }
+
+      bool operator!() const  NDNBOOST_SYSTEM_NOEXCEPT // true if no error
+      {
+        return m_val == 0;
+      }
+
+      // relationals:
+      inline friend bool operator==( const error_code & lhs,
+                                     const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+        //  the more symmetrical non-member syntax allows enum
+        //  conversions work for both rhs and lhs.
+      {
+        return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
+      }
+
+      inline friend bool operator<( const error_code & lhs,
+                                    const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+        //  the more symmetrical non-member syntax allows enum
+        //  conversions work for both rhs and lhs.
+      {
+        return lhs.m_cat < rhs.m_cat
+          || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
+      }
+
+    private:
+      int                     m_val;
+      const error_category *  m_cat;
+
+    };
+
+    //  predefined error_code object used as "throw on error" tag
+# ifndef NDNBOOST_SYSTEM_NO_DEPRECATED
+    NDNBOOST_SYSTEM_DECL extern error_code throws;
+# endif
+
+    //  Moving from a "throws" object to a "throws" function without breaking
+    //  existing code is a bit of a problem. The workaround is to place the
+    //  "throws" function in namespace ndnboost rather than namespace ndnboost::system.
+
+  }  // namespace system
+
+  namespace detail { inline system::error_code * throws() { return 0; } }
+    //  Misuse of the error_code object is turned into a noisy failure by
+    //  poisoning the reference. This particular implementation doesn't
+    //  produce warnings or errors from popular compilers, is very efficient
+    //  (as determined by inspecting generated code), and does not suffer
+    //  from order of initialization problems. In practice, it also seems
+    //  cause user function error handling implementation errors to be detected
+    //  very early in the development cycle.
+
+  inline system::error_code & throws()
+    { return *detail::throws(); }
+
+  namespace system
+  {
+    //  non-member functions  ------------------------------------------------//
+
+    inline bool operator!=( const error_code & lhs,
+                            const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return !(lhs == rhs);
+    }
+
+    inline bool operator!=( const error_condition & lhs,
+                            const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return !(lhs == rhs);
+    }
+
+    inline bool operator==( const error_code & code,
+                            const error_condition & condition ) NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return code.category().equivalent( code.value(), condition )
+        || condition.category().equivalent( code, condition.value() );
+    }
+
+    inline bool operator!=( const error_code & lhs,
+                            const error_condition & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return !(lhs == rhs);
+    }
+
+    inline bool operator==( const error_condition & condition,
+                            const error_code & code ) NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return condition.category().equivalent( code, condition.value() )
+        || code.category().equivalent( code.value(), condition );
+    }
+
+    inline bool operator!=( const error_condition & lhs,
+                            const error_code & rhs ) NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return !(lhs == rhs);
+    }
+
+    // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet.
+
+    template <class charT, class traits>
+    inline std::basic_ostream<charT,traits>&
+      operator<< (std::basic_ostream<charT,traits>& os, error_code ec)
+    {
+      os << ec.category().name() << ':' << ec.value();
+      return os;
+    }
+
+    inline std::size_t hash_value( const error_code & ec )
+    {
+      return static_cast<std::size_t>(ec.value())
+        + reinterpret_cast<std::size_t>(&ec.category());
+    }
+
+    //  make_* functions for errc::errc_t  -----------------------------//
+
+    namespace errc
+    {
+      //  explicit conversion:
+      inline error_code make_error_code( errc_t e ) NDNBOOST_SYSTEM_NOEXCEPT
+        { return error_code( e, generic_category() ); }
+
+      //  implicit conversion:
+      inline error_condition make_error_condition( errc_t e ) NDNBOOST_SYSTEM_NOEXCEPT
+        { return error_condition( e, generic_category() ); }
+    }
+
+    //  error_category default implementation  -------------------------------//
+
+    error_condition error_category::default_error_condition( int ev ) const NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return error_condition( ev, *this );
+    }
+
+    bool error_category::equivalent( int code,
+      const error_condition & condition ) const NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return default_error_condition( code ) == condition;
+    }
+
+    bool error_category::equivalent( const error_code & code,
+      int condition ) const NDNBOOST_SYSTEM_NOEXCEPT
+    {
+      return *this == code.category() && code.value() == condition;
+    }
+
+  } // namespace system
+} // namespace ndnboost
+
+#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+
+# ifdef NDNBOOST_ERROR_CODE_HEADER_ONLY
+#   include <ndnboost/../libs/system/src/error_code.cpp>
+# endif
+
+#endif // NDNBOOST_ERROR_CODE_HPP
+
+
diff --git a/include/ndnboost/system/system_error.hpp b/include/ndnboost/system/system_error.hpp
new file mode 100644
index 0000000..ffa732d
--- /dev/null
+++ b/include/ndnboost/system/system_error.hpp
@@ -0,0 +1,84 @@
+//  Boost system_error.hpp  --------------------------------------------------//
+
+//  Copyright Beman Dawes 2006
+
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NDNBOOST_SYSTEM_ERROR_HPP
+#define NDNBOOST_SYSTEM_ERROR_HPP
+
+#include <string>
+#include <stdexcept>
+#include <cassert>
+#include <ndnboost/system/error_code.hpp>
+
+namespace ndnboost
+{
+  namespace system
+  {
+    //  class system_error  ------------------------------------------------------------//
+
+    class NDNBOOST_SYMBOL_VISIBLE system_error : public std::runtime_error
+    // NDNBOOST_SYMBOL_VISIBLE is needed by GCC to ensure system_error thrown from a shared
+    // library can be caught. See svn.boost.org/trac/boost/ticket/3697
+    {
+    public:
+      system_error( error_code ec )
+          : std::runtime_error(""), m_error_code(ec) {}
+
+      system_error( error_code ec, const std::string & what_arg )
+          : std::runtime_error(what_arg), m_error_code(ec) {}
+
+      system_error( error_code ec, const char* what_arg )
+          : std::runtime_error(what_arg), m_error_code(ec) {}
+
+      system_error( int ev, const error_category & ecat )
+          : std::runtime_error(""), m_error_code(ev,ecat) {}
+
+      system_error( int ev, const error_category & ecat,
+        const std::string & what_arg )
+          : std::runtime_error(what_arg), m_error_code(ev,ecat) {}
+
+      system_error( int ev, const error_category & ecat,
+        const char * what_arg )
+          : std::runtime_error(what_arg), m_error_code(ev,ecat) {}
+
+      virtual ~system_error() throw() {}
+
+      const error_code &  code() const throw() { return m_error_code; }
+      const char *        what() const throw();
+
+    private:
+      error_code           m_error_code;
+      mutable std::string  m_what;
+    };
+
+    //  implementation  ------------------------------------------------------//
+
+    inline const char * system_error::what() const throw()
+    // see http://www.boost.org/more/error_handling.html for lazy build rationale
+    {
+      if ( m_what.empty() )
+      {
+#ifndef NDNBOOST_NO_EXCEPTIONS
+        try
+#endif
+        {
+          m_what = this->std::runtime_error::what();
+          if ( !m_what.empty() ) m_what += ": ";
+          m_what += m_error_code.message();
+        }
+#ifndef NDNBOOST_NO_EXCEPTIONS
+        catch (...) { return std::runtime_error::what(); }
+#endif
+      }
+      return m_what.c_str();
+    }
+
+  } // namespace system
+} // namespace ndnboost
+
+#endif // NDNBOOST_SYSTEM_ERROR_HPP
+
+
diff --git a/include/ndnboost/test/unit_test.hpp b/include/ndnboost/test/unit_test.hpp
new file mode 100644
index 0000000..1adb805
--- /dev/null
+++ b/include/ndnboost/test/unit_test.hpp
@@ -0,0 +1,66 @@
+//  (C) Copyright Gennadiy Rozental 2001-2008.
+//  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)
+
+//  See http://www.boost.org/libs/test for the library home page.
+//
+//  File        : $RCSfile$
+//
+//  Version     : $Revision: 49312 $
+//
+//  Description : Entry point for the end user into the Unit Test Framework.
+// ***************************************************************************
+
+#ifndef NDNBOOST_TEST_UNIT_TEST_HPP_071894GER
+#define NDNBOOST_TEST_UNIT_TEST_HPP_071894GER
+
+// Boost.Test
+#include <ndnboost/test/test_tools.hpp>
+#include <ndnboost/test/unit_test_suite.hpp>
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// **************                 Auto Linking                 ************** //
+// ************************************************************************** //
+
+#if !defined(NDNBOOST_ALL_NO_LIB) && !defined(NDNBOOST_TEST_NO_LIB) && \
+    !defined(NDNBOOST_TEST_SOURCE) && !defined(NDNBOOST_TEST_INCLUDED)
+#  define NDNBOOST_LIB_NAME ndnboost_unit_test_framework
+
+#  if defined(NDNBOOST_ALL_DYN_LINK) || defined(NDNBOOST_TEST_DYN_LINK)
+#    define NDNBOOST_DYN_LINK
+#  endif
+
+#  include <ndnboost/config/auto_link.hpp>
+
+#endif  // auto-linking disabled
+
+// ************************************************************************** //
+// **************                  unit_test_main              ************** //
+// ************************************************************************** //
+
+namespace ndnboost { namespace unit_test {
+
+int NDNBOOST_TEST_DECL unit_test_main( init_unit_test_func init_func, int argc, char* argv[] );
+
+}}
+
+#if defined(NDNBOOST_TEST_DYN_LINK) && defined(NDNBOOST_TEST_MAIN) && !defined(NDNBOOST_TEST_NO_MAIN)
+
+// ************************************************************************** //
+// **************        main function for tests using dll     ************** //
+// ************************************************************************** //
+
+int NDNBOOST_TEST_CALL_DECL
+main( int argc, char* argv[] )
+{
+    return ::ndnboost::unit_test::unit_test_main( &init_unit_test, argc, argv );
+}
+
+//____________________________________________________________________________//
+
+#endif // NDNBOOST_TEST_DYN_LINK && NDNBOOST_TEST_MAIN && !NDNBOOST_TEST_NO_MAIN
+
+#endif // NDNBOOST_TEST_UNIT_TEST_HPP_071894GER