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/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;
+}