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/libs/function/test/Jamfile.v2 b/libs/function/test/Jamfile.v2
new file mode 100644
index 0000000..fe4dfe3
--- /dev/null
+++ b/libs/function/test/Jamfile.v2
@@ -0,0 +1,67 @@
+# Function library
+
+# Copyright Douglas Gregor 2001-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/
+
+project
+    : requirements <toolset>msvc:<asynch-exceptions>on
+    : source-location $(BOOST_ROOT)
+    ;
+
+# bring in rules for testing
+import testing ;
+
+{
+
+  test-suite function
+    : 
+  [ run libs/function/test/function_test.cpp :  :  :  : lib_function_test ]
+
+  [ run libs/function/test/function_n_test.cpp :  :  :  :  ]
+
+  [ run libs/function/test/allocator_test.cpp ../../../libs/test/build//ndnboost_test_exec_monitor :  :  :  :  ]
+
+  [ run libs/function/test/stateless_test.cpp ../../../libs/test/build//ndnboost_test_exec_monitor :  :  :  :  ]
+
+  [ run libs/function/test/lambda_test.cpp ../../../libs/test/build//ndnboost_test_exec_monitor :  :  :  :  ]
+
+  [ compile-fail libs/function/test/function_test_fail1.cpp :  :  :  :  ]
+
+  [ compile-fail libs/function/test/function_test_fail2.cpp :  :  :  :  ]
+
+  [ compile libs/function/test/function_30.cpp :  :  :  :  ] 
+
+  [ run libs/function/test/function_arith_cxx98.cpp :  :  :  :  ]
+
+  [ run libs/function/test/function_arith_portable.cpp :  :  :  :  ]
+
+  [ run libs/function/test/sum_avg_cxx98.cpp :  :  :  :  ]
+
+  [ run libs/function/test/sum_avg_portable.cpp :  :  :  :  ]
+
+  [ run libs/function/test/mem_fun_cxx98.cpp :  :  :  :  ]
+
+  [ run libs/function/test/mem_fun_portable.cpp :  :  :  :  ]
+
+  [ run libs/function/test/std_bind_cxx98.cpp :  :  :  :  ]
+
+  [ run libs/function/test/std_bind_portable.cpp :  :  :  :  ]
+
+  [ run libs/function/test/function_ref_cxx98.cpp :  :  :  :  ]
+
+  [ run libs/function/test/function_ref_portable.cpp :  :  :  :  ]
+  
+  [ run libs/function/test/contains_test.cpp : : : : ]
+   
+  [ run libs/function/test/contains2_test.cpp : : : : ]
+   
+  [ run libs/function/test/nothrow_swap.cpp :  :  :  :  ]
+
+  [ compile libs/function/test/function_typeof_test.cpp ]
+ ;
+}
+      
diff --git a/libs/function/test/allocator_test.cpp b/libs/function/test/allocator_test.cpp
new file mode 100644
index 0000000..de91e6b
--- /dev/null
+++ b/libs/function/test/allocator_test.cpp
@@ -0,0 +1,137 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-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
+
+#include <boost/test/minimal.hpp>
+#include <cassert>
+#include <functional>
+#include <boost/function.hpp>
+
+using namespace std;
+using namespace ndnboost;
+
+static int alloc_count = 0;
+static int dealloc_count = 0;
+
+template<typename T>
+struct counting_allocator : public std::allocator<T>
+{
+  template<typename U>
+  struct rebind
+  {
+    typedef counting_allocator<U> other;
+  };
+
+  counting_allocator()
+  {
+  }
+
+  template<typename U>
+  counting_allocator( counting_allocator<U> )
+  {
+  }
+
+  T* allocate(std::size_t n)
+  {
+    alloc_count++;
+    return std::allocator<T>::allocate(n);
+  }
+
+  void deallocate(T* p, std::size_t n)
+  {
+    dealloc_count++;
+    std::allocator<T>::deallocate(p, n);
+  }
+};
+
+struct enable_small_object_optimization
+{
+};
+
+struct disable_small_object_optimization
+{
+  int unused_state_data[32];
+};
+
+template <typename base>
+struct plus_int: base
+{
+  int operator()(int x, int y) const { return x + y; }
+};
+
+static int do_minus(int x, int y) { return x-y; }
+
+template <typename base>
+struct DoNothing: base
+{
+  void operator()() const {}
+};
+
+static void do_nothing() {}
+
+int
+test_main(int, char*[])
+{
+  function2<int, int, int> f;
+  f.assign( plus_int<disable_small_object_optimization>(), counting_allocator<int>() );
+  f.clear();
+  BOOST_CHECK(alloc_count == 1);
+  BOOST_CHECK(dealloc_count == 1);
+  alloc_count = 0;
+  dealloc_count = 0;
+  f.assign( plus_int<enable_small_object_optimization>(), counting_allocator<int>() );
+  f.clear();
+  BOOST_CHECK(alloc_count == 0);
+  BOOST_CHECK(dealloc_count == 0);
+  f.assign( plus_int<disable_small_object_optimization>(), std::allocator<int>() );
+  f.clear();
+  f.assign( plus_int<enable_small_object_optimization>(), std::allocator<int>() );
+  f.clear();
+
+  alloc_count = 0;
+  dealloc_count = 0;
+  f.assign( &do_minus, counting_allocator<int>() );
+  f.clear();
+  BOOST_CHECK(alloc_count == 0);
+  BOOST_CHECK(dealloc_count == 0);
+  f.assign( &do_minus, std::allocator<int>() );
+  f.clear();
+
+  function0<void> fv;
+  alloc_count = 0;
+  dealloc_count = 0;
+  fv.assign( DoNothing<disable_small_object_optimization>(), counting_allocator<int>() );
+  fv.clear();
+  BOOST_CHECK(alloc_count == 1);
+  BOOST_CHECK(dealloc_count == 1);
+  alloc_count = 0;
+  dealloc_count = 0;
+  fv.assign( DoNothing<enable_small_object_optimization>(), counting_allocator<int>() );
+  fv.clear();
+  BOOST_CHECK(alloc_count == 0);
+  BOOST_CHECK(dealloc_count == 0);
+  fv.assign( DoNothing<disable_small_object_optimization>(), std::allocator<int>() );
+  fv.clear();
+  fv.assign( DoNothing<enable_small_object_optimization>(), std::allocator<int>() );
+  fv.clear();
+
+  alloc_count = 0;
+  dealloc_count = 0;
+  fv.assign( &do_nothing, counting_allocator<int>() );
+  fv.clear();
+  BOOST_CHECK(alloc_count == 0);
+  BOOST_CHECK(dealloc_count == 0);
+  fv.assign( &do_nothing, std::allocator<int>() );
+  fv.clear();
+  
+  function0<void> fv2;
+  fv.assign(&do_nothing, std::allocator<int>() );
+  fv2.assign(fv, std::allocator<int>() );
+
+  return 0;
+}
diff --git a/libs/function/test/contains2_test.cpp b/libs/function/test/contains2_test.cpp
new file mode 100644
index 0000000..2127eb8
--- /dev/null
+++ b/libs/function/test/contains2_test.cpp
@@ -0,0 +1,88 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2004.
+//  Copyright 2005 Peter Dimov
+
+//  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)
+
+#include <boost/function.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+static int forty_two()
+{
+    return 42;
+}
+
+struct Seventeen
+{
+    int operator()() const
+    {
+        return 17;
+    }
+};
+
+bool operator==(const Seventeen&, const Seventeen&)
+{
+    return true;
+}
+
+struct ReturnInt
+{
+    explicit ReturnInt(int value) : value(value)
+    {
+    }
+
+    int operator()() const
+    {
+        return value;
+    }
+
+    int value;
+};
+
+bool operator==(const ReturnInt& x, const ReturnInt& y)
+{
+    return x.value == y.value;
+}
+
+bool operator!=(const ReturnInt& x, const ReturnInt& y)
+{
+    return x.value != y.value;
+}
+
+int main()
+{
+    ndnboost::function0<int> fn;
+
+    fn = &forty_two;
+
+    BOOST_TEST( fn() == 42 );
+
+    BOOST_TEST( fn.contains(&forty_two) );
+    BOOST_TEST( !fn.contains( Seventeen() ) );
+    BOOST_TEST( !fn.contains( ReturnInt(0) ) );
+    BOOST_TEST( !fn.contains( ReturnInt(12) ) );
+
+    fn = Seventeen();
+
+    BOOST_TEST( fn() == 17 );
+
+    BOOST_TEST( !fn.contains( &forty_two ) );
+    BOOST_TEST( fn.contains( Seventeen() ) );
+    BOOST_TEST( !fn.contains( ReturnInt(0) ) );
+    BOOST_TEST( !fn.contains( ReturnInt(12) ) );
+
+    fn = ReturnInt(12);
+
+    BOOST_TEST( fn() == 12 );
+
+    BOOST_TEST( !fn.contains( &forty_two ) );
+    BOOST_TEST( !fn.contains( Seventeen() ) );
+    BOOST_TEST( !fn.contains( ReturnInt(0) ) );
+    BOOST_TEST( fn.contains( ReturnInt(12) ) );
+
+    return ndnboost::report_errors();
+}
diff --git a/libs/function/test/contains_test.cpp b/libs/function/test/contains_test.cpp
new file mode 100644
index 0000000..56ea716
--- /dev/null
+++ b/libs/function/test/contains_test.cpp
@@ -0,0 +1,235 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2004. 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)
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+
+static int forty_two() { return 42; }
+
+struct Seventeen
+{
+  int operator()() const { return 17; }
+};
+
+struct ReturnInt
+{
+  explicit ReturnInt(int value) : value(value) {}
+
+  int operator()() const { return value; }
+
+  int value;
+};
+
+bool operator==(const ReturnInt& x, const ReturnInt& y)
+{ return x.value == y.value; }
+
+bool operator!=(const ReturnInt& x, const ReturnInt& y)
+{ return x.value != y.value; }
+
+namespace contain_test {
+
+struct ReturnIntFE
+{
+  explicit ReturnIntFE(int value) : value(value) {}
+
+  int operator()() const { return value; }
+
+  int value;
+};
+
+}
+
+#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+
+namespace contain_test {
+# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+bool function_equal(const ReturnIntFE& x, const ReturnIntFE& y)
+{ return x.value == y.value; }
+# else
+bool function_equal_impl(const ReturnIntFE& x, const ReturnIntFE& y, int)
+{ return x.value == y.value; }
+# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+}
+#else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+namespace ndnboost {
+# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+bool 
+function_equal(const contain_test::ReturnIntFE& x, 
+               const contain_test::ReturnIntFE& y)
+{ return x.value == y.value; }
+# else
+bool 
+function_equal_impl(const contain_test::ReturnIntFE& x, 
+                    const contain_test::ReturnIntFE& y, int)
+{ return x.value == y.value; }
+# endif
+}
+#endif
+
+static void target_test()
+{
+  ndnboost::function0<int> f;
+
+  f = &forty_two;
+  BOOST_CHECK(*f.target<int (*)()>() == &forty_two);
+  BOOST_CHECK(!f.target<Seventeen>());
+
+  f = Seventeen();
+  BOOST_CHECK(!f.target<int (*)()>());
+  BOOST_CHECK(f.target<Seventeen>());
+
+  Seventeen this_seventeen;
+  f = ndnboost::ref(this_seventeen);
+  BOOST_CHECK(!f.target<int (*)()>());
+  BOOST_CHECK(f.target<Seventeen>());
+  BOOST_CHECK(f.target<Seventeen>() == &this_seventeen);
+
+  const Seventeen const_seventeen = this_seventeen;
+  f = ndnboost::ref(const_seventeen);
+  BOOST_CHECK(!f.target<int (*)()>());
+  BOOST_CHECK(f.target<const Seventeen>());
+  BOOST_CHECK(f.target<const Seventeen>() == &const_seventeen);
+  BOOST_CHECK(f.target<const volatile Seventeen>());
+  BOOST_CHECK(!f.target<Seventeen>());
+  BOOST_CHECK(!f.target<volatile Seventeen>());
+}
+
+static void equal_test()
+{
+  ndnboost::function0<int> f;
+
+  f = &forty_two;
+  BOOST_CHECK(f == &forty_two);
+  BOOST_CHECK(f != ReturnInt(17));
+#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+  BOOST_CHECK(&forty_two == f);
+  BOOST_CHECK(ReturnInt(17) != f);
+#endif
+
+  BOOST_CHECK(f.contains(&forty_two));
+
+  f = ReturnInt(17);
+  BOOST_CHECK(f != &forty_two);
+  BOOST_CHECK(f == ReturnInt(17));
+  BOOST_CHECK(f != ReturnInt(16));
+#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+  BOOST_CHECK(&forty_two != f);
+  BOOST_CHECK(ReturnInt(17) == f);
+  BOOST_CHECK(ReturnInt(16) != f);
+#endif
+
+  BOOST_CHECK(f.contains(ReturnInt(17)));
+
+  f = contain_test::ReturnIntFE(17);
+  BOOST_CHECK(f != &forty_two);
+  BOOST_CHECK(f == contain_test::ReturnIntFE(17));
+  BOOST_CHECK(f != contain_test::ReturnIntFE(16));
+#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+  BOOST_CHECK(&forty_two != f);
+  BOOST_CHECK(contain_test::ReturnIntFE(17) == f);
+  BOOST_CHECK(contain_test::ReturnIntFE(16) != f);
+#endif
+
+  BOOST_CHECK(f.contains(contain_test::ReturnIntFE(17)));
+
+#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
+  ndnboost::function<int(void)> g;
+
+  g = &forty_two;
+  BOOST_CHECK(g == &forty_two);
+  BOOST_CHECK(g != ReturnInt(17));
+#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+  BOOST_CHECK(&forty_two == g);
+  BOOST_CHECK(ReturnInt(17) != g);
+#  endif
+
+  g = ReturnInt(17);
+  BOOST_CHECK(g != &forty_two);
+  BOOST_CHECK(g == ReturnInt(17));
+  BOOST_CHECK(g != ReturnInt(16));
+#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+  BOOST_CHECK(&forty_two != g);
+  BOOST_CHECK(ReturnInt(17) == g);
+  BOOST_CHECK(ReturnInt(16) != g);
+#  endif
+#endif
+}
+
+static void ref_equal_test()
+{
+  {
+    ReturnInt ri(17);
+    ndnboost::function0<int> f = ndnboost::ref(ri);
+
+    // References and values are equal
+    BOOST_CHECK(f == ndnboost::ref(ri));
+    BOOST_CHECK(f == ri);
+    BOOST_CHECK(ndnboost::ref(ri) == f);
+    BOOST_CHECK(!(f != ndnboost::ref(ri)));
+    BOOST_CHECK(!(f != ri));
+    BOOST_CHECK(!(ndnboost::ref(ri) != f));
+#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+    BOOST_CHECK(ri == f);
+    BOOST_CHECK(!(ri != f));
+#endif
+
+    // Values equal, references inequal
+    ReturnInt ri2(17);
+    BOOST_CHECK(f == ri2);
+    BOOST_CHECK(f != ndnboost::ref(ri2));
+    BOOST_CHECK(ndnboost::ref(ri2) != f);
+    BOOST_CHECK(!(f != ri2));
+    BOOST_CHECK(!(f == ndnboost::ref(ri2)));
+    BOOST_CHECK(!(ndnboost::ref(ri2) == f));
+#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+    BOOST_CHECK(ri2 == f);
+    BOOST_CHECK(!(ri2 != f));
+#endif 
+  }
+
+#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
+  {
+    ReturnInt ri(17);
+    ndnboost::function<int(void)> f = ndnboost::ref(ri);
+
+    // References and values are equal
+    BOOST_CHECK(f == ndnboost::ref(ri));
+    BOOST_CHECK(f == ri);
+    BOOST_CHECK(ndnboost::ref(ri) == f);
+    BOOST_CHECK(!(f != ndnboost::ref(ri)));
+    BOOST_CHECK(!(f != ri));
+    BOOST_CHECK(!(ndnboost::ref(ri) != f));
+#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+    BOOST_CHECK(ri == f);
+    BOOST_CHECK(!(ri != f));
+#  endif
+
+    // Values equal, references inequal
+    ReturnInt ri2(17);
+    BOOST_CHECK(f == ri2);
+    BOOST_CHECK(f != ndnboost::ref(ri2));
+    BOOST_CHECK(ndnboost::ref(ri2) != f);
+    BOOST_CHECK(!(f != ri2));
+    BOOST_CHECK(!(f == ndnboost::ref(ri2)));
+    BOOST_CHECK(!(ndnboost::ref(ri2) == f));
+#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+    BOOST_CHECK(ri2 == f);
+    BOOST_CHECK(!(ri2 != f));
+#  endif
+  }
+#endif
+}
+
+int test_main(int, char*[])
+{
+  target_test();
+  equal_test();
+  ref_equal_test();
+
+  return 0;
+}
diff --git a/libs/function/test/function_30.cpp b/libs/function/test/function_30.cpp
new file mode 100644
index 0000000..768b425
--- /dev/null
+++ b/libs/function/test/function_30.cpp
@@ -0,0 +1,25 @@
+// 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
+
+// Make sure we don't try to redefine function2
+#include <boost/function/function2.hpp>
+
+// Define all Boost.Function class templates up to 30 arguments
+#define BOOST_FUNCTION_MAX_ARGS 30
+#include <boost/function.hpp>
+
+int main()
+{
+  ndnboost::function0<float> f0;
+
+  ndnboost::function30<float, int, int, int, int, int, int, int, int, int, int,
+                    int, int, int, int, int, int, int, int, int, int,
+                    int, int, int, int, int, int, int, int, int, int> f30;
+  return 0;
+}
diff --git a/libs/function/test/function_arith_cxx98.cpp b/libs/function/test/function_arith_cxx98.cpp
new file mode 100644
index 0000000..3ef1f09
--- /dev/null
+++ b/libs/function/test/function_arith_cxx98.cpp
@@ -0,0 +1,34 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <iostream>
+
+
+float mul_ints(int x, int y) { return ((float)x) * y; }
+struct int_div { 
+  float operator()(int x, int y) const { return ((float)x)/y; }; 
+};
+
+int main()
+{
+    ndnboost::function<float (int x, int y)> f;
+    f = int_div();
+    std::cout << f(5, 3) << std::endl;
+    if (f)
+  std::cout << f(5, 3) << std::endl;
+else
+  std::cout << "f has no target, so it is unsafe to call" << std::endl;
+    f = 0;
+    f = &mul_ints;
+  
+    return 0;
+}
diff --git a/libs/function/test/function_arith_portable.cpp b/libs/function/test/function_arith_portable.cpp
new file mode 100644
index 0000000..04ebca5
--- /dev/null
+++ b/libs/function/test/function_arith_portable.cpp
@@ -0,0 +1,32 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <iostream>
+
+float mul_ints(int x, int y) { return ((float)x) * y; }
+struct int_div { 
+  float operator()(int x, int y) const { return ((float)x)/y; }; 
+};
+int main()
+{
+    ndnboost::function2<float, int, int> f;
+    f = int_div();
+    std::cout << f(5, 3) << std::endl;
+    if (f)
+  std::cout << f(5, 3) << std::endl;
+else
+  std::cout << "f has no target, so it is unsafe to call" << std::endl;
+    f = 0;
+    f = &mul_ints;
+
+    return 0;
+}
diff --git a/libs/function/test/function_n_test.cpp b/libs/function/test/function_n_test.cpp
new file mode 100644
index 0000000..11b4bf9
--- /dev/null
+++ b/libs/function/test/function_n_test.cpp
@@ -0,0 +1,697 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-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
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+#include <functional>
+#include <cassert>
+#include <string>
+
+using namespace ndnboost;
+using std::string;
+using std::negate;
+
+int global_int;
+
+struct write_five_obj { void operator()() const { global_int = 5; } };
+struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
+static void write_five() { global_int = 5; }
+static void write_three() { global_int = 3; }
+struct generate_five_obj { int operator()() const { return 5; } };
+struct generate_three_obj { int operator()() const { return 3; } };
+static int generate_five() { return 5; }
+static int generate_three() { return 3; }
+static string identity_str(const string& s) { return s; }
+static string string_cat(const string& s1, const string& s2) { return s1+s2; }
+static int sum_ints(int x, int y) { return x+y; }
+
+struct write_const_1_nonconst_2
+{
+  void operator()() { global_int = 2; }
+  void operator()() const { global_int = 1; }
+};
+
+struct add_to_obj
+{
+  add_to_obj(int v) : value(v) {}
+
+  int operator()(int x) const { return value + x; }
+
+  int value;
+};
+
+static void
+test_zero_args()
+{
+  typedef function0<void> func_void_type;
+
+  write_five_obj five = write_five_obj(); // Initialization for Borland C++ 5.5
+  write_three_obj three = write_three_obj(); // Ditto
+
+  // Default construction
+  func_void_type v1;
+  BOOST_CHECK(v1.empty());
+
+  // Assignment to an empty function
+  v1 = five;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation of a function
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v1.clear();
+  BOOST_CHECK(!v1);
+
+  // Assignment to an empty function
+  v1 = three;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation and self-assignment
+  global_int = 0;
+  v1 = v1;
+  v1();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v1 = five;
+
+  // Invocation and self-assignment
+  global_int = 0;
+  v1 = (v1);
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // clear
+  v1 = 0;
+  BOOST_CHECK(v1.empty());
+
+  // Assignment to an empty function from a free function
+  v1 = &write_five;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v1 = &write_three;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v1 = five;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v1 = write_three;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 3);
+
+  // Construction from another function (that is empty)
+  v1.clear();
+  func_void_type v2(v1);
+  BOOST_CHECK(!v2? true : false);
+
+  // Assignment to an empty function
+  v2 = three;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v2 = (five);
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  v2.clear();
+  BOOST_CHECK(v2.empty());
+
+  // Assignment to an empty function from a free function
+  v2 = (&write_five);
+  BOOST_CHECK(v2? true : false);
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v2 = &write_three;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Swapping
+  v1 = five;
+  swap(v1, v2);
+  v2();
+  BOOST_CHECK(global_int == 5);
+  v1();
+  BOOST_CHECK(global_int == 3);
+  swap(v1, v2);
+  v1.clear();
+
+  // Assignment
+  v2 = five;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v2 = &write_three;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a function from an empty function
+  v2 = v1;
+  BOOST_CHECK(v2.empty());
+
+  // Assignment to a function from a function with a functor
+  v1 = three;
+  v2 = v1;
+  BOOST_CHECK(!v1.empty());
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 3);
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Assign to a function from a function with a function
+  v2 = &write_five;
+  v1 = v2;
+  BOOST_CHECK(!v1.empty());
+  BOOST_CHECK(!v2.empty());
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  // Construct a function given another function containing a function
+  func_void_type v3(v1);
+
+  // Invocation of a function
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v3.clear();
+  BOOST_CHECK(!v3? true : false);
+
+  // Assignment to an empty function
+  v3 = three;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v3 = five;
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v3.clear();
+  BOOST_CHECK(v3.empty());
+
+  // Assignment to an empty function from a free function
+  v3 = &write_five;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v3 = &write_three;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v3 = five;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // Construction of a function from a function containing a functor
+  func_void_type v4(v3);
+
+  // Invocation of a function
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v4.clear();
+  BOOST_CHECK(v4.empty());
+
+  // Assignment to an empty function
+  v4 = three;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v4 = five;
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v4.clear();
+  BOOST_CHECK(v4.empty());
+
+  // Assignment to an empty function from a free function
+  v4 = &write_five;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v4 = &write_three;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v4 = five;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // Construction of a function from a functor
+  func_void_type v5(five);
+
+  // Invocation of a function
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v5.clear();
+  BOOST_CHECK(v5.empty());
+
+  // Assignment to an empty function
+  v5 = three;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v5 = five;
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v5.clear();
+  BOOST_CHECK(v5.empty());
+
+  // Assignment to an empty function from a free function
+  v5 = &write_five;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v5 = &write_three;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v5 = five;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // Construction of a function from a function
+  func_void_type v6(&write_five);
+
+  // Invocation of a function
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v6.clear();
+  BOOST_CHECK(v6.empty());
+
+  // Assignment to an empty function
+  v6 = three;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v6 = five;
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v6.clear();
+  BOOST_CHECK(v6.empty());
+
+  // Assignment to an empty function from a free function
+  v6 = &write_five;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v6 = &write_three;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v6 = five;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // Const vs. non-const
+  // Initialization for Borland C++ 5.5
+  write_const_1_nonconst_2 one_or_two = write_const_1_nonconst_2(); 
+  const function0<void> v7(one_or_two);
+  function0<void> v8(one_or_two);
+
+  global_int = 0;
+  v7();
+  BOOST_CHECK(global_int == 2);
+
+  global_int = 0;
+  v8();
+  BOOST_CHECK(global_int == 2);
+
+  // Test construction from 0 and comparison to 0
+  func_void_type v9(0);
+  BOOST_CHECK(v9 == 0);
+# if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540 || defined(BOOST_STRICT_CONFIG)
+  BOOST_CHECK(0 == v9);
+#else
+  BOOST_CHECK(v9.empty());
+#endif
+
+  // Test return values
+  typedef function0<int> func_int_type;
+  // Initialization for Borland C++ 5.5
+  generate_five_obj gen_five = generate_five_obj();
+  generate_three_obj gen_three = generate_three_obj();
+  func_int_type i0(gen_five);
+
+  BOOST_CHECK(i0() == 5);
+  i0 = gen_three;
+  BOOST_CHECK(i0() == 3);
+  i0 = &generate_five;
+  BOOST_CHECK(i0() == 5);
+  i0 = &generate_three;
+  BOOST_CHECK(i0() == 3);
+  BOOST_CHECK(i0? true : false);
+  i0.clear();
+  BOOST_CHECK(!i0? true : false);
+
+  // Test return values with compatible types
+  typedef function0<long> func_long_type;
+  func_long_type i1(gen_five);
+
+  BOOST_CHECK(i1() == 5);
+  i1 = gen_three;
+  BOOST_CHECK(i1() == 3);
+  i1 = &generate_five;
+  BOOST_CHECK(i1() == 5);
+  i1 = &generate_three;
+  BOOST_CHECK(i1() == 3);
+  BOOST_CHECK(i1? true : false);
+  i1.clear();
+  BOOST_CHECK(!i1? true : false);
+}
+
+static void
+test_one_arg()
+{
+  negate<int> neg = negate<int>(); // Initialization for Borland C++ 5.5
+
+  function1<int, int> f1(neg);
+  BOOST_CHECK(f1(5) == -5);
+
+  function1<string, string> id(&identity_str);
+  BOOST_CHECK(id("str") == "str");
+
+  function1<std::string, const char*> id2(&identity_str);
+  BOOST_CHECK(id2("foo") == "foo");
+
+  add_to_obj add_to(5);
+  function1<int, int> f2(add_to);
+  BOOST_CHECK(f2(3) == 8);
+
+  const function1<int, int> cf2(add_to);
+  BOOST_CHECK(cf2(3) == 8);
+}
+
+static void
+test_two_args()
+{
+  function2<string, const string&, const string&> cat(&string_cat);
+  BOOST_CHECK(cat("str", "ing") == "string");
+
+  function2<int, short, short> sum(&sum_ints);
+  BOOST_CHECK(sum(2, 3) == 5);
+}
+
+static void
+test_emptiness()
+{
+  function0<float> f1;
+  BOOST_CHECK(f1.empty());
+
+  function0<float> f2;
+  f2 = f1;
+  BOOST_CHECK(f2.empty());
+
+  function0<double> f3;
+  f3 = f2;
+  BOOST_CHECK(f3.empty());
+}
+
+struct X {
+  X(int v) : value(v) {}
+
+  int twice() const { return 2*value; }
+  int plus(int v) { return value + v; }
+
+  int value;
+};
+
+static void
+test_member_functions()
+{
+
+  ndnboost::function1<int, X*> f1(&X::twice);
+
+  X one(1);
+  X five(5);
+
+  BOOST_CHECK(f1(&one) == 2);
+  BOOST_CHECK(f1(&five) == 10);
+
+  ndnboost::function1<int, X*> f1_2;
+  f1_2 = &X::twice;
+
+  BOOST_CHECK(f1_2(&one) == 2);
+  BOOST_CHECK(f1_2(&five) == 10);
+
+  ndnboost::function2<int, X&, int> f2(&X::plus);
+  BOOST_CHECK(f2(one, 3) == 4);
+  BOOST_CHECK(f2(five, 4) == 9);
+}
+
+struct add_with_throw_on_copy {
+  int operator()(int x, int y) const { return x+y; }
+
+  add_with_throw_on_copy() {}
+
+  add_with_throw_on_copy(const add_with_throw_on_copy&)
+  {
+    throw std::runtime_error("But this CAN'T throw");
+  }
+
+  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
+  {
+    throw std::runtime_error("But this CAN'T throw");
+  }
+};
+
+static void
+test_ref()
+{
+  add_with_throw_on_copy atc;
+  try {
+    ndnboost::function2<int, int, int> f(ref(atc));
+    BOOST_CHECK(f(1, 3) == 4);
+  }
+  catch(std::runtime_error e) {
+    BOOST_ERROR("Nonthrowing constructor threw an exception");
+  }
+}
+
+static unsigned construction_count = 0;
+static unsigned destruction_count = 0;
+
+struct MySmallFunctor {
+  MySmallFunctor() { ++construction_count; }
+  MySmallFunctor(const MySmallFunctor &) { ++construction_count; }
+  ~MySmallFunctor() { ++destruction_count; }
+  int operator()() { return 0; }
+ };
+
+struct MyLargeFunctor {
+  MyLargeFunctor() { ++construction_count; }
+  MyLargeFunctor(const MyLargeFunctor &) { ++construction_count; }
+  ~MyLargeFunctor() { ++destruction_count; }
+  int operator()() { return 0; }
+
+  float data[128];
+ };
+
+void test_construct_destroy_count()
+{
+  {
+    ndnboost::function0<int> f;
+    ndnboost::function0<int> g;
+    f = MySmallFunctor();
+    g = MySmallFunctor();
+    f.swap(g);
+  }
+
+  // MySmallFunctor objects should be constructed as many times as
+  // they are destroyed.
+  BOOST_CHECK(construction_count == destruction_count);
+ 
+  construction_count = 0;
+  destruction_count = 0;
+  {
+    ndnboost::function0<int> f;
+    ndnboost::function0<int> g;
+    f = MyLargeFunctor();
+    g = MyLargeFunctor();
+    f.swap(g);
+   }
+
+   // MyLargeFunctor objects should be constructed as many times as
+   // they are destroyed.
+   BOOST_CHECK(construction_count == destruction_count);
+}
+
+int test_main(int, char* [])
+{
+  test_zero_args();
+  test_one_arg();
+  test_two_args();
+  test_emptiness();
+  test_member_functions();
+  test_ref();
+  test_construct_destroy_count();
+  return 0;
+}
diff --git a/libs/function/test/function_ref_cxx98.cpp b/libs/function/test/function_ref_cxx98.cpp
new file mode 100644
index 0000000..2d79c9d
--- /dev/null
+++ b/libs/function/test/function_ref_cxx98.cpp
@@ -0,0 +1,27 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+
+#include <boost/function.hpp>
+#include <iostream>
+
+
+struct stateful_type { int operator()(int) const { return 0; } };
+
+int main()
+{
+    stateful_type a_function_object;
+  ndnboost::function<int (int)> f;
+  f = ndnboost::ref(a_function_object);
+
+  ndnboost::function<int (int)> f2(f);
+
+    return 0;
+}
diff --git a/libs/function/test/function_ref_portable.cpp b/libs/function/test/function_ref_portable.cpp
new file mode 100644
index 0000000..5ac84a2
--- /dev/null
+++ b/libs/function/test/function_ref_portable.cpp
@@ -0,0 +1,27 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+
+#include <boost/function.hpp>
+#include <iostream>
+
+
+struct stateful_type { int operator()(int) const { return 0; } };
+
+int main()
+{
+    stateful_type a_function_object;
+  ndnboost::function1<int, int> f;
+  f = ndnboost::ref(a_function_object);
+
+  ndnboost::function1<int, int> f2(f);
+
+    return 0;
+}
diff --git a/libs/function/test/function_test.cpp b/libs/function/test/function_test.cpp
new file mode 100644
index 0000000..b1c7cb8
--- /dev/null
+++ b/libs/function/test/function_test.cpp
@@ -0,0 +1,798 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-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
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+#include <functional>
+#include <string>
+#include <utility>
+
+using ndnboost::function;
+using std::string;
+
+int global_int;
+
+struct write_five_obj { void operator()() const { global_int = 5; } };
+struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
+static void write_five() { global_int = 5; }
+static void write_three() { global_int = 3; }
+struct generate_five_obj { int operator()() const { return 5; } };
+struct generate_three_obj { int operator()() const { return 3; } };
+static int generate_five() { return 5; }
+static int generate_three() { return 3; }
+static string identity_str(const string& s) { return s; }
+static string string_cat(const string& s1, const string& s2) { return s1+s2; }
+static int sum_ints(int x, int y) { return x+y; }
+
+struct write_const_1_nonconst_2
+{
+  void operator()() { global_int = 2; }
+  void operator()() const { global_int = 1; }
+};
+
+struct add_to_obj
+{
+  add_to_obj(int v) : value(v) {}
+
+  int operator()(int x) const { return value + x; }
+
+  int value;
+};
+
+static void
+test_zero_args()
+{
+  typedef function<void ()> func_void_type;
+
+  write_five_obj five;
+  write_three_obj three;
+
+  // Default construction
+  func_void_type v1;
+  BOOST_CHECK(v1.empty());
+
+  // Assignment to an empty function
+  v1 = five;
+  BOOST_CHECK(v1 != 0);
+
+  // Invocation of a function
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v1.clear();
+  BOOST_CHECK(v1 == 0);
+
+  // Assignment to an empty function
+  v1 = three;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation and self-assignment
+  global_int = 0;
+  v1 = v1;
+  v1();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v1 = five;
+
+  // Invocation and self-assignment
+  global_int = 0;
+  v1 = (v1);
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // clear
+  v1 = 0;
+  BOOST_CHECK(0 == v1);
+
+  // Assignment to an empty function from a free function
+  v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
+  BOOST_CHECK(0 != v1);
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v1 = five;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v1 = &write_three;
+  BOOST_CHECK(!v1.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 3);
+
+  // Construction from another function (that is empty)
+  v1.clear();
+  func_void_type v2(v1);
+  BOOST_CHECK(!v2? true : false);
+
+  // Assignment to an empty function
+  v2 = three;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v2 = (five);
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  v2.clear();
+  BOOST_CHECK(v2.empty());
+
+  // Assignment to an empty function from a free function
+  v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
+  BOOST_CHECK(v2? true : false);
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Swapping
+  v1 = five;
+  swap(v1, v2);
+  v2();
+  BOOST_CHECK(global_int == 5);
+  v1();
+  BOOST_CHECK(global_int == 3);
+  swap(v1, v2);
+  v1.clear();
+
+  // Assignment
+  v2 = five;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v2 = &write_three;
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a function from an empty function
+  v2 = v1;
+  BOOST_CHECK(v2.empty());
+
+  // Assignment to a function from a function with a functor
+  v1 = three;
+  v2 = v1;
+  BOOST_CHECK(!v1.empty());
+  BOOST_CHECK(!v2.empty());
+
+  // Invocation
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 3);
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 3);
+
+  // Assign to a function from a function with a function
+  v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
+  v1 = v2;
+  BOOST_CHECK(!v1.empty());
+  BOOST_CHECK(!v2.empty());
+  global_int = 0;
+  v1();
+  BOOST_CHECK(global_int == 5);
+  global_int = 0;
+  v2();
+  BOOST_CHECK(global_int == 5);
+
+  // Construct a function given another function containing a function
+  func_void_type v3(v1);
+
+  // Invocation of a function
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v3.clear();
+  BOOST_CHECK(!v3? true : false);
+
+  // Assignment to an empty function
+  v3 = three;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v3 = five;
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v3.clear();
+  BOOST_CHECK(v3.empty());
+
+  // Assignment to an empty function from a free function
+  v3 = &write_five;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v3 = &write_three;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v3 = five;
+  BOOST_CHECK(!v3.empty());
+
+  // Invocation
+  global_int = 0;
+  v3();
+  BOOST_CHECK(global_int == 5);
+
+  // Construction of a function from a function containing a functor
+  func_void_type v4(v3);
+
+  // Invocation of a function
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v4.clear();
+  BOOST_CHECK(v4.empty());
+
+  // Assignment to an empty function
+  v4 = three;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v4 = five;
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v4.clear();
+  BOOST_CHECK(v4.empty());
+
+  // Assignment to an empty function from a free function
+  v4 = &write_five;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v4 = &write_three;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v4 = five;
+  BOOST_CHECK(!v4.empty());
+
+  // Invocation
+  global_int = 0;
+  v4();
+  BOOST_CHECK(global_int == 5);
+
+  // Construction of a function from a functor
+  func_void_type v5(five);
+
+  // Invocation of a function
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v5.clear();
+  BOOST_CHECK(v5.empty());
+
+  // Assignment to an empty function
+  v5 = three;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v5 = five;
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v5.clear();
+  BOOST_CHECK(v5.empty());
+
+  // Assignment to an empty function from a free function
+  v5 = &write_five;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v5 = &write_three;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v5 = five;
+  BOOST_CHECK(!v5.empty());
+
+  // Invocation
+  global_int = 0;
+  v5();
+  BOOST_CHECK(global_int == 5);
+
+  // Construction of a function from a function
+  func_void_type v6(&write_five);
+
+  // Invocation of a function
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // clear() method
+  v6.clear();
+  BOOST_CHECK(v6.empty());
+
+  // Assignment to an empty function
+  v6 = three;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment to a non-empty function
+  v6 = five;
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // clear()
+  v6.clear();
+  BOOST_CHECK(v6.empty());
+
+  // Assignment to an empty function from a free function
+  v6 = &write_five;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // Assignment to a non-empty function from a free function
+  v6 = &write_three;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 3);
+
+  // Assignment
+  v6 = five;
+  BOOST_CHECK(!v6.empty());
+
+  // Invocation
+  global_int = 0;
+  v6();
+  BOOST_CHECK(global_int == 5);
+
+  // Const vs. non-const
+  write_const_1_nonconst_2 one_or_two;
+  const function<void ()> v7(one_or_two);
+  function<void ()> v8(one_or_two);
+
+  global_int = 0;
+  v7();
+  BOOST_CHECK(global_int == 2);
+
+  global_int = 0;
+  v8();
+  BOOST_CHECK(global_int == 2);
+
+  // Test construction from 0 and comparison to 0
+  func_void_type v9(0);
+  BOOST_CHECK(v9 == 0);
+  BOOST_CHECK(0 == v9);
+
+  // Test return values
+  typedef function<int ()> func_int_type;
+  generate_five_obj gen_five;
+  generate_three_obj gen_three;
+
+  func_int_type i0(gen_five);
+
+  BOOST_CHECK(i0() == 5);
+  i0 = gen_three;
+  BOOST_CHECK(i0() == 3);
+  i0 = &generate_five;
+  BOOST_CHECK(i0() == 5);
+  i0 = &generate_three;
+  BOOST_CHECK(i0() == 3);
+  BOOST_CHECK(i0? true : false);
+  i0.clear();
+  BOOST_CHECK(!i0? true : false);
+
+  // Test return values with compatible types
+  typedef function<long ()> func_long_type;
+  func_long_type i1(gen_five);
+
+  BOOST_CHECK(i1() == 5);
+  i1 = gen_three;
+  BOOST_CHECK(i1() == 3);
+  i1 = &generate_five;
+  BOOST_CHECK(i1() == 5);
+  i1 = &generate_three;
+  BOOST_CHECK(i1() == 3);
+  BOOST_CHECK(i1? true : false);
+  i1.clear();
+  BOOST_CHECK(!i1? true : false);
+}
+
+static void
+test_one_arg()
+{
+  std::negate<int> neg;
+
+  function<int (int)> f1(neg);
+  BOOST_CHECK(f1(5) == -5);
+
+  function<string (string)> id(&identity_str);
+  BOOST_CHECK(id("str") == "str");
+
+  function<string (const char*)> id2(&identity_str);
+  BOOST_CHECK(id2("foo") == "foo");
+
+  add_to_obj add_to(5);
+  function<int (int)> f2(add_to);
+  BOOST_CHECK(f2(3) == 8);
+
+  const function<int (int)> cf2(add_to);
+  BOOST_CHECK(cf2(3) == 8);
+}
+
+static void
+test_two_args()
+{
+  function<string (const string&, const string&)> cat(&string_cat);
+  BOOST_CHECK(cat("str", "ing") == "string");
+
+  function<int (short, short)> sum(&sum_ints);
+  BOOST_CHECK(sum(2, 3) == 5);
+}
+
+static void
+test_emptiness()
+{
+  function<float ()> f1;
+  BOOST_CHECK(f1.empty());
+
+  function<float ()> f2;
+  f2 = f1;
+  BOOST_CHECK(f2.empty());
+
+  function<double ()> f3;
+  f3 = f2;
+  BOOST_CHECK(f3.empty());
+}
+
+struct X {
+  X(int v) : value(v) {}
+
+  int twice() const { return 2*value; }
+  int plus(int v) { return value + v; }
+
+  int value;
+};
+
+static void
+test_member_functions()
+{
+  ndnboost::function<int (X*)> f1(&X::twice);
+
+  X one(1);
+  X five(5);
+
+  BOOST_CHECK(f1(&one) == 2);
+  BOOST_CHECK(f1(&five) == 10);
+
+  ndnboost::function<int (X*)> f1_2;
+  f1_2 = &X::twice;
+
+  BOOST_CHECK(f1_2(&one) == 2);
+  BOOST_CHECK(f1_2(&five) == 10);
+
+  ndnboost::function<int (X&, int)> f2(&X::plus);
+  BOOST_CHECK(f2(one, 3) == 4);
+  BOOST_CHECK(f2(five, 4) == 9);
+}
+
+struct add_with_throw_on_copy {
+  int operator()(int x, int y) const { return x+y; }
+
+  add_with_throw_on_copy() {}
+
+  add_with_throw_on_copy(const add_with_throw_on_copy&)
+  {
+    throw std::runtime_error("But this CAN'T throw");
+  }
+
+  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
+  {
+    throw std::runtime_error("But this CAN'T throw");
+  }
+};
+
+static void
+test_ref()
+{
+  add_with_throw_on_copy atc;
+  try {
+    ndnboost::function<int (int, int)> f(ndnboost::ref(atc));
+    BOOST_CHECK(f(1, 3) == 4);
+  }
+  catch(std::runtime_error e) {
+    BOOST_ERROR("Nonthrowing constructor threw an exception");
+  }
+}
+
+static void dummy() {}
+
+static void test_empty_ref()
+{
+  ndnboost::function<void()> f1;
+  ndnboost::function<void()> f2(ndnboost::ref(f1));
+
+  try {
+    f2();
+    BOOST_ERROR("Exception didn't throw for reference to empty function.");
+  }
+  catch(std::runtime_error e) {}
+
+  f1 = dummy;
+
+  try {
+    f2();
+  }
+  catch(std::runtime_error e) {
+    BOOST_ERROR("Error calling referenced function.");
+  }
+}
+
+
+static void test_exception()
+{
+  ndnboost::function<int (int, int)> f;
+  try {
+    f(5, 4);
+    BOOST_CHECK(false);
+  }
+  catch(ndnboost::bad_function_call) {
+    // okay
+  }
+}
+
+typedef ndnboost::function< void * (void * reader) > reader_type;
+typedef std::pair<int, reader_type> mapped_type;
+
+static void test_implicit()
+{
+  mapped_type m;
+  m = mapped_type();
+}
+
+static void test_call_obj(ndnboost::function<int (int, int)> f)
+{
+  BOOST_CHECK(!f.empty());
+}
+
+static void test_call_cref(const ndnboost::function<int (int, int)>& f)
+{
+  BOOST_CHECK(!f.empty());
+}
+
+static void test_call()
+{
+  test_call_obj(std::plus<int>());
+  test_call_cref(std::plus<int>());
+}
+
+struct big_aggregating_structure {
+  int disable_small_objects_optimizations[32];
+    
+  big_aggregating_structure()
+  {
+    ++ global_int;
+  }
+    
+  big_aggregating_structure(const big_aggregating_structure&)
+  {
+    ++ global_int;
+  }
+
+  ~big_aggregating_structure()
+  {
+    -- global_int;
+  }
+    
+  void operator()() 
+  {
+    ++ global_int;
+  }
+
+  void operator()(int) 
+  {
+    ++ global_int;
+  }
+};
+
+template <class FunctionT>
+static void test_move_semantics() 
+{
+  typedef FunctionT f1_type;
+
+  big_aggregating_structure obj;
+  
+  f1_type f1 = obj;
+  global_int = 0;
+  f1();
+  
+  BOOST_CHECK(!f1.empty());
+  BOOST_CHECK(global_int == 1);
+  
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  // Testing rvalue constructors
+  f1_type f2(static_cast<f1_type&&>(f1));
+  BOOST_CHECK(f1.empty());
+  BOOST_CHECK(!f2.empty());
+  BOOST_CHECK(global_int == 1);
+  f2();
+  BOOST_CHECK(global_int == 2);
+  
+  f1_type f3(static_cast<f1_type&&>(f2));
+  BOOST_CHECK(f1.empty());
+  BOOST_CHECK(f2.empty());
+  BOOST_CHECK(!f3.empty());
+  BOOST_CHECK(global_int == 2);
+  f3();
+  BOOST_CHECK(global_int == 3);
+    
+  // Testing move assignment
+  f1_type f4;
+  BOOST_CHECK(f4.empty());
+  f4 = static_cast<f1_type&&>(f3);
+  BOOST_CHECK(f1.empty());
+  BOOST_CHECK(f2.empty());
+  BOOST_CHECK(f3.empty());
+  BOOST_CHECK(!f4.empty());
+  BOOST_CHECK(global_int == 3);
+  f4();
+  BOOST_CHECK(global_int == 4);
+  
+  // Testing self move assignment
+  f4 = static_cast<f1_type&&>(f4);
+  BOOST_CHECK(!f4.empty());
+  BOOST_CHECK(global_int == 4);
+
+  // Testing, that no memory leaked when assigning to nonempty function
+  f4 = obj;
+  BOOST_CHECK(!f4.empty());
+  BOOST_CHECK(global_int == 4);
+  f1_type f5 = obj;
+  BOOST_CHECK(global_int == 5);
+  f4 = static_cast<f1_type&&>(f5);
+  BOOST_CHECK(global_int == 4);
+  
+#endif  
+}
+
+int test_main(int, char* [])
+{
+  test_zero_args();
+  test_one_arg();
+  test_two_args();
+  test_emptiness();
+  test_member_functions();
+  test_ref();
+  test_empty_ref();
+  test_exception();
+  test_implicit();
+  test_call();
+  test_move_semantics<function<void()> >();
+  test_move_semantics<ndnboost::function0<void> >();
+
+  return 0;
+}
diff --git a/libs/function/test/function_test_fail1.cpp b/libs/function/test/function_test_fail1.cpp
new file mode 100644
index 0000000..d9fc804
--- /dev/null
+++ b/libs/function/test/function_test_fail1.cpp
@@ -0,0 +1,28 @@
+// Boost.Function library
+
+//  Copyright (C) Douglas Gregor 2001-2005. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+
+using namespace std;
+using namespace ndnboost;
+
+int
+test_main(int, char*[])
+{
+  function0<int> f1;
+  function0<int> f2;
+
+  if (f1 == f2) {
+  }
+
+  BOOST_ERROR("This should not have compiled.");
+
+  return 0;
+}
diff --git a/libs/function/test/function_test_fail2.cpp b/libs/function/test/function_test_fail2.cpp
new file mode 100644
index 0000000..634c04a
--- /dev/null
+++ b/libs/function/test/function_test_fail2.cpp
@@ -0,0 +1,27 @@
+// Boost.Function library
+
+//  Copyright (C) Douglas Gregor 2001-2005. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+
+using namespace std;
+using namespace ndnboost;
+
+static int bad_fn(float f) { return static_cast<int>(f); }
+
+int
+test_main(int, char*[])
+{
+  function0<int> f1;
+  f1 = bad_fn;
+
+  BOOST_ERROR("This should not have compiled.");
+
+  return 0;
+}
diff --git a/libs/function/test/function_typeof_test.cpp b/libs/function/test/function_typeof_test.cpp
new file mode 100644
index 0000000..6bd0d9d
--- /dev/null
+++ b/libs/function/test/function_typeof_test.cpp
@@ -0,0 +1,18 @@
+// Boost.Function library
+
+//  Copyright 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
+#include <boost/function/function_typeof.hpp>
+#include <boost/function.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+
+void f(ndnboost::function0<void> f, ndnboost::function0<void> g)
+{
+  BOOST_STATIC_ASSERT((ndnboost::is_same<ndnboost::function0<void>, BOOST_TYPEOF(f = g)>::value));
+}
diff --git a/libs/function/test/lambda_test.cpp b/libs/function/test/lambda_test.cpp
new file mode 100644
index 0000000..86281fa
--- /dev/null
+++ b/libs/function/test/lambda_test.cpp
@@ -0,0 +1,38 @@
+// 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
+
+#include <iostream>
+#include <cstdlib>
+
+#include <boost/test/minimal.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/function.hpp>
+
+static unsigned
+func_impl(int arg1, bool arg2, double arg3)
+{
+  using namespace std;
+  return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3));
+}
+
+int test_main(int, char*[])
+{
+  using ndnboost::function;
+  using namespace ndnboost::lambda;
+
+  function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2);
+  function <unsigned(double)>       f2 = ndnboost::lambda::bind(f1, false, _1);
+  function <unsigned()>             f3 = ndnboost::lambda::bind(f2, 4.0);
+
+  f3();
+
+  return 0;
+}
+
diff --git a/libs/function/test/mem_fun_cxx98.cpp b/libs/function/test/mem_fun_cxx98.cpp
new file mode 100644
index 0000000..c55baa4
--- /dev/null
+++ b/libs/function/test/mem_fun_cxx98.cpp
@@ -0,0 +1,37 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <functional>
+
+struct X {
+  int foo(int);
+  std::ostream& foo2(std::ostream&) const;
+};
+int X::foo(int x) { return -x; }
+std::ostream& X::foo2(std::ostream& x) const { return x; }
+
+int main()
+{
+    ndnboost::function<int (X*, int)> f;
+    ndnboost::function<std::ostream& (X*, std::ostream&)> f2;
+
+    f = &X::foo;
+    f2 = &X::foo2;
+
+    X x;
+    BOOST_TEST(f(&x, 5) == -5);
+    BOOST_TEST(f2(&x, ndnboost::ref(std::cout)) == std::cout);
+
+    return ::ndnboost::report_errors();
+}
diff --git a/libs/function/test/mem_fun_portable.cpp b/libs/function/test/mem_fun_portable.cpp
new file mode 100644
index 0000000..af8f75f
--- /dev/null
+++ b/libs/function/test/mem_fun_portable.cpp
@@ -0,0 +1,37 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <functional>
+
+struct X {
+  int foo(int);
+  std::ostream& foo2(std::ostream&) const;
+};
+int X::foo(int x) { return -x; }
+std::ostream& X::foo2(std::ostream& x) const { return x; }
+
+int main()
+{
+    ndnboost::function2<int, X*, int> f;
+    ndnboost::function2<std::ostream&, X*, std::ostream&> f2;
+
+    f = &X::foo;
+    f2 = &X::foo2;
+
+    X x;
+    BOOST_TEST(f(&x, 5) == -5);
+    BOOST_TEST(f2(&x, ndnboost::ref(std::cout)) == std::cout);
+
+    return ::ndnboost::report_errors();
+}
diff --git a/libs/function/test/nothrow_swap.cpp b/libs/function/test/nothrow_swap.cpp
new file mode 100644
index 0000000..568d05d
--- /dev/null
+++ b/libs/function/test/nothrow_swap.cpp
@@ -0,0 +1,60 @@
+// Boost.Function library
+
+//  Copyright 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
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+
+struct tried_to_copy { };
+
+struct MaybeThrowOnCopy {
+  MaybeThrowOnCopy(int value = 0) : value(value) { }
+
+  MaybeThrowOnCopy(const MaybeThrowOnCopy& other) : value(other.value) {
+    if (throwOnCopy)
+      throw tried_to_copy();
+  }
+
+  MaybeThrowOnCopy& operator=(const MaybeThrowOnCopy& other) {
+    if (throwOnCopy)
+      throw tried_to_copy();
+    value = other.value;
+    return *this;
+  }
+
+  int operator()() { return value; }
+
+  int value;
+
+  // Make sure that this function object doesn't trigger the
+  // small-object optimization in Function.
+  float padding[100];
+
+  static bool throwOnCopy;
+};
+
+bool MaybeThrowOnCopy::throwOnCopy = false;
+
+int test_main(int, char* [])
+{
+  ndnboost::function0<int> f;
+  ndnboost::function0<int> g;
+
+  MaybeThrowOnCopy::throwOnCopy = false;
+  f = MaybeThrowOnCopy(1);
+  g = MaybeThrowOnCopy(2);
+  BOOST_CHECK(f() == 1);
+  BOOST_CHECK(g() == 2);
+
+  MaybeThrowOnCopy::throwOnCopy = true;
+  f.swap(g);
+  BOOST_CHECK(f() == 2);
+  BOOST_CHECK(g() == 1);
+  
+  return 0;
+}
diff --git a/libs/function/test/regression.cfg b/libs/function/test/regression.cfg
new file mode 100644
index 0000000..7e44253
--- /dev/null
+++ b/libs/function/test/regression.cfg
@@ -0,0 +1,14 @@
+// Boost.Function regression test configuration file
+
+// From the boost/status directory, run
+// ./regression --tests ../libs/function/test/regression.cfg -o function.html
+
+
+run libs/function/test/allocator_test.cpp
+run libs/function/test/function_n_test.cpp
+run libs/function/test/function_test.cpp
+compile-fail libs/function/test/function_test_fail1.cpp
+compile-fail libs/function/test/function_test_fail2.cpp
+run libs/function/test/mixin_test.cpp
+run libs/function/test/policy_test.cpp
+run libs/function/test/stateless_test.cpp
diff --git a/libs/function/test/stateless_test.cpp b/libs/function/test/stateless_test.cpp
new file mode 100644
index 0000000..1767c7d
--- /dev/null
+++ b/libs/function/test/stateless_test.cpp
@@ -0,0 +1,38 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-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
+
+#include <boost/test/minimal.hpp>
+#include <boost/function.hpp>
+#include <stdexcept>
+
+struct stateless_integer_add {
+  int operator()(int x, int y) const { return x+y; }
+
+  void* operator new(std::size_t)
+  {
+    throw std::runtime_error("Cannot allocate a stateless_integer_add");
+  }
+
+  void* operator new(std::size_t, void* p)
+  {
+    return p;
+  }
+
+  void operator delete(void*) throw()
+  {
+  }
+};
+
+int test_main(int, char*[])
+{
+  ndnboost::function2<int, int, int> f;
+  f = stateless_integer_add();
+
+  return 0;
+}
diff --git a/libs/function/test/std_bind_cxx98.cpp b/libs/function/test/std_bind_cxx98.cpp
new file mode 100644
index 0000000..7ba3cee
--- /dev/null
+++ b/libs/function/test/std_bind_cxx98.cpp
@@ -0,0 +1,30 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <iostream>
+#include <functional>
+
+struct X {
+  int foo(int);
+};
+int X::foo(int x) { return -x; }
+
+int main()
+{
+      ndnboost::function<int (int)> f;
+  X x;
+  f = std::bind1st(
+        std::mem_fun(&X::foo), &x);
+  f(5); // Call x.foo(5)
+
+    return 0;
+}
diff --git a/libs/function/test/std_bind_portable.cpp b/libs/function/test/std_bind_portable.cpp
new file mode 100644
index 0000000..7aca746
--- /dev/null
+++ b/libs/function/test/std_bind_portable.cpp
@@ -0,0 +1,30 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <iostream>
+#include <functional>
+
+struct X {
+  int foo(int);
+};
+int X::foo(int x) { return -x; }
+
+int main()
+{
+      ndnboost::function1<int, int> f;
+  X x;
+  f = std::bind1st(
+        std::mem_fun(&X::foo), &x);
+  f(5); // Call x.foo(5)
+
+    return 0;
+}
diff --git a/libs/function/test/sum_avg_cxx98.cpp b/libs/function/test/sum_avg_cxx98.cpp
new file mode 100644
index 0000000..a49d4ea
--- /dev/null
+++ b/libs/function/test/sum_avg_cxx98.cpp
@@ -0,0 +1,28 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <iostream>
+
+void do_sum_avg(int values[], int n, int& sum, float& avg)
+{
+  sum = 0;
+  for (int i = 0; i < n; i++)
+    sum += values[i];
+  avg = (float)sum / n;
+}
+int main()
+{
+    ndnboost::function<void (int values[], int n, int& sum, float& avg)> sum_avg;
+    sum_avg = &do_sum_avg;
+
+    return 0;
+}
diff --git a/libs/function/test/sum_avg_portable.cpp b/libs/function/test/sum_avg_portable.cpp
new file mode 100644
index 0000000..76de8fe
--- /dev/null
+++ b/libs/function/test/sum_avg_portable.cpp
@@ -0,0 +1,28 @@
+// Function library
+
+// Copyright (C) 2001-2003 Douglas Gregor
+
+// 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/
+
+    
+#include <boost/function.hpp>
+#include <iostream>
+
+void do_sum_avg(int values[], int n, int& sum, float& avg)
+{
+  sum = 0;
+  for (int i = 0; i < n; i++)
+    sum += values[i];
+  avg = (float)sum / n;
+}
+int main()
+{
+    ndnboost::function4<void, int*, int, int&, float&> sum_avg;
+    sum_avg = &do_sum_avg;
+
+    return 0;
+}