In common.h, define func_lib for function objects.  In configure.ac, define HAVE_STD_FUNCTION and HAVE_BOOST_FUNCTION.  Include function headers in ndnboost.
diff --git a/ndnboost/function/detail/function_iterate.hpp b/ndnboost/function/detail/function_iterate.hpp
new file mode 100644
index 0000000..5c41196
--- /dev/null
+++ b/ndnboost/function/detail/function_iterate.hpp
@@ -0,0 +1,16 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2003. 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)
+
+// For more information, see http://www.boost.org
+#if !defined(BOOST_PP_IS_ITERATING)
+# error Boost.Function - do not include this file!
+#endif
+
+#define BOOST_FUNCTION_NUM_ARGS BOOST_PP_ITERATION()
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
+
diff --git a/ndnboost/function/detail/gen_maybe_include.pl b/ndnboost/function/detail/gen_maybe_include.pl
new file mode 100644
index 0000000..ab4367d
--- /dev/null
+++ b/ndnboost/function/detail/gen_maybe_include.pl
@@ -0,0 +1,37 @@
+#!/usr/bin/perl -w
+#
+# Boost.Function library
+#
+# Copyright (C) 2001-2003 Douglas Gregor (gregod@cs.rpi.edu)
+#
+# Permission to copy, use, sell and distribute this software is granted
+# provided this copyright notice appears in all copies.
+# Permission to modify the code and to distribute modified code is granted
+# provided this copyright notice appears in all copies, and a notice
+# that the code was modified is included with the copyright notice.
+#
+# This software is provided "as is" without express or implied warranty,
+# and with no claim as to its suitability for any purpose.
+#
+# For more information, see http://www.boost.org
+use English;
+
+$max_args = $ARGV[0];
+
+open (OUT, ">maybe_include.hpp") or die("Cannot write to maybe_include.hpp");
+for($on_arg = 0; $on_arg <= $max_args; ++$on_arg) {
+    if ($on_arg == 0) {
+	print OUT "#if";
+    }
+    else {
+	print OUT "#elif";
+    }
+    print OUT " BOOST_FUNCTION_NUM_ARGS == $on_arg\n";
+    print OUT "#  ifndef BOOST_FUNCTION_$on_arg\n";
+    print OUT "#    define BOOST_FUNCTION_$on_arg\n";
+    print OUT "#    include <ndnboost/function/function_template.hpp>\n";
+    print OUT "#  endif\n";
+}
+print OUT "#else\n";
+print OUT "#  error Cannot handle Boost.Function objects that accept more than $max_args arguments!\n";
+print OUT "#endif\n";
diff --git a/ndnboost/function/detail/maybe_include.hpp b/ndnboost/function/detail/maybe_include.hpp
new file mode 100644
index 0000000..a2f003e
--- /dev/null
+++ b/ndnboost/function/detail/maybe_include.hpp
@@ -0,0 +1,267 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2003. 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)
+
+// For more information, see http://www.boost.org
+
+#if BOOST_FUNCTION_NUM_ARGS == 0
+#  ifndef BOOST_FUNCTION_0
+#    define BOOST_FUNCTION_0
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 1
+#  ifndef BOOST_FUNCTION_1
+#    define BOOST_FUNCTION_1
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 2
+#  ifndef BOOST_FUNCTION_2
+#    define BOOST_FUNCTION_2
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 3
+#  ifndef BOOST_FUNCTION_3
+#    define BOOST_FUNCTION_3
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 4
+#  ifndef BOOST_FUNCTION_4
+#    define BOOST_FUNCTION_4
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 5
+#  ifndef BOOST_FUNCTION_5
+#    define BOOST_FUNCTION_5
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 6
+#  ifndef BOOST_FUNCTION_6
+#    define BOOST_FUNCTION_6
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 7
+#  ifndef BOOST_FUNCTION_7
+#    define BOOST_FUNCTION_7
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 8
+#  ifndef BOOST_FUNCTION_8
+#    define BOOST_FUNCTION_8
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 9
+#  ifndef BOOST_FUNCTION_9
+#    define BOOST_FUNCTION_9
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 10
+#  ifndef BOOST_FUNCTION_10
+#    define BOOST_FUNCTION_10
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 11
+#  ifndef BOOST_FUNCTION_11
+#    define BOOST_FUNCTION_11
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 12
+#  ifndef BOOST_FUNCTION_12
+#    define BOOST_FUNCTION_12
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 13
+#  ifndef BOOST_FUNCTION_13
+#    define BOOST_FUNCTION_13
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 14
+#  ifndef BOOST_FUNCTION_14
+#    define BOOST_FUNCTION_14
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 15
+#  ifndef BOOST_FUNCTION_15
+#    define BOOST_FUNCTION_15
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 16
+#  ifndef BOOST_FUNCTION_16
+#    define BOOST_FUNCTION_16
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 17
+#  ifndef BOOST_FUNCTION_17
+#    define BOOST_FUNCTION_17
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 18
+#  ifndef BOOST_FUNCTION_18
+#    define BOOST_FUNCTION_18
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 19
+#  ifndef BOOST_FUNCTION_19
+#    define BOOST_FUNCTION_19
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 20
+#  ifndef BOOST_FUNCTION_20
+#    define BOOST_FUNCTION_20
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 21
+#  ifndef BOOST_FUNCTION_21
+#    define BOOST_FUNCTION_21
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 22
+#  ifndef BOOST_FUNCTION_22
+#    define BOOST_FUNCTION_22
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 23
+#  ifndef BOOST_FUNCTION_23
+#    define BOOST_FUNCTION_23
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 24
+#  ifndef BOOST_FUNCTION_24
+#    define BOOST_FUNCTION_24
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 25
+#  ifndef BOOST_FUNCTION_25
+#    define BOOST_FUNCTION_25
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 26
+#  ifndef BOOST_FUNCTION_26
+#    define BOOST_FUNCTION_26
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 27
+#  ifndef BOOST_FUNCTION_27
+#    define BOOST_FUNCTION_27
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 28
+#  ifndef BOOST_FUNCTION_28
+#    define BOOST_FUNCTION_28
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 29
+#  ifndef BOOST_FUNCTION_29
+#    define BOOST_FUNCTION_29
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 30
+#  ifndef BOOST_FUNCTION_30
+#    define BOOST_FUNCTION_30
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 31
+#  ifndef BOOST_FUNCTION_31
+#    define BOOST_FUNCTION_31
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 32
+#  ifndef BOOST_FUNCTION_32
+#    define BOOST_FUNCTION_32
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 33
+#  ifndef BOOST_FUNCTION_33
+#    define BOOST_FUNCTION_33
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 34
+#  ifndef BOOST_FUNCTION_34
+#    define BOOST_FUNCTION_34
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 35
+#  ifndef BOOST_FUNCTION_35
+#    define BOOST_FUNCTION_35
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 36
+#  ifndef BOOST_FUNCTION_36
+#    define BOOST_FUNCTION_36
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 37
+#  ifndef BOOST_FUNCTION_37
+#    define BOOST_FUNCTION_37
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 38
+#  ifndef BOOST_FUNCTION_38
+#    define BOOST_FUNCTION_38
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 39
+#  ifndef BOOST_FUNCTION_39
+#    define BOOST_FUNCTION_39
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 40
+#  ifndef BOOST_FUNCTION_40
+#    define BOOST_FUNCTION_40
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 41
+#  ifndef BOOST_FUNCTION_41
+#    define BOOST_FUNCTION_41
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 42
+#  ifndef BOOST_FUNCTION_42
+#    define BOOST_FUNCTION_42
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 43
+#  ifndef BOOST_FUNCTION_43
+#    define BOOST_FUNCTION_43
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 44
+#  ifndef BOOST_FUNCTION_44
+#    define BOOST_FUNCTION_44
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 45
+#  ifndef BOOST_FUNCTION_45
+#    define BOOST_FUNCTION_45
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 46
+#  ifndef BOOST_FUNCTION_46
+#    define BOOST_FUNCTION_46
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 47
+#  ifndef BOOST_FUNCTION_47
+#    define BOOST_FUNCTION_47
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 48
+#  ifndef BOOST_FUNCTION_48
+#    define BOOST_FUNCTION_48
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 49
+#  ifndef BOOST_FUNCTION_49
+#    define BOOST_FUNCTION_49
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 50
+#  ifndef BOOST_FUNCTION_50
+#    define BOOST_FUNCTION_50
+#    include <ndnboost/function/function_template.hpp>
+#  endif
+#else
+#  error Cannot handle Boost.Function objects that accept more than 50 arguments!
+#endif
diff --git a/ndnboost/function/detail/prologue.hpp b/ndnboost/function/detail/prologue.hpp
new file mode 100644
index 0000000..458324c
--- /dev/null
+++ b/ndnboost/function/detail/prologue.hpp
@@ -0,0 +1,26 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_FUNCTION_PROLOGUE_HPP
+#define BOOST_FUNCTION_PROLOGUE_HPP
+#  include <cassert>
+#  include <algorithm>
+#  include <ndnboost/config/no_tr1/functional.hpp> // unary_function, binary_function
+#  include <ndnboost/throw_exception.hpp>
+#  include <ndnboost/config.hpp>
+#  include <ndnboost/function/function_base.hpp>
+#  include <ndnboost/mem_fn.hpp>
+#  include <ndnboost/type_traits/is_integral.hpp>
+#  include <ndnboost/preprocessor/enum.hpp>
+#  include <ndnboost/preprocessor/enum_params.hpp>
+#  include <ndnboost/preprocessor/cat.hpp>
+#  include <ndnboost/preprocessor/repeat.hpp>
+#  include <ndnboost/preprocessor/inc.hpp>
+#  include <ndnboost/type_traits/is_void.hpp>
+#endif // BOOST_FUNCTION_PROLOGUE_HPP
diff --git a/ndnboost/function/function0.hpp b/ndnboost/function/function0.hpp
new file mode 100644
index 0000000..79211dc
--- /dev/null
+++ b/ndnboost/function/function0.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 0
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function1.hpp b/ndnboost/function/function1.hpp
new file mode 100644
index 0000000..83fbc19
--- /dev/null
+++ b/ndnboost/function/function1.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 1
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function10.hpp b/ndnboost/function/function10.hpp
new file mode 100644
index 0000000..bbd3dec
--- /dev/null
+++ b/ndnboost/function/function10.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 10
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function2.hpp b/ndnboost/function/function2.hpp
new file mode 100644
index 0000000..65dbfda
--- /dev/null
+++ b/ndnboost/function/function2.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 2
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function3.hpp b/ndnboost/function/function3.hpp
new file mode 100644
index 0000000..3244755
--- /dev/null
+++ b/ndnboost/function/function3.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 3
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function4.hpp b/ndnboost/function/function4.hpp
new file mode 100644
index 0000000..467b03b
--- /dev/null
+++ b/ndnboost/function/function4.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 4
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function5.hpp b/ndnboost/function/function5.hpp
new file mode 100644
index 0000000..77cf420
--- /dev/null
+++ b/ndnboost/function/function5.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 5
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function6.hpp b/ndnboost/function/function6.hpp
new file mode 100644
index 0000000..eae829d
--- /dev/null
+++ b/ndnboost/function/function6.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 6
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function7.hpp b/ndnboost/function/function7.hpp
new file mode 100644
index 0000000..0c7a5aa
--- /dev/null
+++ b/ndnboost/function/function7.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 7
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function8.hpp b/ndnboost/function/function8.hpp
new file mode 100644
index 0000000..c9cc28b
--- /dev/null
+++ b/ndnboost/function/function8.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 8
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function9.hpp b/ndnboost/function/function9.hpp
new file mode 100644
index 0000000..33c8836
--- /dev/null
+++ b/ndnboost/function/function9.hpp
@@ -0,0 +1,12 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. 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)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_FUNCTION_NUM_ARGS 9
+#include <ndnboost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/ndnboost/function/function_base.hpp b/ndnboost/function/function_base.hpp
new file mode 100644
index 0000000..30af1a3
--- /dev/null
+++ b/ndnboost/function/function_base.hpp
@@ -0,0 +1,910 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-2006
+//  Copyright Emil Dotchevski 2007
+//  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)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_FUNCTION_BASE_HEADER
+#define BOOST_FUNCTION_BASE_HEADER
+
+#include <stdexcept>
+#include <string>
+#include <memory>
+#include <new>
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <ndnboost/assert.hpp>
+#include <ndnboost/integer.hpp>
+#include <ndnboost/type_traits/has_trivial_copy.hpp>
+#include <ndnboost/type_traits/has_trivial_destructor.hpp>
+#include <ndnboost/type_traits/is_const.hpp>
+#include <ndnboost/type_traits/is_integral.hpp>
+#include <ndnboost/type_traits/is_volatile.hpp>
+#include <ndnboost/type_traits/composite_traits.hpp>
+#include <ndnboost/type_traits/ice.hpp>
+#include <ndnboost/ref.hpp>
+#include <ndnboost/mpl/if.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/type_traits/alignment_of.hpp>
+#ifndef BOOST_NO_SFINAE
+#  include "ndnboost/utility/enable_if.hpp"
+#else
+#  include "ndnboost/mpl/bool.hpp"
+#endif
+#include <ndnboost/function_equal.hpp>
+#include <ndnboost/function/function_fwd.hpp>
+
+#if defined(BOOST_MSVC)
+#   pragma warning( push )
+#   pragma warning( disable : 4793 ) // complaint about native code generation
+#   pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif       
+
+// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
+#ifdef BOOST_NO_STD_TYPEINFO
+// Embedded VC++ does not have type_info in namespace std
+#  define BOOST_FUNCTION_STD_NS
+#else
+#  define BOOST_FUNCTION_STD_NS std
+#endif
+
+// Borrowed from Boost.Python library: determines the cases where we
+// need to use std::type_info::name to compare instead of operator==.
+#if defined( BOOST_NO_TYPEID )
+#  define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
+#elif (defined(__GNUC__) && __GNUC__ >= 3) \
+ || defined(_AIX) \
+ || (   defined(__sgi) && defined(__host_mips))
+#  include <cstring>
+#  define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \
+     (std::strcmp((X).name(),(Y).name()) == 0)
+# else
+#  define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
+#endif
+
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
+#  define BOOST_FUNCTION_TARGET_FIX(x) x
+#else
+#  define BOOST_FUNCTION_TARGET_FIX(x)
+#endif // not MSVC
+
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x5A0)
+#  define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type)              \
+      typename ::ndnboost::enable_if_c<(::ndnboost::type_traits::ice_not<          \
+                            (::ndnboost::is_integral<Functor>::value)>::value), \
+                           Type>::type
+#else
+// BCC doesn't recognize this depends on a template argument and complains
+// about the use of 'typename'
+#  define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type)     \
+      ::ndnboost::enable_if_c<(::ndnboost::type_traits::ice_not<          \
+                   (::ndnboost::is_integral<Functor>::value)>::value), \
+                       Type>::type
+#endif
+
+namespace ndnboost {
+  namespace detail {
+    namespace function {
+      class X;
+
+      /**
+       * A buffer used to store small function objects in
+       * ndnboost::function. It is a union containing function pointers,
+       * object pointers, and a structure that resembles a bound
+       * member function pointer.
+       */
+      union function_buffer
+      {
+        // For pointers to function objects
+        mutable void* obj_ptr;
+
+        // For pointers to std::type_info objects
+        struct type_t {
+          // (get_functor_type_tag, check_functor_type_tag).
+          const detail::sp_typeinfo* type;
+
+          // Whether the type is const-qualified.
+          bool const_qualified;
+          // Whether the type is volatile-qualified.
+          bool volatile_qualified;
+        } type;
+
+        // For function pointers of all kinds
+        mutable void (*func_ptr)();
+
+        // For bound member pointers
+        struct bound_memfunc_ptr_t {
+          void (X::*memfunc_ptr)(int);
+          void* obj_ptr;
+        } bound_memfunc_ptr;
+
+        // For references to function objects. We explicitly keep
+        // track of the cv-qualifiers on the object referenced.
+        struct obj_ref_t {
+          mutable void* obj_ptr;
+          bool is_const_qualified;
+          bool is_volatile_qualified;
+        } obj_ref;
+
+        // To relax aliasing constraints
+        mutable char data;
+      };
+
+      /**
+       * The unusable class is a placeholder for unused function arguments
+       * It is also completely unusable except that it constructable from
+       * anything. This helps compilers without partial specialization to
+       * handle Boost.Function objects returning void.
+       */
+      struct unusable
+      {
+        unusable() {}
+        template<typename T> unusable(const T&) {}
+      };
+
+      /* Determine the return type. This supports compilers that do not support
+       * void returns or partial specialization by silently changing the return
+       * type to "unusable".
+       */
+      template<typename T> struct function_return_type { typedef T type; };
+
+      template<>
+      struct function_return_type<void>
+      {
+        typedef unusable type;
+      };
+
+      // The operation type to perform on the given functor/function pointer
+      enum functor_manager_operation_type {
+        clone_functor_tag,
+        move_functor_tag,
+        destroy_functor_tag,
+        check_functor_type_tag,
+        get_functor_type_tag
+      };
+
+      // Tags used to decide between different types of functions
+      struct function_ptr_tag {};
+      struct function_obj_tag {};
+      struct member_ptr_tag {};
+      struct function_obj_ref_tag {};
+
+      template<typename F>
+      class get_function_tag
+      {
+        typedef typename mpl::if_c<(is_pointer<F>::value),
+                                   function_ptr_tag,
+                                   function_obj_tag>::type ptr_or_obj_tag;
+
+        typedef typename mpl::if_c<(is_member_pointer<F>::value),
+                                   member_ptr_tag,
+                                   ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
+
+        typedef typename mpl::if_c<(is_reference_wrapper<F>::value),
+                                   function_obj_ref_tag,
+                                   ptr_or_obj_or_mem_tag>::type or_ref_tag;
+
+      public:
+        typedef or_ref_tag type;
+      };
+
+      // The trivial manager does nothing but return the same pointer (if we
+      // are cloning) or return the null pointer (if we are deleting).
+      template<typename F>
+      struct reference_manager
+      {
+        static inline void
+        manage(const function_buffer& in_buffer, function_buffer& out_buffer, 
+               functor_manager_operation_type op)
+        {
+          switch (op) {
+          case clone_functor_tag: 
+            out_buffer.obj_ref = in_buffer.obj_ref;
+            return;
+
+          case move_functor_tag:
+            out_buffer.obj_ref = in_buffer.obj_ref;
+            in_buffer.obj_ref.obj_ptr = 0;
+            return;
+
+          case destroy_functor_tag:
+            out_buffer.obj_ref.obj_ptr = 0;
+            return;
+
+          case check_functor_type_tag:
+            {
+              const detail::sp_typeinfo& check_type 
+                = *out_buffer.type.type;
+
+              // Check whether we have the same type. We can add
+              // cv-qualifiers, but we can't take them away.
+              if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F))
+                  && (!in_buffer.obj_ref.is_const_qualified 
+                      || out_buffer.type.const_qualified)
+                  && (!in_buffer.obj_ref.is_volatile_qualified
+                      || out_buffer.type.volatile_qualified))
+                out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr;
+              else
+                out_buffer.obj_ptr = 0;
+            }
+            return;
+
+          case get_functor_type_tag:
+            out_buffer.type.type = &BOOST_SP_TYPEID(F);
+            out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
+            out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
+            return;
+          }
+        }
+      };
+
+      /**
+       * Determine if ndnboost::function can use the small-object
+       * optimization with the function object type F.
+       */
+      template<typename F>
+      struct function_allows_small_object_optimization
+      {
+        BOOST_STATIC_CONSTANT
+          (bool, 
+           value = ((sizeof(F) <= sizeof(function_buffer) &&
+                     (alignment_of<function_buffer>::value 
+                      % alignment_of<F>::value == 0))));
+      };
+
+      template <typename F,typename A>
+      struct functor_wrapper: public F, public A
+      {
+        functor_wrapper( F f, A a ):
+          F(f),
+          A(a)
+        {
+        }
+        
+        functor_wrapper(const functor_wrapper& f) :
+          F(static_cast<const F&>(f)),
+          A(static_cast<const A&>(f))
+        {
+        }
+      };
+
+      /**
+       * The functor_manager class contains a static function "manage" which
+       * can clone or destroy the given function/function object pointer.
+       */
+      template<typename Functor>
+      struct functor_manager_common
+      {
+        typedef Functor functor_type;
+
+        // Function pointers
+        static inline void
+        manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op)
+        {
+          if (op == clone_functor_tag)
+            out_buffer.func_ptr = in_buffer.func_ptr;
+          else if (op == move_functor_tag) {
+            out_buffer.func_ptr = in_buffer.func_ptr;
+            in_buffer.func_ptr = 0;
+          } else if (op == destroy_functor_tag)
+            out_buffer.func_ptr = 0;
+          else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type 
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = &in_buffer.func_ptr;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+
+        // Function objects that fit in the small-object buffer.
+        static inline void
+        manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op)
+        {
+          if (op == clone_functor_tag || op == move_functor_tag) {
+            const functor_type* in_functor = 
+              reinterpret_cast<const functor_type*>(&in_buffer.data);
+            new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor);
+
+            if (op == move_functor_tag) {
+              functor_type* f = reinterpret_cast<functor_type*>(&in_buffer.data);
+              (void)f; // suppress warning about the value of f not being used (MSVC)
+              f->~Functor();
+            }
+          } else if (op == destroy_functor_tag) {
+            // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
+             functor_type* f = reinterpret_cast<functor_type*>(&out_buffer.data);
+             (void)f; // suppress warning about the value of f not being used (MSVC)
+             f->~Functor();
+          } else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type 
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = &in_buffer.data;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;            
+          }
+        }
+      };
+
+      template<typename Functor>
+      struct functor_manager
+      {
+      private:
+        typedef Functor functor_type;
+
+        // Function pointers
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, function_ptr_tag)
+        {
+          functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
+        }
+
+        // Function objects that fit in the small-object buffer.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, mpl::true_)
+        {
+          functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
+        }
+        
+        // Function objects that require heap allocation
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, mpl::false_)
+        {
+          if (op == clone_functor_tag) {
+            // Clone the functor
+            // GCC 2.95.3 gets the CV qualifiers wrong here, so we
+            // can't do the static_cast that we should do.
+            // jewillco: Changing this to static_cast because GCC 2.95.3 is
+            // obsolete.
+            const functor_type* f =
+              static_cast<const functor_type*>(in_buffer.obj_ptr);
+            functor_type* new_f = new functor_type(*f);
+            out_buffer.obj_ptr = new_f;
+          } else if (op == move_functor_tag) {
+            out_buffer.obj_ptr = in_buffer.obj_ptr;
+            in_buffer.obj_ptr = 0;
+          } else if (op == destroy_functor_tag) {
+            /* Cast from the void pointer to the functor pointer type */
+            functor_type* f =
+              static_cast<functor_type*>(out_buffer.obj_ptr);
+            delete f;
+            out_buffer.obj_ptr = 0;
+          } else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = in_buffer.obj_ptr;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+
+        // For function objects, we determine whether the function
+        // object can use the small-object optimization buffer or
+        // whether we need to allocate it on the heap.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, function_obj_tag)
+        {
+          manager(in_buffer, out_buffer, op,
+                  mpl::bool_<(function_allows_small_object_optimization<functor_type>::value)>());
+        }
+
+        // For member pointers, we use the small-object optimization buffer.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, member_ptr_tag)
+        {
+          manager(in_buffer, out_buffer, op, mpl::true_());
+        }
+
+      public:
+        /* Dispatch to an appropriate manager based on whether we have a
+           function pointer or a function object pointer. */
+        static inline void
+        manage(const function_buffer& in_buffer, function_buffer& out_buffer, 
+               functor_manager_operation_type op)
+        {
+          typedef typename get_function_tag<functor_type>::type tag_type;
+          switch (op) {
+          case get_functor_type_tag:
+            out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+            return;
+
+          default:
+            manager(in_buffer, out_buffer, op, tag_type());
+            return;
+          }
+        }
+      };
+
+      template<typename Functor, typename Allocator>
+      struct functor_manager_a
+      {
+      private:
+        typedef Functor functor_type;
+
+        // Function pointers
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, function_ptr_tag)
+        {
+          functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
+        }
+
+        // Function objects that fit in the small-object buffer.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, mpl::true_)
+        {
+          functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
+        }
+        
+        // Function objects that require heap allocation
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, mpl::false_)
+        {
+          typedef functor_wrapper<Functor,Allocator> functor_wrapper_type;
+          typedef typename Allocator::template rebind<functor_wrapper_type>::other
+            wrapper_allocator_type;
+          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
+
+          if (op == clone_functor_tag) {
+            // Clone the functor
+            // GCC 2.95.3 gets the CV qualifiers wrong here, so we
+            // can't do the static_cast that we should do.
+            const functor_wrapper_type* f =
+              static_cast<const functor_wrapper_type*>(in_buffer.obj_ptr);
+            wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f));
+            wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
+            wrapper_allocator.construct(copy, *f);
+
+            // Get back to the original pointer type
+            functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
+            out_buffer.obj_ptr = new_f;
+          } else if (op == move_functor_tag) {
+            out_buffer.obj_ptr = in_buffer.obj_ptr;
+            in_buffer.obj_ptr = 0;
+          } else if (op == destroy_functor_tag) {
+            /* Cast from the void pointer to the functor_wrapper_type */
+            functor_wrapper_type* victim =
+              static_cast<functor_wrapper_type*>(in_buffer.obj_ptr);
+            wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*victim));
+            wrapper_allocator.destroy(victim);
+            wrapper_allocator.deallocate(victim,1);
+            out_buffer.obj_ptr = 0;
+          } else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type 
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = in_buffer.obj_ptr;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+
+        // For function objects, we determine whether the function
+        // object can use the small-object optimization buffer or
+        // whether we need to allocate it on the heap.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer, 
+                functor_manager_operation_type op, function_obj_tag)
+        {
+          manager(in_buffer, out_buffer, op,
+                  mpl::bool_<(function_allows_small_object_optimization<functor_type>::value)>());
+        }
+
+      public:
+        /* Dispatch to an appropriate manager based on whether we have a
+           function pointer or a function object pointer. */
+        static inline void
+        manage(const function_buffer& in_buffer, function_buffer& out_buffer, 
+               functor_manager_operation_type op)
+        {
+          typedef typename get_function_tag<functor_type>::type tag_type;
+          switch (op) {
+          case get_functor_type_tag:
+            out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+            return;
+
+          default:
+            manager(in_buffer, out_buffer, op, tag_type());
+            return;
+          }
+        }
+      };
+
+      // A type that is only used for comparisons against zero
+      struct useless_clear_type {};
+
+#ifdef BOOST_NO_SFINAE
+      // These routines perform comparisons between a Boost.Function
+      // object and an arbitrary function object (when the last
+      // parameter is mpl::bool_<false>) or against zero (when the
+      // last parameter is mpl::bool_<true>). They are only necessary
+      // for compilers that don't support SFINAE.
+      template<typename Function, typename Functor>
+        bool
+        compare_equal(const Function& f, const Functor&, int, mpl::bool_<true>)
+        { return f.empty(); }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_not_equal(const Function& f, const Functor&, int,
+                          mpl::bool_<true>)
+        { return !f.empty(); }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_equal(const Function& f, const Functor& g, long,
+                      mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return function_equal(*fp, g);
+          else return false;
+        }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_equal(const Function& f, const reference_wrapper<Functor>& g,
+                      int, mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return fp == g.get_pointer();
+          else return false;
+        }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_not_equal(const Function& f, const Functor& g, long,
+                          mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return !function_equal(*fp, g);
+          else return true;
+        }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_not_equal(const Function& f,
+                          const reference_wrapper<Functor>& g, int,
+                          mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return fp != g.get_pointer();
+          else return true;
+        }
+#endif // BOOST_NO_SFINAE
+
+      /**
+       * Stores the "manager" portion of the vtable for a
+       * ndnboost::function object.
+       */
+      struct vtable_base
+      {
+        void (*manager)(const function_buffer& in_buffer, 
+                        function_buffer& out_buffer, 
+                        functor_manager_operation_type op);
+      };
+    } // end namespace function
+  } // end namespace detail
+
+/**
+ * The function_base class contains the basic elements needed for the
+ * function1, function2, function3, etc. classes. It is common to all
+ * functions (and as such can be used to tell if we have one of the
+ * functionN objects).
+ */
+class function_base
+{
+public:
+  function_base() : vtable(0) { }
+
+  /** Determine if the function is empty (i.e., has no target). */
+  bool empty() const { return !vtable; }
+
+  /** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void)
+      if this is empty. */
+  const detail::sp_typeinfo& target_type() const
+  {
+    if (!vtable) return BOOST_SP_TYPEID(void);
+
+    detail::function::function_buffer type;
+    get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
+    return *type.type.type;
+  }
+
+  template<typename Functor>
+    Functor* target()
+    {
+      if (!vtable) return 0;
+
+      detail::function::function_buffer type_result;
+      type_result.type.type = &BOOST_SP_TYPEID(Functor);
+      type_result.type.const_qualified = is_const<Functor>::value;
+      type_result.type.volatile_qualified = is_volatile<Functor>::value;
+      get_vtable()->manager(functor, type_result, 
+                      detail::function::check_functor_type_tag);
+      return static_cast<Functor*>(type_result.obj_ptr);
+    }
+
+  template<typename Functor>
+#if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    const Functor* target( Functor * = 0 ) const
+#else
+    const Functor* target() const
+#endif
+    {
+      if (!vtable) return 0;
+
+      detail::function::function_buffer type_result;
+      type_result.type.type = &BOOST_SP_TYPEID(Functor);
+      type_result.type.const_qualified = true;
+      type_result.type.volatile_qualified = is_volatile<Functor>::value;
+      get_vtable()->manager(functor, type_result, 
+                      detail::function::check_functor_type_tag);
+      // GCC 2.95.3 gets the CV qualifiers wrong here, so we
+      // can't do the static_cast that we should do.
+      return static_cast<const Functor*>(type_result.obj_ptr);
+    }
+
+  template<typename F>
+    bool contains(const F& f) const
+    {
+#if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+      if (const F* fp = this->target( (F*)0 ))
+#else
+      if (const F* fp = this->template target<F>())
+#endif
+      {
+        return function_equal(*fp, f);
+      } else {
+        return false;
+      }
+    }
+
+#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3
+  // GCC 3.3 and newer cannot copy with the global operator==, due to
+  // problems with instantiation of function return types before it
+  // has been verified that the argument types match up.
+  template<typename Functor>
+    BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+    operator==(Functor g) const
+    {
+      if (const Functor* fp = target<Functor>())
+        return function_equal(*fp, g);
+      else return false;
+    }
+
+  template<typename Functor>
+    BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+    operator!=(Functor g) const
+    {
+      if (const Functor* fp = target<Functor>())
+        return !function_equal(*fp, g);
+      else return true;
+    }
+#endif
+
+public: // should be protected, but GCC 2.95.3 will fail to allow access
+  detail::function::vtable_base* get_vtable() const {
+    return reinterpret_cast<detail::function::vtable_base*>(
+             reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
+  }
+
+  bool has_trivial_copy_and_destroy() const {
+    return reinterpret_cast<std::size_t>(vtable) & 0x01;
+  }
+
+  detail::function::vtable_base* vtable;
+  mutable detail::function::function_buffer functor;
+};
+
+/**
+ * The bad_function_call exception class is thrown when a ndnboost::function
+ * object is invoked
+ */
+class bad_function_call : public std::runtime_error
+{
+public:
+  bad_function_call() : std::runtime_error("call to empty ndnboost::function") {}
+};
+
+#ifndef BOOST_NO_SFINAE
+inline bool operator==(const function_base& f,
+                       detail::function::useless_clear_type*)
+{
+  return f.empty();
+}
+
+inline bool operator!=(const function_base& f,
+                       detail::function::useless_clear_type*)
+{
+  return !f.empty();
+}
+
+inline bool operator==(detail::function::useless_clear_type*,
+                       const function_base& f)
+{
+  return f.empty();
+}
+
+inline bool operator!=(detail::function::useless_clear_type*,
+                       const function_base& f)
+{
+  return !f.empty();
+}
+#endif
+
+#ifdef BOOST_NO_SFINAE
+// Comparisons between ndnboost::function objects and arbitrary function objects
+template<typename Functor>
+  inline bool operator==(const function_base& f, Functor g)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_equal(f, g, 0, integral());
+  }
+
+template<typename Functor>
+  inline bool operator==(Functor g, const function_base& f)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_equal(f, g, 0, integral());
+  }
+
+template<typename Functor>
+  inline bool operator!=(const function_base& f, Functor g)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_not_equal(f, g, 0, integral());
+  }
+
+template<typename Functor>
+  inline bool operator!=(Functor g, const function_base& f)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_not_equal(f, g, 0, integral());
+  }
+#else
+
+#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+// Comparisons between ndnboost::function objects and arbitrary function
+// objects. GCC 3.3 and before has an obnoxious bug that prevents this
+// from working.
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(const function_base& f, Functor g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return function_equal(*fp, g);
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(Functor g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return function_equal(g, *fp);
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(const function_base& f, Functor g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return !function_equal(*fp, g);
+    else return true;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(Functor g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return !function_equal(g, *fp);
+    else return true;
+  }
+#  endif
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(const function_base& f, reference_wrapper<Functor> g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return fp == g.get_pointer();
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(reference_wrapper<Functor> g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return g.get_pointer() == fp;
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(const function_base& f, reference_wrapper<Functor> g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return fp != g.get_pointer();
+    else return true;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(reference_wrapper<Functor> g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return g.get_pointer() != fp;
+    else return true;
+  }
+
+#endif // Compiler supporting SFINAE
+
+namespace detail {
+  namespace function {
+    inline bool has_empty_target(const function_base* f)
+    {
+      return f->empty();
+    }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+    inline bool has_empty_target(const void*)
+    {
+      return false;
+    }
+#else
+    inline bool has_empty_target(...)
+    {
+      return false;
+    }
+#endif
+  } // end namespace function
+} // end namespace detail
+} // end namespace ndnboost
+
+#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
+#undef BOOST_FUNCTION_COMPARE_TYPE_ID
+
+#if defined(BOOST_MSVC)
+#   pragma warning( pop )
+#endif       
+
+#endif // BOOST_FUNCTION_BASE_HEADER
diff --git a/ndnboost/function/function_fwd.hpp b/ndnboost/function/function_fwd.hpp
new file mode 100644
index 0000000..11df6eb
--- /dev/null
+++ b/ndnboost/function/function_fwd.hpp
@@ -0,0 +1,70 @@
+// Boost.Function library
+//  Copyright (C) Douglas Gregor 2008
+//
+//  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)
+//
+// For more information, see http://www.boost.org
+#ifndef BOOST_FUNCTION_FWD_HPP
+#define BOOST_FUNCTION_FWD_HPP
+#include <ndnboost/config.hpp>
+
+#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
+// Work around a compiler bug.
+// ndnboost::python::objects::function has to be seen by the compiler before the
+// ndnboost::function class template.
+namespace ndnboost { namespace python { namespace objects {
+  class function;
+}}}
+#endif
+
+#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)                    \
+ || defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG)                         \
+ || !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
+#  define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
+#endif
+
+namespace ndnboost {
+  class bad_function_call;
+
+#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
+  // Preferred syntax
+  template<typename Signature> class function;
+
+  template<typename Signature>
+  inline void swap(function<Signature>& f1, function<Signature>& f2)
+  {
+    f1.swap(f2);
+  }
+#endif // have partial specialization
+
+  // Portable syntax
+  template<typename R> class function0;
+  template<typename R, typename T1> class function1;
+  template<typename R, typename T1, typename T2> class function2;
+  template<typename R, typename T1, typename T2, typename T3> class function3;
+  template<typename R, typename T1, typename T2, typename T3, typename T4> 
+    class function4;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5> 
+    class function5;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6> 
+    class function6;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7> 
+    class function7;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7, typename T8> 
+    class function8;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7, typename T8, typename T9> 
+    class function9;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7, typename T8, typename T9,
+           typename T10> 
+    class function10;
+}
+
+#endif
diff --git a/ndnboost/function/function_template.hpp b/ndnboost/function/function_template.hpp
new file mode 100644
index 0000000..6256b73
--- /dev/null
+++ b/ndnboost/function/function_template.hpp
@@ -0,0 +1,1185 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-2006
+//  Copyright Emil Dotchevski 2007
+//  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)
+
+// For more information, see http://www.boost.org
+
+// Note: this header is a header template and must NOT have multiple-inclusion
+// protection.
+#include <ndnboost/function/detail/prologue.hpp>
+#include <ndnboost/detail/no_exceptions_support.hpp>
+
+#if defined(BOOST_MSVC)
+#   pragma warning( push )
+#   pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif       
+
+#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
+
+#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
+
+#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
+
+#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
+
+#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
+
+#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
+  typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
+
+#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
+
+// Comma if nonzero number of arguments
+#if BOOST_FUNCTION_NUM_ARGS == 0
+#  define BOOST_FUNCTION_COMMA
+#else
+#  define BOOST_FUNCTION_COMMA ,
+#endif // BOOST_FUNCTION_NUM_ARGS > 0
+
+// Class names used in this version of the code
+#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_FUNCTION_INVOKER \
+  BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
+  BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
+  BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
+  BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
+  BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
+  BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_MEMBER_INVOKER \
+  BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
+  BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
+  BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
+  BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
+  BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_MEMBER_INVOKER \
+  BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_INVOKER \
+  BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
+
+#ifndef BOOST_NO_VOID_RETURNS
+#  define BOOST_FUNCTION_VOID_RETURN_TYPE void
+#  define BOOST_FUNCTION_RETURN(X) X
+#else
+#  define BOOST_FUNCTION_VOID_RETURN_TYPE ndnboost::detail::function::unusable
+#  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
+#endif
+
+namespace ndnboost {
+  namespace detail {
+    namespace function {
+      template<
+        typename FunctionPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+        >
+      struct BOOST_FUNCTION_FUNCTION_INVOKER
+      {
+        static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+        {
+          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
+          return f(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename FunctionPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+        >
+      struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
+          BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
+      {
+        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f;
+          if (function_allows_small_object_optimization<FunctionObj>::value)
+            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
+          else
+            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          return (*f)(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f;
+          if (function_allows_small_object_optimization<FunctionObj>::value)
+            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
+          else
+            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
+      {
+        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f = 
+            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          return (*f)(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f = 
+            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
+        }
+      };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+      /* Handle invocation of member pointers. */
+      template<
+        typename MemberPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_MEMBER_INVOKER
+      {
+        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+
+        {
+          MemberPtr* f = 
+            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
+          return ndnboost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename MemberPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          MemberPtr* f = 
+            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
+          BOOST_FUNCTION_RETURN(ndnboost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
+        }
+      };
+#endif
+
+      template<
+        typename FunctionPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
+                            FunctionPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_FUNCTION_INVOKER<
+                            FunctionPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+       >
+      struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+       >
+      struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_FUNCTION_REF_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+      /* Retrieve the appropriate invoker for a member pointer.  */
+      template<
+        typename MemberPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+       >
+      struct BOOST_FUNCTION_GET_MEMBER_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_MEMBER_INVOKER<
+                            MemberPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_MEMBER_INVOKER<
+                            MemberPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+#endif
+
+      /* Given the tag returned by get_function_tag, retrieve the
+         actual invoker that will be used for the given function
+         object. 
+
+         Each specialization contains an "apply" nested class template
+         that accepts the function object, return type, function
+         argument types, and allocator. The resulting "apply" class
+         contains two typedefs, "invoker_type" and "manager_type",
+         which correspond to the invoker and manager types. */
+      template<typename Tag>
+      struct BOOST_FUNCTION_GET_INVOKER { };
+
+      /* Retrieve the invoker for a function pointer. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
+      {
+        template<typename FunctionPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
+                             FunctionPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<FunctionPtr> manager_type;
+        };
+
+        template<typename FunctionPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
+                             FunctionPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<FunctionPtr> manager_type;
+        };
+      };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+      /* Retrieve the invoker for a member pointer. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
+      {
+        template<typename MemberPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
+                             MemberPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<MemberPtr> manager_type;
+        };
+
+        template<typename MemberPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
+                             MemberPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<MemberPtr> manager_type;
+        };
+      };
+#endif
+
+      /* Retrieve the invoker for a function object. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
+      {
+        template<typename FunctionObj,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
+                             FunctionObj,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<FunctionObj> manager_type;
+        };
+
+        template<typename FunctionObj,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
+                             FunctionObj,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager_a<FunctionObj, Allocator> manager_type;
+        };
+      };
+
+      /* Retrieve the invoker for a reference to a function object. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
+      {
+        template<typename RefWrapper,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
+                             typename RefWrapper::type,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef reference_manager<typename RefWrapper::type> manager_type;
+        };
+
+        template<typename RefWrapper,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
+                             typename RefWrapper::type,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef reference_manager<typename RefWrapper::type> manager_type;
+        };
+      };
+
+
+      /**
+       * vtable for a specific ndnboost::function instance. This
+       * structure must be an aggregate so that we can use static
+       * initialization in ndnboost::function's assign_to and assign_to_a
+       * members. It therefore cannot have any constructors,
+       * destructors, base classes, etc.
+       */
+      template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+      struct BOOST_FUNCTION_VTABLE
+      {
+#ifndef BOOST_NO_VOID_RETURNS
+        typedef R         result_type;
+#else
+        typedef typename function_return_type<R>::type result_type;
+#endif // BOOST_NO_VOID_RETURNS
+
+        typedef result_type (*invoker_type)(function_buffer&
+                                            BOOST_FUNCTION_COMMA
+                                            BOOST_FUNCTION_TEMPLATE_ARGS);
+
+        template<typename F>
+        bool assign_to(F f, function_buffer& functor) const
+        {
+          typedef typename get_function_tag<F>::type tag;
+          return assign_to(f, functor, tag());
+        }
+        template<typename F,typename Allocator>
+        bool assign_to_a(F f, function_buffer& functor, Allocator a) const
+        {
+          typedef typename get_function_tag<F>::type tag;
+          return assign_to_a(f, functor, a, tag());
+        }
+
+        void clear(function_buffer& functor) const
+        {
+          if (base.manager)
+            base.manager(functor, functor, destroy_functor_tag);
+        }
+
+      private:
+        // Function pointers
+        template<typename FunctionPtr>
+        bool 
+        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
+        {
+          this->clear(functor);
+          if (f) {
+            // should be a reinterpret cast, but some compilers insist
+            // on giving cv-qualifiers to free functions
+            functor.func_ptr = reinterpret_cast<void (*)()>(f);
+            return true;
+          } else {
+            return false;
+          }
+        }
+        template<typename FunctionPtr,typename Allocator>
+        bool 
+        assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
+        {
+          return assign_to(f,functor,function_ptr_tag());
+        }
+
+        // Member pointers
+#if BOOST_FUNCTION_NUM_ARGS > 0
+        template<typename MemberPtr>
+        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
+        {
+          // DPG TBD: Add explicit support for member function
+          // objects, so we invoke through mem_fn() but we retain the
+          // right target_type() values.
+          if (f) {
+            this->assign_to(ndnboost::mem_fn(f), functor);
+            return true;
+          } else {
+            return false;
+          }
+        }
+        template<typename MemberPtr,typename Allocator>
+        bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
+        {
+          // DPG TBD: Add explicit support for member function
+          // objects, so we invoke through mem_fn() but we retain the
+          // right target_type() values.
+          if (f) {
+            this->assign_to_a(ndnboost::mem_fn(f), functor, a);
+            return true;
+          } else {
+            return false;
+          }
+        }
+#endif // BOOST_FUNCTION_NUM_ARGS > 0
+
+        // Function objects
+        // Assign to a function object using the small object optimization
+        template<typename FunctionObj>
+        void 
+        assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const
+        {
+          new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f);
+        }
+        template<typename FunctionObj,typename Allocator>
+        void 
+        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const
+        {
+          assign_functor(f,functor,mpl::true_());
+        }
+
+        // Assign to a function object allocated on the heap.
+        template<typename FunctionObj>
+        void 
+        assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const
+        {
+          functor.obj_ptr = new FunctionObj(f);
+        }
+        template<typename FunctionObj,typename Allocator>
+        void 
+        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const
+        {
+          typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
+          typedef typename Allocator::template rebind<functor_wrapper_type>::other
+            wrapper_allocator_type;
+          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
+          wrapper_allocator_type wrapper_allocator(a);
+          wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
+          wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
+          functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
+          functor.obj_ptr = new_f;
+        }
+
+        template<typename FunctionObj>
+        bool 
+        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
+        {
+          if (!ndnboost::detail::function::has_empty_target(ndnboost::addressof(f))) {
+            assign_functor(f, functor, 
+                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
+            return true;
+          } else {
+            return false;
+          }
+        }
+        template<typename FunctionObj,typename Allocator>
+        bool 
+        assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
+        {
+          if (!ndnboost::detail::function::has_empty_target(ndnboost::addressof(f))) {
+            assign_functor_a(f, functor, a,
+                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
+            return true;
+          } else {
+            return false;
+          }
+        }
+
+        // Reference to a function object
+        template<typename FunctionObj>
+        bool 
+        assign_to(const reference_wrapper<FunctionObj>& f, 
+                  function_buffer& functor, function_obj_ref_tag) const
+        {
+          functor.obj_ref.obj_ptr = (void *)(f.get_pointer());
+          functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
+          functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
+          return true;
+        }
+        template<typename FunctionObj,typename Allocator>
+        bool 
+        assign_to_a(const reference_wrapper<FunctionObj>& f, 
+                  function_buffer& functor, Allocator, function_obj_ref_tag) const
+        {
+          return assign_to(f,functor,function_obj_ref_tag());
+        }
+
+      public:
+        vtable_base base;
+        invoker_type invoker;
+      };
+    } // end namespace function
+  } // end namespace detail
+
+  template<
+    typename R BOOST_FUNCTION_COMMA
+    BOOST_FUNCTION_TEMPLATE_PARMS
+  >
+  class BOOST_FUNCTION_FUNCTION : public function_base
+
+#if BOOST_FUNCTION_NUM_ARGS == 1
+
+    , public std::unary_function<T0,R>
+
+#elif BOOST_FUNCTION_NUM_ARGS == 2
+
+    , public std::binary_function<T0,T1,R>
+
+#endif
+
+  {
+  public:
+#ifndef BOOST_NO_VOID_RETURNS
+    typedef R         result_type;
+#else
+    typedef  typename ndnboost::detail::function::function_return_type<R>::type
+      result_type;
+#endif // BOOST_NO_VOID_RETURNS
+
+  private:
+    typedef ndnboost::detail::function::BOOST_FUNCTION_VTABLE<
+              R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
+      vtable_type;
+
+    vtable_type* get_vtable() const {
+      return reinterpret_cast<vtable_type*>(
+               reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
+    }
+
+    struct clear_type {};
+
+  public:
+    BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
+
+    // add signature for ndnboost::lambda
+    template<typename Args>
+    struct sig
+    {
+      typedef result_type type;
+    };
+
+#if BOOST_FUNCTION_NUM_ARGS == 1
+    typedef T0 argument_type;
+#elif BOOST_FUNCTION_NUM_ARGS == 2
+    typedef T0 first_argument_type;
+    typedef T1 second_argument_type;
+#endif
+
+    BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
+    BOOST_FUNCTION_ARG_TYPES
+
+    typedef BOOST_FUNCTION_FUNCTION self_type;
+
+    BOOST_FUNCTION_FUNCTION() : function_base() { }
+
+    // MSVC chokes if the following two constructors are collapsed into
+    // one with a default parameter.
+    template<typename Functor>
+    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
+#ifndef BOOST_NO_SFINAE
+                            ,typename enable_if_c<
+                            (ndnboost::type_traits::ice_not<
+                             (is_integral<Functor>::value)>::value),
+                                        int>::type = 0
+#endif // BOOST_NO_SFINAE
+                            ) :
+      function_base()
+    {
+      this->assign_to(f);
+    }
+    template<typename Functor,typename Allocator>
+    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
+#ifndef BOOST_NO_SFINAE
+                            ,typename enable_if_c<
+                            (ndnboost::type_traits::ice_not<
+                             (is_integral<Functor>::value)>::value),
+                                        int>::type = 0
+#endif // BOOST_NO_SFINAE
+                            ) :
+      function_base()
+    {
+      this->assign_to_a(f,a);
+    }
+
+#ifndef BOOST_NO_SFINAE
+    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
+#else
+    BOOST_FUNCTION_FUNCTION(int zero) : function_base()
+    {
+      BOOST_ASSERT(zero == 0);
+    }
+#endif
+
+    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
+    {
+      this->assign_to_own(f);
+    }
+    
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
+    {
+      this->move_assign(f);
+    }
+#endif
+    
+    ~BOOST_FUNCTION_FUNCTION() { clear(); }
+
+    result_type operator()(BOOST_FUNCTION_PARMS) const
+    {
+      if (this->empty())
+        ndnboost::throw_exception(bad_function_call());
+
+      return get_vtable()->invoker
+               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
+    }
+
+    // The distinction between when to use BOOST_FUNCTION_FUNCTION and
+    // when to use self_type is obnoxious. MSVC cannot handle self_type as
+    // the return type of these assignment operators, but Borland C++ cannot
+    // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
+    // construct.
+    template<typename Functor>
+#ifndef BOOST_NO_SFINAE
+    typename enable_if_c<
+               (ndnboost::type_traits::ice_not<
+                 (is_integral<Functor>::value)>::value),
+               BOOST_FUNCTION_FUNCTION&>::type
+#else
+    BOOST_FUNCTION_FUNCTION&
+#endif
+    operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
+    {
+      this->clear();
+      BOOST_TRY  {
+        this->assign_to(f);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      return *this;
+    }
+    template<typename Functor,typename Allocator>
+    void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
+    {
+      this->clear();
+      BOOST_TRY{
+        this->assign_to_a(f,a);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+    }
+
+#ifndef BOOST_NO_SFINAE
+    BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
+    {
+      this->clear();
+      return *this;
+    }
+#else
+    BOOST_FUNCTION_FUNCTION& operator=(int zero)
+    {
+      BOOST_ASSERT(zero == 0);
+      this->clear();
+      return *this;
+    }
+#endif
+
+    // Assignment from another BOOST_FUNCTION_FUNCTION
+    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
+    {
+      if (&f == this)
+        return *this;
+
+      this->clear();
+      BOOST_TRY {
+        this->assign_to_own(f);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      return *this;
+    }
+    
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    // Move assignment from another BOOST_FUNCTION_FUNCTION
+    BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
+    {
+      
+      if (&f == this)
+        return *this;
+
+      this->clear();
+      BOOST_TRY {
+        this->move_assign(f);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      return *this;
+    }
+#endif
+
+    void swap(BOOST_FUNCTION_FUNCTION& other)
+    {
+      if (&other == this)
+        return;
+
+      BOOST_FUNCTION_FUNCTION tmp;
+      tmp.move_assign(*this);
+      this->move_assign(other);
+      other.move_assign(tmp);
+    }
+
+    // Clear out a target, if there is one
+    void clear()
+    {
+      if (vtable) {
+        if (!this->has_trivial_copy_and_destroy())
+          get_vtable()->clear(this->functor);
+        vtable = 0;
+      }
+    }
+
+#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
+    // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
+    operator bool () const { return !this->empty(); }
+#else
+  private:
+    struct dummy {
+      void nonnull() {}
+    };
+
+    typedef void (dummy::*safe_bool)();
+
+  public:
+    operator safe_bool () const
+      { return (this->empty())? 0 : &dummy::nonnull; }
+
+    bool operator!() const
+      { return this->empty(); }
+#endif
+
+  private:
+    void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
+    {
+      if (!f.empty()) {
+        this->vtable = f.vtable;
+        if (this->has_trivial_copy_and_destroy())
+          this->functor = f.functor;
+        else
+          get_vtable()->base.manager(f.functor, this->functor,
+                                     ndnboost::detail::function::clone_functor_tag);
+      }
+    }
+
+    template<typename Functor>
+    void assign_to(Functor f)
+    {
+      using detail::function::vtable_base;
+
+      typedef typename detail::function::get_function_tag<Functor>::type tag;
+      typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
+      typedef typename get_invoker::
+                         template apply<Functor, R BOOST_FUNCTION_COMMA 
+                        BOOST_FUNCTION_TEMPLATE_ARGS>
+        handler_type;
+      
+      typedef typename handler_type::invoker_type invoker_type;
+      typedef typename handler_type::manager_type manager_type;
+
+      // Note: it is extremely important that this initialization use
+      // static initialization. Otherwise, we will have a race
+      // condition here in multi-threaded code. See
+      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
+      static const vtable_type stored_vtable = 
+        { { &manager_type::manage }, &invoker_type::invoke };
+
+      if (stored_vtable.assign_to(f, functor)) {
+        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
+        if (ndnboost::has_trivial_copy_constructor<Functor>::value &&
+            ndnboost::has_trivial_destructor<Functor>::value &&
+            detail::function::function_allows_small_object_optimization<Functor>::value)
+          value |= static_cast<size_t>(0x01);
+        vtable = reinterpret_cast<detail::function::vtable_base *>(value);
+      } else 
+        vtable = 0;
+    }
+
+    template<typename Functor,typename Allocator>
+    void assign_to_a(Functor f,Allocator a)
+    {
+      using detail::function::vtable_base;
+
+      typedef typename detail::function::get_function_tag<Functor>::type tag;
+      typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
+      typedef typename get_invoker::
+                         template apply_a<Functor, R BOOST_FUNCTION_COMMA 
+                         BOOST_FUNCTION_TEMPLATE_ARGS,
+                         Allocator>
+        handler_type;
+      
+      typedef typename handler_type::invoker_type invoker_type;
+      typedef typename handler_type::manager_type manager_type;
+
+      // Note: it is extremely important that this initialization use
+      // static initialization. Otherwise, we will have a race
+      // condition here in multi-threaded code. See
+      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
+      static const vtable_type stored_vtable =
+        { { &manager_type::manage }, &invoker_type::invoke };
+
+      if (stored_vtable.assign_to_a(f, functor, a)) { 
+        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
+        if (ndnboost::has_trivial_copy_constructor<Functor>::value &&
+            ndnboost::has_trivial_destructor<Functor>::value &&
+            detail::function::function_allows_small_object_optimization<Functor>::value)
+          value |= static_cast<std::size_t>(0x01);
+        vtable = reinterpret_cast<detail::function::vtable_base *>(value);
+      } else 
+        vtable = 0;
+    }
+
+    // Moves the value from the specified argument to *this. If the argument 
+    // has its function object allocated on the heap, move_assign will pass 
+    // its buffer to *this, and set the argument's buffer pointer to NULL. 
+    void move_assign(BOOST_FUNCTION_FUNCTION& f) 
+    { 
+      if (&f == this)
+        return;
+
+      BOOST_TRY {
+        if (!f.empty()) {
+          this->vtable = f.vtable;
+          if (this->has_trivial_copy_and_destroy())
+            this->functor = f.functor;
+          else
+            get_vtable()->base.manager(f.functor, this->functor,
+                                     ndnboost::detail::function::move_functor_tag);
+          f.vtable = 0;
+        } else {
+          clear();
+        }
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+    }
+  };
+
+  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+  inline void swap(BOOST_FUNCTION_FUNCTION<
+                     R BOOST_FUNCTION_COMMA
+                     BOOST_FUNCTION_TEMPLATE_ARGS
+                   >& f1,
+                   BOOST_FUNCTION_FUNCTION<
+                     R BOOST_FUNCTION_COMMA
+                     BOOST_FUNCTION_TEMPLATE_ARGS
+                   >& f2)
+  {
+    f1.swap(f2);
+  }
+
+// Poison comparisons between ndnboost::function objects of the same type.
+template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+  void operator==(const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
+                  const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>&);
+template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+  void operator!=(const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
+                  const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>& );
+
+#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
+
+#if BOOST_FUNCTION_NUM_ARGS == 0
+#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
+#else
+#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
+#endif
+
+template<typename R BOOST_FUNCTION_COMMA
+         BOOST_FUNCTION_TEMPLATE_PARMS>
+class function<BOOST_FUNCTION_PARTIAL_SPEC>
+  : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
+{
+  typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
+  typedef function self_type;
+
+  struct clear_type {};
+
+public:
+
+  function() : base_type() {}
+
+  template<typename Functor>
+  function(Functor f
+#ifndef BOOST_NO_SFINAE
+           ,typename enable_if_c<
+                            (ndnboost::type_traits::ice_not<
+                          (is_integral<Functor>::value)>::value),
+                       int>::type = 0
+#endif
+           ) :
+    base_type(f)
+  {
+  }
+  template<typename Functor,typename Allocator>
+  function(Functor f, Allocator a
+#ifndef BOOST_NO_SFINAE
+           ,typename enable_if_c<
+                            (ndnboost::type_traits::ice_not<
+                          (is_integral<Functor>::value)>::value),
+                       int>::type = 0
+#endif
+           ) :
+    base_type(f,a)
+  {
+  }
+
+#ifndef BOOST_NO_SFINAE
+  function(clear_type*) : base_type() {}
+#endif
+
+  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
+
+  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  // Move constructors
+  function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
+  function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
+#endif
+  
+  self_type& operator=(const self_type& f)
+  {
+    self_type(f).swap(*this);
+    return *this;
+  }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  self_type& operator=(self_type&& f)
+  {
+    self_type(static_cast<self_type&&>(f)).swap(*this);
+    return *this;
+  }
+#endif  
+
+  template<typename Functor>
+#ifndef BOOST_NO_SFINAE
+  typename enable_if_c<
+                            (ndnboost::type_traits::ice_not<
+                         (is_integral<Functor>::value)>::value),
+                      self_type&>::type
+#else
+  self_type&
+#endif
+  operator=(Functor f)
+  {
+    self_type(f).swap(*this);
+    return *this;
+  }
+
+#ifndef BOOST_NO_SFINAE
+  self_type& operator=(clear_type*)
+  {
+    this->clear();
+    return *this;
+  }
+#endif
+
+  self_type& operator=(const base_type& f)
+  {
+    self_type(f).swap(*this);
+    return *this;
+  }
+  
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  self_type& operator=(base_type&& f)
+  {
+    self_type(static_cast<base_type&&>(f)).swap(*this);
+    return *this;
+  }
+#endif 
+};
+
+#undef BOOST_FUNCTION_PARTIAL_SPEC
+#endif // have partial specialization
+
+} // end namespace ndnboost
+
+// Cleanup after ourselves...
+#undef BOOST_FUNCTION_VTABLE
+#undef BOOST_FUNCTION_COMMA
+#undef BOOST_FUNCTION_FUNCTION
+#undef BOOST_FUNCTION_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
+#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
+#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
+#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
+#undef BOOST_FUNCTION_MEMBER_INVOKER
+#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
+#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
+#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
+#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_GET_INVOKER
+#undef BOOST_FUNCTION_TEMPLATE_PARMS
+#undef BOOST_FUNCTION_TEMPLATE_ARGS
+#undef BOOST_FUNCTION_PARMS
+#undef BOOST_FUNCTION_PARM
+#undef BOOST_FUNCTION_ARGS
+#undef BOOST_FUNCTION_ARG_TYPE
+#undef BOOST_FUNCTION_ARG_TYPES
+#undef BOOST_FUNCTION_VOID_RETURN_TYPE
+#undef BOOST_FUNCTION_RETURN
+
+#if defined(BOOST_MSVC)
+#   pragma warning( pop )
+#endif