diff --git a/tests/daemon/face/dummy-face.hpp b/tests/daemon/face/dummy-face.hpp
new file mode 100644
index 0000000..7039286
--- /dev/null
+++ b/tests/daemon/face/dummy-face.hpp
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_TESTS_NFD_FACE_DUMMY_FACE_HPP
+#define NFD_TESTS_NFD_FACE_DUMMY_FACE_HPP
+
+#include "face/face.hpp"
+#include "face/local-face.hpp"
+
+namespace nfd {
+namespace tests {
+
+/** \class DummyFace
+ *  \brief a Face for unit testing
+ */
+template<class FaceBase>
+class DummyFaceImpl : public FaceBase
+{
+public:
+  DummyFaceImpl()
+    : FaceBase(FaceUri("dummy://"), FaceUri("dummy://"))
+  {
+  }
+
+  virtual void
+  sendInterest(const Interest& interest)
+  {
+    this->onSendInterest(interest);
+    m_sentInterests.push_back(interest);
+    this->afterSend();
+  }
+
+  virtual void
+  sendData(const Data& data)
+  {
+    this->onSendData(data);
+    m_sentDatas.push_back(data);
+    this->afterSend();
+  }
+
+  virtual void
+  close()
+  {
+    this->onFail("close");
+  }
+
+  void
+  receiveInterest(const Interest& interest)
+  {
+    this->onReceiveInterest(interest);
+  }
+
+  void
+  receiveData(const Data& data)
+  {
+    this->onReceiveData(data);
+  }
+
+  EventEmitter<> afterSend;
+
+public:
+  std::vector<Interest> m_sentInterests;
+  std::vector<Data> m_sentDatas;
+};
+
+typedef DummyFaceImpl<Face> DummyFace;
+typedef DummyFaceImpl<LocalFace> DummyLocalFace;
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_FACE_DUMMY_FACE_HPP
diff --git a/tests/daemon/face/ethernet.cpp b/tests/daemon/face/ethernet.cpp
new file mode 100644
index 0000000..d27fda4
--- /dev/null
+++ b/tests/daemon/face/ethernet.cpp
@@ -0,0 +1,162 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face/ethernet-factory.hpp"
+#include "core/network-interface.hpp"
+#include "tests/test-common.hpp"
+
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <pcap/pcap.h>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceEthernet, BaseFixture)
+
+class InterfacesFixture : protected BaseFixture
+{
+protected:
+  InterfacesFixture()
+  {
+    std::list< shared_ptr<NetworkInterfaceInfo> > ifs = listNetworkInterfaces();
+    for (std::list< shared_ptr<NetworkInterfaceInfo> >::const_iterator i = ifs.begin();
+         i != ifs.end();
+         ++i)
+      {
+        if (!(*i)->isLoopback() && (*i)->isUp())
+          {
+            pcap_t* p = pcap_create((*i)->name.c_str(), 0);
+            if (!p)
+              continue;
+
+            if (pcap_activate(p) == 0)
+              m_interfaces.push_back(*i);
+
+            pcap_close(p);
+          }
+      }
+  }
+
+protected:
+  std::list< shared_ptr<NetworkInterfaceInfo> > m_interfaces;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(MulticastFacesMap, InterfacesFixture)
+{
+  EthernetFactory factory;
+
+  if (m_interfaces.empty())
+    {
+      BOOST_WARN_MESSAGE(false, "No interfaces available, cannot perform MulticastFacesMap test");
+      return;
+    }
+
+  shared_ptr<EthernetFace> face1;
+  BOOST_REQUIRE_NO_THROW(face1 = factory.createMulticastFace(m_interfaces.front(),
+                                                             ethernet::getBroadcastAddress()));
+  shared_ptr<EthernetFace> face1bis;
+  BOOST_REQUIRE_NO_THROW(face1bis = factory.createMulticastFace(m_interfaces.front(),
+                                                                ethernet::getBroadcastAddress()));
+  BOOST_CHECK_EQUAL(face1, face1bis);
+
+  if (m_interfaces.size() > 1)
+    {
+      shared_ptr<EthernetFace> face2;
+      BOOST_REQUIRE_NO_THROW(face2 = factory.createMulticastFace(m_interfaces.back(),
+                                                                 ethernet::getBroadcastAddress()));
+      BOOST_CHECK_NE(face1, face2);
+    }
+  else
+    {
+      BOOST_WARN_MESSAGE(false, "Cannot test second EthernetFace creation, "
+                         "only one interface available");
+    }
+
+  shared_ptr<EthernetFace> face3;
+  BOOST_REQUIRE_NO_THROW(face3 = factory.createMulticastFace(m_interfaces.front(),
+                                                             ethernet::getDefaultMulticastAddress()));
+  BOOST_CHECK_NE(face1, face3);
+}
+
+BOOST_FIXTURE_TEST_CASE(SendPacket, InterfacesFixture)
+{
+  EthernetFactory factory;
+
+  if (m_interfaces.empty())
+    {
+      BOOST_WARN_MESSAGE(false, "No interfaces available for pcap, cannot perform SendPacket test");
+      return;
+    }
+
+  shared_ptr<EthernetFace> face = factory.createMulticastFace(m_interfaces.front(),
+                                                              ethernet::getDefaultMulticastAddress());
+
+  BOOST_REQUIRE(static_cast<bool>(face));
+
+  BOOST_CHECK(!face->isOnDemand());
+  BOOST_CHECK_EQUAL(face->isLocal(), false);
+  BOOST_CHECK_EQUAL(face->getRemoteUri().toString(),
+                    "ether://" + ethernet::getDefaultMulticastAddress().toString());
+  BOOST_CHECK_EQUAL(face->getLocalUri().toString(),
+                    "dev://" + m_interfaces.front()->name);
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+
+  BOOST_CHECK_NO_THROW(face->sendInterest(interest1));
+  BOOST_CHECK_NO_THROW(face->sendData    (data1    ));
+  BOOST_CHECK_NO_THROW(face->sendInterest(interest2));
+  BOOST_CHECK_NO_THROW(face->sendData    (data2    ));
+
+//  m_ioRemaining = 4;
+//  m_ioService.run();
+//  m_ioService.reset();
+
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face2_receivedDatas    .size(), 1);
+
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data2.getName());
+//  BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
+//  BOOST_CHECK_EQUAL(m_face2_receivedDatas    [0].getName(), data1.getName());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/face/face.cpp b/tests/daemon/face/face.cpp
new file mode 100644
index 0000000..46c0345
--- /dev/null
+++ b/tests/daemon/face/face.cpp
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face/face.hpp"
+#include "face/local-face.hpp"
+#include "dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceFace, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Description)
+{
+  DummyFace face;
+  face.setDescription("3pFsKrvWr");
+  BOOST_CHECK_EQUAL(face.getDescription(), "3pFsKrvWr");
+}
+
+BOOST_AUTO_TEST_CASE(LocalControlHeaderEnabled)
+{
+  DummyLocalFace face;
+
+  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), false);
+
+  face.setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID, true);
+  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), true);
+  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID), true);
+  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(
+                         LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID), false);
+
+  face.setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID, false);
+  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), false);
+  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(
+                         LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID), false);
+}
+
+BOOST_AUTO_TEST_CASE(Counters)
+{
+  DummyFace face;
+  const FaceCounters& counters = face.getCounters();
+  BOOST_CHECK_EQUAL(counters.getNInInterests() , 0);
+  BOOST_CHECK_EQUAL(counters.getNInDatas()     , 0);
+  BOOST_CHECK_EQUAL(counters.getNOutInterests(), 0);
+  BOOST_CHECK_EQUAL(counters.getNOutDatas()    , 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/face/ndnlp.cpp b/tests/daemon/face/ndnlp.cpp
new file mode 100644
index 0000000..f5ba8e1
--- /dev/null
+++ b/tests/daemon/face/ndnlp.cpp
@@ -0,0 +1,232 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face/ndnlp-sequence-generator.hpp"
+#include "face/ndnlp-slicer.hpp"
+#include "face/ndnlp-partial-message-store.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <boost/scoped_array.hpp>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceNdnlp, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(SequenceBlock)
+{
+  ndnlp::SequenceBlock sb(0x8000, 2);
+  BOOST_CHECK_EQUAL(sb.count(), 2);
+  BOOST_CHECK_EQUAL(sb[0], 0x8000);
+  BOOST_CHECK_EQUAL(sb[1], 0x8001);
+  BOOST_CHECK_THROW(sb[2], std::out_of_range);
+}
+
+// sequence number can safely wrap around
+BOOST_AUTO_TEST_CASE(SequenceBlockWrap)
+{
+  ndnlp::SequenceBlock sb(std::numeric_limits<uint64_t>::max(), 2);
+  BOOST_CHECK_EQUAL(sb[0], std::numeric_limits<uint64_t>::max());
+  BOOST_CHECK_EQUAL(sb[1], std::numeric_limits<uint64_t>::min());
+  BOOST_CHECK_EQUAL(sb[1] - sb[0], 1);
+}
+
+BOOST_AUTO_TEST_CASE(SequenceGenerator)
+{
+  ndnlp::SequenceGenerator seqgen;
+
+  ndnlp::SequenceBlock sb1 = seqgen.nextBlock(2);
+  BOOST_CHECK_EQUAL(sb1.count(), 2);
+
+  ndnlp::SequenceBlock sb2 = seqgen.nextBlock(1);
+  BOOST_CHECK_NE(sb1[0], sb2[0]);
+  BOOST_CHECK_NE(sb1[1], sb2[0]);
+}
+
+// slice a Block to one NDNLP packet
+BOOST_AUTO_TEST_CASE(Slice1)
+{
+  uint8_t blockValue[60];
+  memset(blockValue, 0xcc, sizeof(blockValue));
+  Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
+
+  ndnlp::Slicer slicer(9000);
+  ndnlp::PacketArray pa = slicer.slice(block);
+
+  BOOST_REQUIRE_EQUAL(pa->size(), 1);
+
+  const Block& pkt = pa->at(0);
+  BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
+  pkt.parse();
+
+  const Block::element_container& elements = pkt.elements();
+  BOOST_REQUIRE_EQUAL(elements.size(), 2);
+
+  const Block& sequenceElement = elements[0];
+  BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
+  BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
+
+  const Block& payloadElement = elements[1];
+  BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
+  size_t payloadSize = payloadElement.value_size();
+  BOOST_CHECK_EQUAL(payloadSize, block.size());
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(payloadElement.value_begin(), payloadElement.value_end(),
+                                block.begin(),                block.end());
+}
+
+// slice a Block to four NDNLP packets
+BOOST_AUTO_TEST_CASE(Slice4)
+{
+  uint8_t blockValue[5050];
+  memset(blockValue, 0xcc, sizeof(blockValue));
+  Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
+
+  ndnlp::Slicer slicer(1500);
+  ndnlp::PacketArray pa = slicer.slice(block);
+
+  BOOST_REQUIRE_EQUAL(pa->size(), 4);
+
+  uint64_t seq0 = 0xdddd;
+
+  size_t totalPayloadSize = 0;
+
+  for (size_t i = 0; i < 4; ++i) {
+    const Block& pkt = pa->at(i);
+    BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
+    pkt.parse();
+
+    const Block::element_container& elements = pkt.elements();
+    BOOST_REQUIRE_EQUAL(elements.size(), 4);
+
+    const Block& sequenceElement = elements[0];
+    BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
+    BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
+    uint64_t seq = be64toh(*reinterpret_cast<const uint64_t*>(
+                             &*sequenceElement.value_begin()));
+    if (i == 0) {
+      seq0 = seq;
+    }
+    BOOST_CHECK_EQUAL(seq, seq0 + i);
+
+    const Block& fragIndexElement = elements[1];
+    BOOST_CHECK_EQUAL(fragIndexElement.type(), static_cast<uint32_t>(tlv::NdnlpFragIndex));
+    uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
+    BOOST_CHECK_EQUAL(fragIndex, i);
+
+    const Block& fragCountElement = elements[2];
+    BOOST_CHECK_EQUAL(fragCountElement.type(), static_cast<uint32_t>(tlv::NdnlpFragCount));
+    uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
+    BOOST_CHECK_EQUAL(fragCount, 4);
+
+    const Block& payloadElement = elements[3];
+    BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
+    size_t payloadSize = payloadElement.value_size();
+    totalPayloadSize += payloadSize;
+  }
+
+  BOOST_CHECK_EQUAL(totalPayloadSize, block.size());
+}
+
+class ReassembleFixture : protected BaseFixture
+{
+protected:
+  ReassembleFixture()
+    : m_slicer(1500)
+  {
+    m_partialMessageStore.onReceive +=
+      // push_back in C++11 has 2 overloads, and specific version needs to be selected
+      bind(static_cast<void (std::vector<Block>::*)(const Block&)>(&std::vector<Block>::push_back),
+           &m_received, _1);
+  }
+
+  Block
+  makeBlock(size_t valueLength)
+  {
+    boost::scoped_array<uint8_t> blockValue(new uint8_t[valueLength]);
+    memset(blockValue.get(), 0xcc, valueLength);
+    return ndn::dataBlock(0x01, blockValue.get(), valueLength);
+  }
+
+protected:
+  ndnlp::Slicer m_slicer;
+  ndnlp::PartialMessageStore m_partialMessageStore;
+
+  // received network layer packets
+  std::vector<Block> m_received;
+};
+
+// reassemble one NDNLP packets into one Block
+BOOST_FIXTURE_TEST_CASE(Reassemble1, ReassembleFixture)
+{
+  Block block = makeBlock(60);
+  ndnlp::PacketArray pa = m_slicer.slice(block);
+  BOOST_REQUIRE_EQUAL(pa->size(), 1);
+
+  BOOST_CHECK_EQUAL(m_received.size(), 0);
+  m_partialMessageStore.receiveNdnlpData(pa->at(0));
+
+  BOOST_REQUIRE_EQUAL(m_received.size(), 1);
+  BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
+                                block.begin(),            block.end());
+}
+
+// reassemble four and two NDNLP packets into two Blocks
+BOOST_FIXTURE_TEST_CASE(Reassemble4and2, ReassembleFixture)
+{
+  Block block = makeBlock(5050);
+  ndnlp::PacketArray pa = m_slicer.slice(block);
+  BOOST_REQUIRE_EQUAL(pa->size(), 4);
+
+  Block block2 = makeBlock(2000);
+  ndnlp::PacketArray pa2 = m_slicer.slice(block2);
+  BOOST_REQUIRE_EQUAL(pa2->size(), 2);
+
+  BOOST_CHECK_EQUAL(m_received.size(), 0);
+  m_partialMessageStore.receiveNdnlpData(pa->at(0));
+  BOOST_CHECK_EQUAL(m_received.size(), 0);
+  m_partialMessageStore.receiveNdnlpData(pa->at(1));
+  BOOST_CHECK_EQUAL(m_received.size(), 0);
+  m_partialMessageStore.receiveNdnlpData(pa2->at(1));
+  BOOST_CHECK_EQUAL(m_received.size(), 0);
+  m_partialMessageStore.receiveNdnlpData(pa->at(1));
+  BOOST_CHECK_EQUAL(m_received.size(), 0);
+  m_partialMessageStore.receiveNdnlpData(pa2->at(0));
+  BOOST_CHECK_EQUAL(m_received.size(), 1);
+  m_partialMessageStore.receiveNdnlpData(pa->at(3));
+  BOOST_CHECK_EQUAL(m_received.size(), 1);
+  m_partialMessageStore.receiveNdnlpData(pa->at(2));
+
+  BOOST_REQUIRE_EQUAL(m_received.size(), 2);
+  BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(1).begin(), m_received.at(1).end(),
+                                block.begin(),            block.end());
+  BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
+                                block2.begin(),           block2.end());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/face/tcp.cpp b/tests/daemon/face/tcp.cpp
new file mode 100644
index 0000000..07e6ec5
--- /dev/null
+++ b/tests/daemon/face/tcp.cpp
@@ -0,0 +1,440 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face/tcp-factory.hpp"
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
+#include "tests/test-common.hpp"
+#include "tests/limited-io.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceTcp, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(ChannelMap)
+{
+  TcpFactory factory;
+
+  shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
+
+  shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  BOOST_CHECK_NE(channel1, channel2);
+
+  shared_ptr<TcpChannel> channel3 = factory.createChannel("::1", "20071");
+  BOOST_CHECK_NE(channel2, channel3);
+  BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
+}
+
+class EndToEndFixture : protected BaseFixture
+{
+public:
+  void
+  channel1_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(face1));
+    face1 = newFace;
+    face1->onReceiveInterest +=
+      bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
+    face1->onReceiveData +=
+      bind(&EndToEndFixture::face1_onReceiveData, this, _1);
+    face1->onFail +=
+      bind(&EndToEndFixture::face1_onFail, this);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel1_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onReceiveInterest(const Interest& interest)
+  {
+    face1_receivedInterests.push_back(interest);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onReceiveData(const Data& data)
+  {
+    face1_receivedDatas.push_back(data);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onFail()
+  {
+    face1.reset();
+    limitedIo.afterOp();
+  }
+
+  void
+  channel2_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(face2));
+    face2 = newFace;
+    face2->onReceiveInterest +=
+      bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+    face2->onReceiveData +=
+      bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+    face2->onFail +=
+      bind(&EndToEndFixture::face2_onFail, this);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel2_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onReceiveInterest(const Interest& interest)
+  {
+    face2_receivedInterests.push_back(interest);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onReceiveData(const Data& data)
+  {
+    face2_receivedDatas.push_back(data);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onFail()
+  {
+    face2.reset();
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    faces.push_back(newFace);
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  checkFaceList(size_t shouldBe)
+  {
+    BOOST_CHECK_EQUAL(faces.size(), shouldBe);
+  }
+
+public:
+  LimitedIo limitedIo;
+
+  shared_ptr<Face> face1;
+  std::vector<Interest> face1_receivedInterests;
+  std::vector<Data> face1_receivedDatas;
+  shared_ptr<Face> face2;
+  std::vector<Interest> face2_receivedInterests;
+  std::vector<Data> face2_receivedDatas;
+
+  std::list< shared_ptr<Face> > faces;
+};
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
+{
+  TcpFactory factory1;
+
+  shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
+  factory1.createChannel("127.0.0.1", "20071");
+
+  BOOST_CHECK_EQUAL(channel1->isListening(), false);
+
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  BOOST_CHECK_EQUAL(channel1->isListening(), true);
+
+  TcpFactory factory2;
+
+  shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
+  factory2.createChannel("127.0.0.2", "20071");
+
+  factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
+                      bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                      bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+  BOOST_REQUIRE(static_cast<bool>(face2));
+
+  BOOST_CHECK(face1->isOnDemand());
+  BOOST_CHECK(!face2->isOnDemand());
+
+  BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp4://127.0.0.1:20070");
+  BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp4://127.0.0.1:20070");
+  // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
+
+  BOOST_CHECK_EQUAL(face1->isLocal(), true);
+  BOOST_CHECK_EQUAL(face2->isLocal(), true);
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
+  BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
+
+  // integrated tests needs to check that TcpFace for non-loopback fails these tests...
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+
+  face1->sendInterest(interest1);
+  face1->sendInterest(interest1);
+  face1->sendInterest(interest1);
+  face1->sendData    (data1    );
+  face2->sendInterest(interest2);
+  face2->sendData    (data2    );
+  face2->sendData    (data2    );
+  face2->sendData    (data2    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot send or receive Interest/Data packets");
+
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 3);
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+
+  const FaceCounters& counters1 = face1->getCounters();
+  BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
+  BOOST_CHECK_EQUAL(counters1.getNInDatas()     , 3);
+  BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
+  BOOST_CHECK_EQUAL(counters1.getNOutDatas()    , 1);
+
+  const FaceCounters& counters2 = face2->getCounters();
+  BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
+  BOOST_CHECK_EQUAL(counters2.getNInDatas()     , 1);
+  BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 1);
+  BOOST_CHECK_EQUAL(counters2.getNOutDatas()    , 3);
+}
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
+{
+  TcpFactory factory1;
+
+  shared_ptr<TcpChannel> channel1 = factory1.createChannel("::1", "20070");
+  shared_ptr<TcpChannel> channel2 = factory1.createChannel("::1", "20071");
+
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  TcpFactory factory2;
+
+  factory2.createChannel("::2", "20070");
+
+  factory2.createFace(FaceUri("tcp://[::1]:20070"),
+                      bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                      bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+  BOOST_REQUIRE(static_cast<bool>(face2));
+
+  BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp6://[::1]:20070");
+  BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp6://[::1]:20070");
+  // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
+
+  BOOST_CHECK_EQUAL(face1->isLocal(), true);
+  BOOST_CHECK_EQUAL(face2->isLocal(), true);
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
+  BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
+
+  // integrated tests needs to check that TcpFace for non-loopback fails these tests...
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+
+  face1->sendInterest(interest1);
+  face1->sendData    (data1    );
+  face2->sendInterest(interest2);
+  face2->sendData    (data2    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot send or receive Interest/Data packets");
+
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
+{
+  TcpFactory factory;
+
+  shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+
+  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
+                    time::seconds(4)); // very short timeout
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot connect or cannot accept connection");
+
+
+  BOOST_CHECK_EQUAL(faces.size(), 2);
+
+  shared_ptr<TcpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
+  channel3->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
+                    time::seconds(4)); // very short timeout
+
+
+  shared_ptr<TcpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
+
+  BOOST_CHECK_NE(channel3, channel4);
+
+  scheduler::schedule(time::seconds(1),
+      bind(&TcpChannel::connect, channel4, "127.0.0.1", "20070",
+          // does not work without static_cast
+           static_cast<TcpChannel::FaceCreatedCallback>(
+               bind(&EndToEndFixture::channel_onFaceCreated, this, _1)),
+           static_cast<TcpChannel::ConnectFailedCallback>(
+               bind(&EndToEndFixture::channel_onConnectFailed, this, _1)),
+           time::seconds(4)));
+
+  scheduler::schedule(time::milliseconds(500),
+                      bind(&EndToEndFixture::checkFaceList, this, 4));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(4,// 2 connects and 2 accepts
+                      time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot connect or cannot accept multiple connections");
+
+  BOOST_CHECK_EQUAL(faces.size(), 6);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
+{
+  TcpFactory factory;
+
+  shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
+                    time::seconds(4)); // very short timeout
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "TcpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_CHECK_EQUAL(channel1->size(), 1);
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+  BOOST_CHECK(static_cast<bool>(face2));
+
+  // Face::close must be invoked during io run to be counted as an op
+  scheduler::schedule(time::milliseconds(100), bind(&Face::close, face1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
+                      "FaceClosing error: cannot properly close faces");
+
+  // both faces should get closed
+  BOOST_CHECK(!static_cast<bool>(face1));
+  BOOST_CHECK(!static_cast<bool>(face2));
+
+  BOOST_CHECK_EQUAL(channel1->size(), 0);
+  BOOST_CHECK_EQUAL(channel2->size(), 0);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/face/udp.cpp b/tests/daemon/face/udp.cpp
new file mode 100644
index 0000000..2dfca3a
--- /dev/null
+++ b/tests/daemon/face/udp.cpp
@@ -0,0 +1,915 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face/udp-factory.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/limited-io.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceUdp, BaseFixture)
+
+class FactoryErrorCheck : protected BaseFixture
+{
+public:
+  bool isTheSameMulticastEndpoint(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP unicast channel, local "
+                  "endpoint is already allocated for a UDP multicast face") == 0;
+  }
+
+  bool isNotMulticastAddress(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, "
+                  "the multicast group given as input is not a multicast address") == 0;
+  }
+
+  bool isTheSameUnicastEndpoint(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, local "
+                  "endpoint is already allocated for a UDP unicast channel") == 0;
+  }
+
+  bool isLocalEndpointOnDifferentGroup(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, local "
+                  "endpoint is already allocated for a UDP multicast face "
+                  "on a different multicast group") == 0;
+  }
+};
+
+BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
+{
+  using boost::asio::ip::udp;
+
+  UdpFactory factory = UdpFactory();
+
+  //to instantiate multicast face on a specific ip address, change interfaceIp
+  std::string interfaceIp = "0.0.0.0";
+
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
+
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  BOOST_CHECK_NE(channel1, channel2);
+
+  shared_ptr<UdpChannel> channel3 = factory.createChannel(interfaceIp, "20070");
+
+  shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20071");
+  BOOST_CHECK_NE(channel2, channel4);
+  BOOST_CHECK_EQUAL(channel4->getUri().toString(), "udp6://[::1]:20071");
+
+  //same endpoint of a unicast channel
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "224.0.0.1",
+                                                    "20070"),
+                        UdpFactory::Error,
+                        isTheSameUnicastEndpoint);
+
+
+  shared_ptr<MulticastUdpFace> multicastFace1 = factory.createMulticastFace(interfaceIp,
+                                                                            "224.0.0.1",
+                                                                            "20072");
+  shared_ptr<MulticastUdpFace> multicastFace1a = factory.createMulticastFace(interfaceIp,
+                                                                            "224.0.0.1",
+                                                                            "20072");
+  BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
+
+
+  //same endpoint of a multicast face
+  BOOST_CHECK_EXCEPTION(factory.createChannel(interfaceIp, "20072"),
+                        UdpFactory::Error,
+                        isTheSameMulticastEndpoint);
+
+  //same multicast endpoint, different group
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "224.0.0.42",
+                                                    "20072"),
+                        UdpFactory::Error,
+                        isLocalEndpointOnDifferentGroup);
+
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "192.168.10.15",
+                                                    "20025"),
+                        UdpFactory::Error,
+                        isNotMulticastAddress);
+
+
+//  //Test commented because it required to be run in a machine that can resolve ipv6 query
+//  shared_ptr<UdpChannel> channel1v6 = factory.createChannel(//"::1",
+//                                                     "fe80::5e96:9dff:fe7d:9c8d%en1",
+//                                                     //"fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                     "20070");
+//
+//  //the creation of multicastFace2 works properly. It has been disable because it needs an IP address of
+//  //an available network interface (different from the first one used)
+//  shared_ptr<MulticastUdpFace> multicastFace2 = factory.createMulticastFace("192.168.1.17",
+//                                                                            "224.0.0.1",
+//                                                                            "20073");
+//  BOOST_CHECK_NE(multicastFace1, multicastFace2);
+//
+//
+//  //ipv6 - work in progress
+//  shared_ptr<MulticastUdpFace> multicastFace3 = factory.createMulticastFace("fe80::5e96:9dff:fe7d:9c8d%en1",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//
+//  shared_ptr<MulticastUdpFace> multicastFace4 = factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//
+//  BOOST_CHECK_EQUAL(multicastFace3, multicastFace4);
+//
+//  shared_ptr<MulticastUdpFace> multicastFace5 = factory.createMulticastFace("::1",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//
+//  BOOST_CHECK_NE(multicastFace3, multicastFace5);
+//
+//  //same local ipv6 endpoint for a different multicast group
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                "FE01:0:0:0:0:0:0:2",
+//                                                "20073"),
+//                    UdpFactory::Error);
+//
+//  //same local ipv6 (expect for th port number) endpoint for a different multicast group
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                "FE01:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+//
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
+//                                                "FE12:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+//
+//  //not a multicast ipv6
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
+//                                                "A112:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+}
+
+class EndToEndFixture : protected BaseFixture
+{
+public:
+  void
+  channel1_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(face1));
+    channel1_onFaceCreatedNoCheck(newFace);
+  }
+
+  void
+  channel1_onFaceCreatedNoCheck(const shared_ptr<Face>& newFace)
+  {
+    face1 = newFace;
+    face1->onReceiveInterest +=
+      bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
+    face1->onReceiveData +=
+      bind(&EndToEndFixture::face1_onReceiveData, this, _1);
+    face1->onFail +=
+      bind(&EndToEndFixture::face1_onFail, this);
+    BOOST_CHECK_MESSAGE(true, "channel 1 face created");
+
+    faces.push_back(face1);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel1_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onReceiveInterest(const Interest& interest)
+  {
+    face1_receivedInterests.push_back(interest);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onReceiveData(const Data& data)
+  {
+    face1_receivedDatas.push_back(data);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onFail()
+  {
+    face1.reset();
+    limitedIo.afterOp();
+  }
+
+  void
+  channel2_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(face2));
+    face2 = newFace;
+    face2->onReceiveInterest +=
+      bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+    face2->onReceiveData +=
+      bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+    face2->onFail +=
+      bind(&EndToEndFixture::face2_onFail, this);
+
+    faces.push_back(face2);
+
+    BOOST_CHECK_MESSAGE(true, "channel 2 face created");
+    limitedIo.afterOp();
+  }
+
+  void
+  channel2_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onReceiveInterest(const Interest& interest)
+  {
+    face2_receivedInterests.push_back(interest);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onReceiveData(const Data& data)
+  {
+    face2_receivedDatas.push_back(data);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onFail()
+  {
+    face2.reset();
+    limitedIo.afterOp();
+  }
+
+  void
+  channel3_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(face1));
+    face3 = newFace;
+    faces.push_back(newFace);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    faces.push_back(newFace);
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onConnectFailedOk(const std::string& reason)
+  {
+    //it's ok, it was supposed to fail
+    limitedIo.afterOp();
+  }
+
+  void
+  checkFaceList(size_t shouldBe)
+  {
+    BOOST_CHECK_EQUAL(faces.size(), shouldBe);
+  }
+
+public:
+  LimitedIo limitedIo;
+
+  shared_ptr<Face> face1;
+  std::vector<Interest> face1_receivedInterests;
+  std::vector<Data> face1_receivedDatas;
+  shared_ptr<Face> face2;
+  std::vector<Interest> face2_receivedInterests;
+  std::vector<Data> face2_receivedDatas;
+  shared_ptr<Face> face3;
+
+  std::list< shared_ptr<Face> > faces;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
+{
+  UdpFactory factory;
+
+  factory.createChannel("127.0.0.1", "20071");
+
+  factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
+                     bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                     bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_REQUIRE(static_cast<bool>(face2));
+  BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "udp4://127.0.0.1:20070");
+  BOOST_CHECK_EQUAL(face2->getLocalUri().toString(), "udp4://127.0.0.1:20071");
+  BOOST_CHECK_EQUAL(face2->isLocal(), false);
+  // face1 is not created yet
+
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+  Interest interest3("ndn:/QWiIhjgkj5sL");
+  Data     data3    ("ndn:/XNBV794f");
+  data3.setContent(0, 0);
+
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
+                                        reinterpret_cast<const uint8_t*>(0),
+                                        0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+  data3.setSignature(fakeSignature);
+
+  face2->sendInterest(interest2);
+  face2->sendData    (data2    );
+  face2->sendData    (data2    );
+  face2->sendData    (data2    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(5,//4 send + 1 listen return
+                      time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+  BOOST_CHECK_EQUAL(face1->getRemoteUri().toString(), "udp4://127.0.0.1:20071");
+  BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "udp4://127.0.0.1:20070");
+  BOOST_CHECK_EQUAL(face1->isLocal(), false);
+
+  face1->sendInterest(interest1);
+  face1->sendInterest(interest1);
+  face1->sendInterest(interest1);
+  face1->sendData    (data1    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 3);
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+
+
+
+  //checking if the connection accepting mechanism works properly.
+
+  face2->sendData    (data3    );
+  face2->sendInterest(interest3);
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 2);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 4);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[1].getName(), interest3.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [3].getName(), data3.getName());
+
+  const FaceCounters& counters1 = face1->getCounters();
+  BOOST_CHECK_EQUAL(counters1.getNInInterests() , 2);
+  BOOST_CHECK_EQUAL(counters1.getNInDatas()     , 4);
+  BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
+  BOOST_CHECK_EQUAL(counters1.getNOutDatas()    , 1);
+
+  const FaceCounters& counters2 = face2->getCounters();
+  BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
+  BOOST_CHECK_EQUAL(counters2.getNInDatas()     , 1);
+  BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 2);
+  BOOST_CHECK_EQUAL(counters2.getNOutDatas()    , 4);
+}
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
+{
+  UdpFactory factory;
+
+  factory.createChannel("::1", "20071");
+
+  factory.createFace(FaceUri("udp://[::1]:20070"),
+                     bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                     bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_REQUIRE(static_cast<bool>(face2));
+  BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "udp6://[::1]:20070");
+  BOOST_CHECK_EQUAL(face2->getLocalUri().toString(), "udp6://[::1]:20071");
+  BOOST_CHECK_EQUAL(face2->isLocal(), false);
+  // face1 is not created yet
+
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+  Interest interest3("ndn:/QWiIhjgkj5sL");
+  Data     data3    ("ndn:/XNBV794f");
+  data3.setContent(0, 0);
+
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
+                                        reinterpret_cast<const uint8_t*>(0),
+                                        0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+  data3.setSignature(fakeSignature);
+
+  face2->sendInterest(interest2);
+  face2->sendData    (data2    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(3,//2 send + 1 listen return
+                      time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+  BOOST_CHECK_EQUAL(face1->getRemoteUri().toString(), "udp6://[::1]:20071");
+  BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "udp6://[::1]:20070");
+  BOOST_CHECK_EQUAL(face1->isLocal(), false);
+
+  face1->sendInterest(interest1);
+  face1->sendData    (data1    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+
+
+
+  //checking if the connection accepting mechanism works properly.
+
+  face2->sendData    (data3    );
+  face2->sendInterest(interest3);
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 2);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 2);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[1].getName(), interest3.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [1].getName(), data3.getName());
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
+{
+  Interest interest1("ndn:/TpnzGvW9R");
+  Interest interest2("ndn:/QWiIMfj5sL");
+
+  UdpFactory factory;
+
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+
+  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_CHECK_EQUAL(faces.size(), 1);
+
+  shared_ptr<UdpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
+  channel3->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+
+  shared_ptr<UdpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
+
+  BOOST_CHECK_NE(channel3, channel4);
+
+  scheduler::schedule(time::milliseconds(500),
+           bind(&UdpChannel::connect, channel4, "127.0.0.1", "20070",
+                // does not work without static_cast
+                static_cast<UdpChannel::FaceCreatedCallback>(
+                    bind(&EndToEndFixture::channel_onFaceCreated, this, _1)),
+                static_cast<UdpChannel::ConnectFailedCallback>(
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1))));
+
+  scheduler::schedule(time::milliseconds(400), bind(&EndToEndFixture::checkFaceList, this, 2));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2,// 2 connects
+                      time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect or cannot accept multiple connections");
+
+  BOOST_CHECK_EQUAL(faces.size(), 3);
+
+
+  face2->sendInterest(interest1);
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_CHECK_EQUAL(faces.size(), 4);
+
+  face3->sendInterest(interest2);
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  //channel1 should have created 2 faces, one when face2 sent an interest, one when face3 sent an interest
+  BOOST_CHECK_EQUAL(faces.size(), 5);
+  BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,     this, _1),
+                                     bind(&EndToEndFixture::channel_onConnectFailedOk, this, _1)),
+                    UdpChannel::Error);
+}
+
+//Test commented because it required to be run in a machine that can resolve ipv6 query
+//BOOST_FIXTURE_TEST_CASE(EndToEndIpv6, EndToEndFixture)
+//{
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                              "UdpChannel error: cannot connect or cannot accept connection"));
+//
+//  limitedIoRemaining = 1;
+//
+//  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+//  shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
+//
+//  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+//                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+//
+//  channel2->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  BOOST_REQUIRE(static_cast<bool>(face2));
+//
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Data     data1    ("ndn:/KfczhUqVix");
+//  data1.setContent(0, 0);
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Data     data2    ("ndn:/XNBV796f");
+//  data2.setContent(0, 0);
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//  Data     data3    ("ndn:/XNBV794f");
+//  data3.setContent(0, 0);
+//
+//  ndn::SignatureSha256WithRsa fakeSignature;
+//  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+//
+//  // set fake signature on data1 and data2
+//  data1.setSignature(fakeSignature);
+//  data2.setSignature(fakeSignature);
+//  data3.setSignature(fakeSignature);
+//
+//  face2->sendInterest(interest2);
+//  face2->sendData    (data2    );
+//
+//  limitedIoRemaining = 3; //2 send + 1 listen return
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  BOOST_REQUIRE(static_cast<bool>(face1));
+//
+//  face1->sendInterest(interest1);
+//  face1->sendData    (data1    );
+//
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  limitedIoRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 1);
+//  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+//
+//  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+//  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+//  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+//  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+//
+//  //checking if the connection accepting mechanism works properly.
+//
+//  face2->sendData    (data3    );
+//  face2->sendInterest(interest3);
+//
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  limitedIoRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 2);
+//  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 2);
+//
+//  BOOST_CHECK_EQUAL(face1_receivedInterests[1].getName(), interest3.getName());
+//  BOOST_CHECK_EQUAL(face1_receivedDatas    [1].getName(), data3.getName());
+//
+//}
+
+
+//Test commented because it required to be run in a machine that can resolve ipv6 query
+//BOOST_FIXTURE_TEST_CASE(MultipleAcceptsIpv6, EndToEndFixture)
+//{
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(4),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot connect or cannot accept connection"));
+//
+//  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+//  shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
+//
+//  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+//                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//
+//  channel2->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//
+//  limitedIoRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  BOOST_CHECK_EQUAL(faces.size(), 1);
+//
+//  shared_ptr<UdpChannel> channel3 = factory.createChannel("::1", "20072");
+//  channel3->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//
+//  shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20073");
+//
+//  BOOST_CHECK_NE(channel3, channel4);
+//
+//  scheduler
+//  .scheduleEvent(time::milliseconds(500),
+//                 bind(&UdpChannel::connect, channel4,
+//                      "::1", "20070",
+//                      static_cast<UdpChannel::FaceCreatedCallback>(bind(&EndToEndFixture::
+//                                                                        channel_onFaceCreated, this, _1)),
+//                      static_cast<UdpChannel::ConnectFailedCallback>(bind(&EndToEndFixture::
+//                                                                          channel_onConnectFailed, this, _1))));
+//
+//  limitedIoRemaining = 2; // 2 connects
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(4),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot connect or cannot accept multiple connections"));
+//
+//  scheduler.scheduleEvent(time::seconds(0.4),
+//                          bind(&EndToEndFixture::checkFaceList, this, 2));
+//
+//  g_io.run();
+//  g_io.reset();
+//
+//  BOOST_CHECK_EQUAL(faces.size(), 3);
+//
+//
+//  face2->sendInterest(interest1);
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  limitedIoRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  BOOST_CHECK_EQUAL(faces.size(), 4);
+//
+//  face3->sendInterest(interest2);
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  limitedIoRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//
+//  //channel1 should have created 2 faces, one when face2 sent an interest, one when face3 sent an interest
+//  BOOST_CHECK_EQUAL(faces.size(), 5);
+//  BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,
+//                                          this,
+//                                          _1),
+//                                      bind(&EndToEndFixture::channel_onConnectFailedOk,
+//                                          this,
+//                                          _1)),
+//                    UdpChannel::Error);
+//}
+
+
+BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
+{
+  UdpFactory factory = UdpFactory();
+
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect or cannot accept connection");
+
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+
+  BOOST_CHECK(static_cast<bool>(face2));
+
+  // Face::close must be invoked during io run to be counted as an op
+  scheduler::schedule(time::milliseconds(100), bind(&Face::close, face2));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "FaceClosing error: cannot properly close faces");
+
+  BOOST_CHECK(!static_cast<bool>(face2));
+
+  BOOST_CHECK_EQUAL(channel2->size(), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE(ClosingIdleFace, EndToEndFixture)
+{
+  Interest interest1("ndn:/TpnzGvW9R");
+  Interest interest2("ndn:/QWiIMfj5sL");
+
+  UdpFactory factory;
+
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070",
+                                                          time::seconds(2));
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071",
+                                                          time::seconds(2));
+
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect or cannot accept connection");
+
+  face2->sendInterest(interest1);
+  BOOST_CHECK(!face2->isOnDemand());
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2,//1 send + 1 listen return
+                                      time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_CHECK_EQUAL(faces.size(), 2);
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(2)) == LimitedIo::EXCEED_TIME,
+                      "Idle face should be still open because has been used recently");
+  BOOST_CHECK_EQUAL(faces.size(), 2);
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_OPS,
+                      "Closing idle face error: face should be closed by now");
+
+  //the face on listen should be closed now
+  BOOST_CHECK_EQUAL(channel1->size(), 0);
+  //checking that face2 has not been closed
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+  BOOST_REQUIRE(static_cast<bool>(face2));
+
+  face2->sendInterest(interest2);
+  BOOST_CHECK_MESSAGE(limitedIo.run(2,//1 send + 1 listen return
+                                      time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot send or receive Interest/Data packets");
+  //channel1 should have created a new face by now
+  BOOST_CHECK_EQUAL(channel1->size(), 1);
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+  BOOST_REQUIRE(static_cast<bool>(face1));
+  BOOST_CHECK(face1->isOnDemand());
+
+  channel1->connect("127.0.0.1", "20071",
+                    bind(&EndToEndFixture::channel1_onFaceCreatedNoCheck, this, _1),
+                    bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(1,//1 connect
+                                      time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UdpChannel error: cannot connect");
+
+  BOOST_CHECK(!face1->isOnDemand());
+
+  //the connect should have set face1 as permanent face,
+  //but it shouln't have created any additional faces
+  BOOST_CHECK_EQUAL(channel1->size(), 1);
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+  BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(4)) == LimitedIo::EXCEED_TIME,
+                      "Idle face should be still open because it's permanent now");
+  //both faces are permanent, nothing should have changed
+  BOOST_CHECK_EQUAL(channel1->size(), 1);
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/face/unix-stream.cpp b/tests/daemon/face/unix-stream.cpp
new file mode 100644
index 0000000..4181aa1
--- /dev/null
+++ b/tests/daemon/face/unix-stream.cpp
@@ -0,0 +1,423 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face/unix-stream-factory.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/limited-io.hpp"
+
+namespace nfd {
+namespace tests {
+
+using namespace boost::asio::local;
+
+#define CHANNEL_PATH1 "unix-stream-test.1.sock"
+#define CHANNEL_PATH2 "unix-stream-test.2.sock"
+
+BOOST_FIXTURE_TEST_SUITE(FaceUnixStream, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(ChannelMap)
+{
+  UnixStreamFactory factory;
+
+  shared_ptr<UnixStreamChannel> channel1 = factory.createChannel(CHANNEL_PATH1);
+  shared_ptr<UnixStreamChannel> channel1a = factory.createChannel(CHANNEL_PATH1);
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  std::string channel1uri = channel1->getUri().toString();
+  BOOST_CHECK_EQUAL(channel1uri.find("unix:///"), 0); // third '/' is the path separator
+  BOOST_CHECK_EQUAL(channel1uri.rfind(CHANNEL_PATH1),
+                    channel1uri.size() - std::string(CHANNEL_PATH1).size());
+
+  shared_ptr<UnixStreamChannel> channel2 = factory.createChannel(CHANNEL_PATH2);
+  BOOST_CHECK_NE(channel1, channel2);
+}
+
+class EndToEndFixture : protected BaseFixture
+{
+public:
+  void
+  client_onConnect(const boost::system::error_code& error)
+  {
+    BOOST_CHECK_MESSAGE(!error, error.message());
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel1_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(face1));
+    face1 = static_pointer_cast<UnixStreamFace>(newFace);
+    face1->onReceiveInterest +=
+      bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
+    face1->onReceiveData +=
+      bind(&EndToEndFixture::face1_onReceiveData, this, _1);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel1_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onReceiveInterest(const Interest& interest)
+  {
+    face1_receivedInterests.push_back(interest);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face1_onReceiveData(const Data& data)
+  {
+    face1_receivedDatas.push_back(data);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onReceiveInterest(const Interest& interest)
+  {
+    face2_receivedInterests.push_back(interest);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  face2_onReceiveData(const Data& data)
+  {
+    face2_receivedDatas.push_back(data);
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    faces.push_back(static_pointer_cast<UnixStreamFace>(newFace));
+
+    limitedIo.afterOp();
+  }
+
+  void
+  channel_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    limitedIo.afterOp();
+  }
+
+protected:
+  LimitedIo limitedIo;
+
+  shared_ptr<UnixStreamFace> face1;
+  std::vector<Interest> face1_receivedInterests;
+  std::vector<Data> face1_receivedDatas;
+  shared_ptr<UnixStreamFace> face2;
+  std::vector<Interest> face2_receivedInterests;
+  std::vector<Data> face2_receivedDatas;
+
+  std::list< shared_ptr<UnixStreamFace> > faces;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
+{
+  UnixStreamFactory factory;
+
+  shared_ptr<UnixStreamChannel> channel1 = factory.createChannel(CHANNEL_PATH1);
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  shared_ptr<stream_protocol::socket> client =
+      make_shared<stream_protocol::socket>(boost::ref(g_io));
+  client->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
+                        bind(&EndToEndFixture::client_onConnect, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot connect or cannot accept connection");
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+
+  BOOST_CHECK_EQUAL(face1->getRemoteUri().getScheme(), "fd");
+  BOOST_CHECK_NO_THROW(boost::lexical_cast<int>(face1->getRemoteUri().getHost()));
+  std::string face1localUri = face1->getLocalUri().toString();
+  BOOST_CHECK_EQUAL(face1localUri.find("unix:///"), 0); // third '/' is the path separator
+  BOOST_CHECK_EQUAL(face1localUri.rfind(CHANNEL_PATH1),
+                    face1localUri.size() - std::string(CHANNEL_PATH1).size());
+
+  face2 = make_shared<UnixStreamFace>(client);
+  face2->onReceiveInterest +=
+    bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+  face2->onReceiveData +=
+    bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+
+  face1->sendInterest(interest1);
+  face1->sendInterest(interest1);
+  face1->sendInterest(interest1);
+  face1->sendData    (data1    );
+  face2->sendInterest(interest2);
+  face2->sendData    (data2    );
+  face2->sendData    (data2    );
+  face2->sendData    (data2    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 3);
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+
+  const FaceCounters& counters1 = face1->getCounters();
+  BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
+  BOOST_CHECK_EQUAL(counters1.getNInDatas()     , 3);
+  BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
+  BOOST_CHECK_EQUAL(counters1.getNOutDatas()    , 1);
+
+  const FaceCounters& counters2 = face2->getCounters();
+  BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
+  BOOST_CHECK_EQUAL(counters2.getNInDatas()     , 1);
+  BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 1);
+  BOOST_CHECK_EQUAL(counters2.getNOutDatas()    , 3);
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
+{
+  UnixStreamFactory factory;
+
+  shared_ptr<UnixStreamChannel> channel = factory.createChannel(CHANNEL_PATH1);
+  channel->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+                  bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+
+  shared_ptr<stream_protocol::socket> client1 =
+      make_shared<stream_protocol::socket>(boost::ref(g_io));
+  client1->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
+                         bind(&EndToEndFixture::client_onConnect, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot connect or cannot accept connection");
+
+  BOOST_CHECK_EQUAL(faces.size(), 1);
+
+  shared_ptr<stream_protocol::socket> client2 =
+      make_shared<stream_protocol::socket>(boost::ref(g_io));
+  client2->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
+                         bind(&EndToEndFixture::client_onConnect, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot accept multiple connections");
+
+  BOOST_CHECK_EQUAL(faces.size(), 2);
+
+  // now close one of the faces
+  faces.front()->close();
+
+  // we should still be able to send/receive with the other one
+  face1 = faces.back();
+  face1->onReceiveInterest += bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
+  face1->onReceiveData += bind(&EndToEndFixture::face1_onReceiveData, this, _1);
+
+  face2 = make_shared<UnixStreamFace>(client2);
+  face2->onReceiveInterest += bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+  face2->onReceiveData += bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+
+  face1->sendInterest(interest1);
+  face1->sendData    (data1    );
+  face2->sendInterest(interest2);
+  face2->sendData    (data2    );
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1.getName());
+}
+
+static inline void
+noOp()
+{
+}
+
+BOOST_FIXTURE_TEST_CASE(UnixStreamFaceLocalControlHeader, EndToEndFixture)
+{
+  UnixStreamFactory factory;
+
+  shared_ptr<UnixStreamChannel> channel1 = factory.createChannel(CHANNEL_PATH1);
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+
+  shared_ptr<stream_protocol::socket> client =
+      make_shared<stream_protocol::socket>(boost::ref(g_io));
+  client->async_connect(stream_protocol::endpoint(CHANNEL_PATH1),
+                        bind(&EndToEndFixture::client_onConnect, this, _1));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot connect or cannot accept connection");
+
+  BOOST_REQUIRE(static_cast<bool>(face1));
+
+  face2 = make_shared<UnixStreamFace>(client);
+  face2->onReceiveInterest +=
+    bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+  face2->onReceiveData +=
+    bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+
+  face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+  face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  BOOST_CHECK(face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  face2->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+  face2->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  BOOST_CHECK(face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  ////////////////////////////////////////////////////////
+
+  interest1.setIncomingFaceId(11);
+  interest1.setNextHopFaceId(111);
+
+  face1->sendInterest(interest1);
+
+  data1.setIncomingFaceId(22);
+  data1.getLocalControlHeader().setNextHopFaceId(222);
+
+  face1->sendData    (data1);
+
+  //
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
+
+  // sending allows only IncomingFaceId, receiving allows only NextHopFaceId
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
+  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), false);
+
+  BOOST_CHECK_EQUAL(face2_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
+  BOOST_CHECK_EQUAL(face2_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+
+  ////////////////////////////////////////////////////////
+
+  using namespace boost::asio;
+
+  std::vector<const_buffer> interestWithHeader;
+  Block iHeader  = interest1.getLocalControlHeader().wireEncode(interest1, true, true);
+  Block iPayload = interest1.wireEncode();
+  interestWithHeader.push_back(buffer(iHeader.wire(),  iHeader.size()));
+  interestWithHeader.push_back(buffer(iPayload.wire(), iPayload.size()));
+
+  std::vector<const_buffer> dataWithHeader;
+  Block dHeader  = data1.getLocalControlHeader().wireEncode(data1, true, true);
+  Block dPayload = data1.wireEncode();
+  dataWithHeader.push_back(buffer(dHeader.wire(),  dHeader.size()));
+  dataWithHeader.push_back(buffer(dPayload.wire(), dPayload.size()));
+
+  //
+
+  client->async_send(interestWithHeader, bind(&noOp));
+  client->async_send(dataWithHeader, bind(&noOp));
+
+  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
+                      "UnixStreamChannel error: cannot send or receive Interest/Data packets");
+
+  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 1);
+
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), true);
+  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getNextHopFaceId(), 111);
+
+  BOOST_CHECK_EQUAL(face1_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
+  BOOST_CHECK_EQUAL(face1_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/fw/broadcast-strategy.cpp b/tests/daemon/fw/broadcast-strategy.cpp
new file mode 100644
index 0000000..cde9b44
--- /dev/null
+++ b/tests/daemon/fw/broadcast-strategy.cpp
@@ -0,0 +1,129 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "fw/broadcast-strategy.hpp"
+#include "strategy-tester.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FwBroadcastStrategy, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Forward2)
+{
+  Forwarder forwarder;
+  typedef StrategyTester<fw::BroadcastStrategy> BroadcastStrategyTester;
+  BroadcastStrategyTester strategy(forwarder);
+
+  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+  forwarder.addFace(face3);
+
+  Fib& fib = forwarder.getFib();
+  shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
+  fibEntry->addNextHop(face1, 0);
+  fibEntry->addNextHop(face2, 0);
+  fibEntry->addNextHop(face3, 0);
+
+  shared_ptr<Interest> interest = makeInterest("ndn:/H0D6i5fc");
+  Pit& pit = forwarder.getPit();
+  shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(face3, *interest);
+
+  strategy.afterReceiveInterest(*face3, *interest, fibEntry, pitEntry);
+  BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 2);
+  bool hasFace1 = false;
+  bool hasFace2 = false;
+  for (std::vector<BroadcastStrategyTester::SendInterestArgs>::iterator it =
+       strategy.m_sendInterestHistory.begin();
+       it != strategy.m_sendInterestHistory.end(); ++it) {
+    if (it->get<1>() == face1) {
+      hasFace1 = true;
+    }
+    if (it->get<1>() == face2) {
+      hasFace2 = true;
+    }
+  }
+  BOOST_CHECK(hasFace1 && hasFace2);
+}
+
+BOOST_AUTO_TEST_CASE(RejectScope)
+{
+  Forwarder forwarder;
+  typedef StrategyTester<fw::BroadcastStrategy> BroadcastStrategyTester;
+  BroadcastStrategyTester strategy(forwarder);
+
+  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+
+  Fib& fib = forwarder.getFib();
+  shared_ptr<fib::Entry> fibEntry = fib.insert("ndn:/localhop/uS09bub6tm").first;
+  fibEntry->addNextHop(face2, 0);
+
+  shared_ptr<Interest> interest = makeInterest("ndn:/localhop/uS09bub6tm/eG3MMoP6z");
+  Pit& pit = forwarder.getPit();
+  shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(face1, *interest);
+
+  strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
+  BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(RejectLoopback)
+{
+  Forwarder forwarder;
+  typedef StrategyTester<fw::BroadcastStrategy> BroadcastStrategyTester;
+  BroadcastStrategyTester strategy(forwarder);
+
+  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+
+  Fib& fib = forwarder.getFib();
+  shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
+  fibEntry->addNextHop(face1, 0);
+
+  shared_ptr<Interest> interest = makeInterest("ndn:/H0D6i5fc");
+  Pit& pit = forwarder.getPit();
+  shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(face1, *interest);
+
+  strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
+  BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/fw/client-control-strategy.cpp b/tests/daemon/fw/client-control-strategy.cpp
new file mode 100644
index 0000000..c76fb52
--- /dev/null
+++ b/tests/daemon/fw/client-control-strategy.cpp
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "fw/client-control-strategy.hpp"
+#include "strategy-tester.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FwClientControlStrategy, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Forward3)
+{
+  Forwarder forwarder;
+  typedef StrategyTester<fw::ClientControlStrategy> ClientControlStrategyTester;
+  ClientControlStrategyTester strategy(forwarder);
+
+  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
+  shared_ptr<DummyLocalFace> face4 = make_shared<DummyLocalFace>();
+  face4->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+  forwarder.addFace(face3);
+  forwarder.addFace(face4);
+
+  Fib& fib = forwarder.getFib();
+  shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
+  fibEntry->addNextHop(face2, 0);
+
+  Pit& pit = forwarder.getPit();
+
+  // Interest with valid NextHopFaceId
+  shared_ptr<Interest> interest1 = makeInterest("ndn:/0z8r6yDDe");
+  interest1->setNextHopFaceId(face1->getId());
+  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
+  pitEntry1->insertOrUpdateInRecord(face4, *interest1);
+
+  strategy.m_sendInterestHistory.clear();
+  strategy.afterReceiveInterest(*face4, *interest1, fibEntry, pitEntry1);
+  BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[0].get<1>(), face1);
+
+  // Interest without NextHopFaceId
+  shared_ptr<Interest> interest2 = makeInterest("ndn:/y6JQADGVz");
+  shared_ptr<pit::Entry> pitEntry2 = pit.insert(*interest2).first;
+  pitEntry2->insertOrUpdateInRecord(face4, *interest2);
+
+  strategy.m_sendInterestHistory.clear();
+  strategy.afterReceiveInterest(*face4, *interest2, fibEntry, pitEntry2);
+  BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[0].get<1>(), face2);
+
+  // Interest with invalid NextHopFaceId
+  shared_ptr<Interest> interest3 = makeInterest("ndn:/0z8r6yDDe");
+  interest3->setNextHopFaceId(face3->getId());
+  shared_ptr<pit::Entry> pitEntry3 = pit.insert(*interest3).first;
+  pitEntry3->insertOrUpdateInRecord(face4, *interest3);
+
+  face3->close(); // face3 is closed and its FaceId becomes invalid
+  strategy.m_sendInterestHistory.clear();
+  strategy.m_rejectPendingInterestHistory.clear();
+  strategy.afterReceiveInterest(*face4, *interest3, fibEntry, pitEntry3);
+  BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 0);
+  BOOST_REQUIRE_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/fw/dummy-strategy.hpp b/tests/daemon/fw/dummy-strategy.hpp
new file mode 100644
index 0000000..67784fc
--- /dev/null
+++ b/tests/daemon/fw/dummy-strategy.hpp
@@ -0,0 +1,86 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_TESTS_NFD_FW_DUMMY_STRATEGY_HPP
+#define NFD_TESTS_NFD_FW_DUMMY_STRATEGY_HPP
+
+#include "fw/strategy.hpp"
+
+namespace nfd {
+namespace tests {
+
+/** \brief strategy for unit testing
+ *
+ *  Triggers on DummyStrategy are recorded but does nothing
+ */
+class DummyStrategy : public fw::Strategy
+{
+public:
+  DummyStrategy(Forwarder& forwarder, const Name& name)
+    : Strategy(forwarder, name)
+  {
+  }
+
+  virtual void
+  afterReceiveInterest(const Face& inFace,
+                       const Interest& interest,
+                       shared_ptr<fib::Entry> fibEntry,
+                       shared_ptr<pit::Entry> pitEntry)
+  {
+    ++m_afterReceiveInterest_count;
+
+    if (static_cast<bool>(m_interestOutFace)) {
+      this->sendInterest(pitEntry, m_interestOutFace);
+    }
+    else {
+      this->rejectPendingInterest(pitEntry);
+    }
+  }
+
+  virtual void
+  beforeSatisfyPendingInterest(shared_ptr<pit::Entry> pitEntry,
+                               const Face& inFace, const Data& data)
+  {
+    ++m_beforeSatisfyPendingInterest_count;
+  }
+
+  virtual void
+  beforeExpirePendingInterest(shared_ptr<pit::Entry> pitEntry)
+  {
+    ++m_beforeExpirePendingInterest_count;
+  }
+
+public:
+  int m_afterReceiveInterest_count;
+  int m_beforeSatisfyPendingInterest_count;
+  int m_beforeExpirePendingInterest_count;
+
+  /// outFace to use in afterReceiveInterest, nullptr to reject
+  shared_ptr<Face> m_interestOutFace;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_FW_DUMMY_STRATEGY_HPP
diff --git a/tests/daemon/fw/face-table.cpp b/tests/daemon/fw/face-table.cpp
new file mode 100644
index 0000000..daf9256
--- /dev/null
+++ b/tests/daemon/fw/face-table.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "fw/face-table.hpp"
+#include "fw/forwarder.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FwFaceTable, BaseFixture)
+
+static inline void
+saveFaceId(std::vector<FaceId>& faceIds, shared_ptr<Face> face)
+{
+  faceIds.push_back(face->getId());
+}
+
+BOOST_AUTO_TEST_CASE(AddRemove)
+{
+  Forwarder forwarder;
+
+  FaceTable& faceTable = forwarder.getFaceTable();
+  std::vector<FaceId> onAddHistory;
+  std::vector<FaceId> onRemoveHistory;
+  faceTable.onAdd    += bind(&saveFaceId, boost::ref(onAddHistory   ), _1);
+  faceTable.onRemove += bind(&saveFaceId, boost::ref(onRemoveHistory), _1);
+
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+
+  BOOST_CHECK_EQUAL(face1->getId(), INVALID_FACEID);
+  BOOST_CHECK_EQUAL(face2->getId(), INVALID_FACEID);
+
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+
+  BOOST_CHECK_NE(face1->getId(), INVALID_FACEID);
+  BOOST_CHECK_NE(face2->getId(), INVALID_FACEID);
+  BOOST_CHECK_NE(face1->getId(), face2->getId());
+
+  FaceId oldId1 = face1->getId();
+  faceTable.add(face1);
+  BOOST_CHECK_EQUAL(face1->getId(), oldId1);
+  BOOST_CHECK_EQUAL(faceTable.size(), 2);
+
+  BOOST_REQUIRE_EQUAL(onAddHistory.size(), 2);
+  BOOST_CHECK_EQUAL(onAddHistory[0], face1->getId());
+  BOOST_CHECK_EQUAL(onAddHistory[1], face2->getId());
+
+  face1->close();
+
+  BOOST_CHECK_EQUAL(face1->getId(), INVALID_FACEID);
+
+  BOOST_REQUIRE_EQUAL(onRemoveHistory.size(), 1);
+  BOOST_CHECK_EQUAL(onRemoveHistory[0], onAddHistory[0]);
+}
+
+BOOST_AUTO_TEST_CASE(Enumerate)
+{
+  Forwarder forwarder;
+  FaceTable& faceTable = forwarder.getFaceTable();
+
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+  bool hasFace1 = false, hasFace2 = false;
+
+  BOOST_CHECK_EQUAL(faceTable.size(), 0);
+  BOOST_CHECK_EQUAL(std::distance(faceTable.begin(), faceTable.end()), faceTable.size());
+
+  faceTable.add(face1);
+  BOOST_CHECK_EQUAL(faceTable.size(), 1);
+  BOOST_CHECK_EQUAL(std::distance(faceTable.begin(), faceTable.end()), faceTable.size());
+  hasFace1 = hasFace2 = false;
+  for (FaceTable::const_iterator it = faceTable.begin(); it != faceTable.end(); ++it) {
+    if (*it == face1) {
+      hasFace1 = true;
+    }
+  }
+  BOOST_CHECK(hasFace1);
+
+  faceTable.add(face2);
+  BOOST_CHECK_EQUAL(faceTable.size(), 2);
+  BOOST_CHECK_EQUAL(std::distance(faceTable.begin(), faceTable.end()), faceTable.size());
+  hasFace1 = hasFace2 = false;
+  for (FaceTable::const_iterator it = faceTable.begin(); it != faceTable.end(); ++it) {
+    if (*it == face1) {
+      hasFace1 = true;
+    }
+    if (*it == face2) {
+      hasFace2 = true;
+    }
+  }
+  BOOST_CHECK(hasFace1);
+  BOOST_CHECK(hasFace2);
+
+  face1->close();
+  BOOST_CHECK_EQUAL(faceTable.size(), 1);
+  BOOST_CHECK_EQUAL(std::distance(faceTable.begin(), faceTable.end()), faceTable.size());
+  hasFace1 = hasFace2 = false;
+  for (FaceTable::const_iterator it = faceTable.begin(); it != faceTable.end(); ++it) {
+    if (*it == face1) {
+      hasFace1 = true;
+    }
+    if (*it == face2) {
+      hasFace2 = true;
+    }
+  }
+  BOOST_CHECK(!hasFace1);
+  BOOST_CHECK(hasFace2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/fw/forwarder.cpp b/tests/daemon/fw/forwarder.cpp
new file mode 100644
index 0000000..0151460
--- /dev/null
+++ b/tests/daemon/fw/forwarder.cpp
@@ -0,0 +1,352 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "fw/forwarder.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+#include "dummy-strategy.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/limited-io.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FwForwarder, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(SimpleExchange)
+{
+  Forwarder forwarder;
+
+  Name nameA  ("ndn:/A");
+  Name nameAB ("ndn:/A/B");
+  Name nameABC("ndn:/A/B/C");
+  shared_ptr<Interest> interestAB = makeInterest(nameAB);
+  interestAB->setInterestLifetime(time::seconds(4));
+  shared_ptr<Data> dataABC = makeData(nameABC);
+
+  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
+  face1->afterSend += bind(&boost::asio::io_service::stop, &g_io);
+  face2->afterSend += bind(&boost::asio::io_service::stop, &g_io);
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+
+  Fib& fib = forwarder.getFib();
+  shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
+  fibEntry->addNextHop(face2, 0);
+
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 0);
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 0);
+  face1->receiveInterest(*interestAB);
+  g_io.run();
+  g_io.reset();
+  BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
+  BOOST_CHECK(face2->m_sentInterests[0].getName().equals(nameAB));
+  BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 1);
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 1);
+
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 0);
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 0);
+  face2->receiveData(*dataABC);
+  g_io.run();
+  g_io.reset();
+  BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
+  BOOST_CHECK(face1->m_sentDatas[0].getName().equals(nameABC));
+  BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 1);
+  BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 1);
+}
+
+class ScopeLocalhostIncomingTestForwarder : public Forwarder
+{
+public:
+  ScopeLocalhostIncomingTestForwarder()
+  {
+  }
+
+  virtual void
+  onDataUnsolicited(Face& inFace, const Data& data)
+  {
+    ++m_onDataUnsolicited_count;
+  }
+
+protected:
+  virtual void
+  dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> f)
+  {
+    ++m_dispatchToStrategy_count;
+  }
+
+public:
+  int m_dispatchToStrategy_count;
+  int m_onDataUnsolicited_count;
+};
+
+BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
+{
+  ScopeLocalhostIncomingTestForwarder forwarder;
+  shared_ptr<Face> face1 = make_shared<DummyLocalFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+
+  // local face, /localhost: OK
+  forwarder.m_dispatchToStrategy_count = 0;
+  shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
+  forwarder.onIncomingInterest(*face1, *i1);
+  BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
+
+  // non-local face, /localhost: violate
+  forwarder.m_dispatchToStrategy_count = 0;
+  shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
+  forwarder.onIncomingInterest(*face2, *i2);
+  BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 0);
+
+  // local face, non-/localhost: OK
+  forwarder.m_dispatchToStrategy_count = 0;
+  shared_ptr<Interest> i3 = makeInterest("/A3");
+  forwarder.onIncomingInterest(*face1, *i3);
+  BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
+
+  // non-local face, non-/localhost: OK
+  forwarder.m_dispatchToStrategy_count = 0;
+  shared_ptr<Interest> i4 = makeInterest("/A4");
+  forwarder.onIncomingInterest(*face2, *i4);
+  BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
+
+  // local face, /localhost: OK
+  forwarder.m_onDataUnsolicited_count = 0;
+  shared_ptr<Data> d1 = makeData("/localhost/B1");
+  forwarder.onIncomingData(*face1, *d1);
+  BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
+
+  // non-local face, /localhost: OK
+  forwarder.m_onDataUnsolicited_count = 0;
+  shared_ptr<Data> d2 = makeData("/localhost/B2");
+  forwarder.onIncomingData(*face2, *d2);
+  BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 0);
+
+  // local face, non-/localhost: OK
+  forwarder.m_onDataUnsolicited_count = 0;
+  shared_ptr<Data> d3 = makeData("/B3");
+  forwarder.onIncomingData(*face1, *d3);
+  BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
+
+  // non-local face, non-/localhost: OK
+  forwarder.m_onDataUnsolicited_count = 0;
+  shared_ptr<Data> d4 = makeData("/B4");
+  forwarder.onIncomingData(*face2, *d4);
+  BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
+}
+
+BOOST_AUTO_TEST_CASE(ScopeLocalhostOutgoing)
+{
+  Forwarder forwarder;
+  shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
+  shared_ptr<DummyFace>      face2 = make_shared<DummyFace>();
+  shared_ptr<Face>           face3 = make_shared<DummyLocalFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+  forwarder.addFace(face3);
+  Pit& pit = forwarder.getPit();
+
+  // local face, /localhost: OK
+  shared_ptr<Interest> interestA1 = makeInterest("/localhost/A1");
+  shared_ptr<pit::Entry> pitA1 = pit.insert(*interestA1).first;
+  pitA1->insertOrUpdateInRecord(face3, *interestA1);
+  face1->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pitA1, *face1);
+  BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
+
+  // non-local face, /localhost: violate
+  shared_ptr<Interest> interestA2 = makeInterest("/localhost/A2");
+  shared_ptr<pit::Entry> pitA2 = pit.insert(*interestA2).first;
+  pitA2->insertOrUpdateInRecord(face3, *interestA2);
+  face2->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pitA2, *face2);
+  BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 0);
+
+  // local face, non-/localhost: OK
+  shared_ptr<Interest> interestA3 = makeInterest("/A3");
+  shared_ptr<pit::Entry> pitA3 = pit.insert(*interestA3).first;
+  pitA3->insertOrUpdateInRecord(face3, *interestA3);
+  face1->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pitA3, *face1);
+  BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
+
+  // non-local face, non-/localhost: OK
+  shared_ptr<Interest> interestA4 = makeInterest("/A4");
+  shared_ptr<pit::Entry> pitA4 = pit.insert(*interestA4).first;
+  pitA4->insertOrUpdateInRecord(face3, *interestA4);
+  face2->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pitA4, *face2);
+  BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
+
+  // local face, /localhost: OK
+  face1->m_sentDatas.clear();
+  forwarder.onOutgoingData(Data("/localhost/B1"), *face1);
+  BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
+
+  // non-local face, /localhost: OK
+  face2->m_sentDatas.clear();
+  forwarder.onOutgoingData(Data("/localhost/B2"), *face2);
+  BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 0);
+
+  // local face, non-/localhost: OK
+  face1->m_sentDatas.clear();
+  forwarder.onOutgoingData(Data("/B3"), *face1);
+  BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
+
+  // non-local face, non-/localhost: OK
+  face2->m_sentDatas.clear();
+  forwarder.onOutgoingData(Data("/B4"), *face2);
+  BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(ScopeLocalhopOutgoing)
+{
+  Forwarder forwarder;
+  shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
+  shared_ptr<DummyFace>      face2 = make_shared<DummyFace>();
+  shared_ptr<DummyLocalFace> face3 = make_shared<DummyLocalFace>();
+  shared_ptr<DummyFace>      face4 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+  forwarder.addFace(face3);
+  forwarder.addFace(face4);
+  Pit& pit = forwarder.getPit();
+
+  // from local face, to local face: OK
+  shared_ptr<Interest> interest1 = makeInterest("/localhop/1");
+  shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
+  pit1->insertOrUpdateInRecord(face1, *interest1);
+  face3->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pit1, *face3);
+  BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
+
+  // from non-local face, to local face: OK
+  shared_ptr<Interest> interest2 = makeInterest("/localhop/2");
+  shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
+  pit2->insertOrUpdateInRecord(face2, *interest2);
+  face3->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pit2, *face3);
+  BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
+
+  // from local face, to non-local face: OK
+  shared_ptr<Interest> interest3 = makeInterest("/localhop/3");
+  shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
+  pit3->insertOrUpdateInRecord(face1, *interest3);
+  face4->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pit3, *face4);
+  BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
+
+  // from non-local face, to non-local face: violate
+  shared_ptr<Interest> interest4 = makeInterest("/localhop/4");
+  shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
+  pit4->insertOrUpdateInRecord(face2, *interest4);
+  face4->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pit4, *face4);
+  BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 0);
+
+  // from local face and non-local face, to local face: OK
+  shared_ptr<Interest> interest5 = makeInterest("/localhop/5");
+  shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
+  pit5->insertOrUpdateInRecord(face1, *interest5);
+  pit5->insertOrUpdateInRecord(face2, *interest5);
+  face3->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pit5, *face3);
+  BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
+
+  // from local face and non-local face, to non-local face: OK
+  shared_ptr<Interest> interest6 = makeInterest("/localhop/6");
+  shared_ptr<pit::Entry> pit6 = pit.insert(*interest6).first;
+  pit6->insertOrUpdateInRecord(face1, *interest6);
+  pit6->insertOrUpdateInRecord(face2, *interest6);
+  face4->m_sentInterests.clear();
+  forwarder.onOutgoingInterest(pit6, *face4);
+  BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(StrategyDispatch)
+{
+  LimitedIo limitedIo;
+  Forwarder forwarder;
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+
+  StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
+  shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
+                                        boost::ref(forwarder), "ndn:/strategyP");
+  shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
+                                        boost::ref(forwarder), "ndn:/strategyQ");
+  strategyChoice.install(strategyP);
+  strategyChoice.install(strategyQ);
+  strategyChoice.insert("ndn:/" , strategyP->getName());
+  strategyChoice.insert("ndn:/B", strategyQ->getName());
+
+  shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
+  strategyP->m_afterReceiveInterest_count = 0;
+  strategyP->m_interestOutFace = face2;
+  forwarder.onInterest(*face1, *interest1);
+  BOOST_CHECK_EQUAL(strategyP->m_afterReceiveInterest_count, 1);
+
+  shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
+  strategyQ->m_afterReceiveInterest_count = 0;
+  strategyQ->m_interestOutFace = face2;
+  forwarder.onInterest(*face1, *interest2);
+  BOOST_CHECK_EQUAL(strategyQ->m_afterReceiveInterest_count, 1);
+
+  limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
+
+  shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
+  strategyP->m_beforeSatisfyPendingInterest_count = 0;
+  forwarder.onData(*face2, *data1);
+  BOOST_CHECK_EQUAL(strategyP->m_beforeSatisfyPendingInterest_count, 1);
+
+  shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
+  strategyQ->m_beforeSatisfyPendingInterest_count = 0;
+  forwarder.onData(*face2, *data2);
+  BOOST_CHECK_EQUAL(strategyQ->m_beforeSatisfyPendingInterest_count, 1);
+
+  shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
+  interest3->setInterestLifetime(time::milliseconds(30));
+  forwarder.onInterest(*face1, *interest3);
+  shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
+  interest4->setInterestLifetime(time::milliseconds(5000));
+  forwarder.onInterest(*face1, *interest4);
+
+  strategyP->m_beforeExpirePendingInterest_count = 0;
+  strategyQ->m_beforeExpirePendingInterest_count = 0;
+  limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(100));
+  BOOST_CHECK_EQUAL(strategyP->m_beforeExpirePendingInterest_count, 1);
+  BOOST_CHECK_EQUAL(strategyQ->m_beforeExpirePendingInterest_count, 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/fw/ncc-strategy.cpp b/tests/daemon/fw/ncc-strategy.cpp
new file mode 100644
index 0000000..29db3b3
--- /dev/null
+++ b/tests/daemon/fw/ncc-strategy.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "fw/ncc-strategy.hpp"
+#include "strategy-tester.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+#include "tests/limited-io.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FwNccStrategy, BaseFixture)
+
+// NccStrategy is fairly complex.
+// The most important property is:
+// it remembers which upstream is the fastest to return Data,
+// and favors this upstream in subsequent Interests.
+BOOST_AUTO_TEST_CASE(FavorRespondingUpstream)
+{
+  LimitedIo limitedIo;
+  Forwarder forwarder;
+  typedef StrategyTester<fw::NccStrategy> NccStrategyTester;
+  shared_ptr<NccStrategyTester> strategy = make_shared<NccStrategyTester>(boost::ref(forwarder));
+  strategy->onAction += bind(&LimitedIo::afterOp, &limitedIo);
+
+  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
+  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+  forwarder.addFace(face3);
+
+  Fib& fib = forwarder.getFib();
+  shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
+  fibEntry->addNextHop(face1, 10);
+  fibEntry->addNextHop(face2, 20);
+
+  StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
+  strategyChoice.install(strategy);
+  strategyChoice.insert(Name(), strategy->getName());
+
+  Pit& pit = forwarder.getPit();
+
+  // first Interest: strategy knows nothing and follows routing
+  shared_ptr<Interest> interest1p = makeInterest("ndn:/0Jm1ajrW/%00");
+  Interest& interest1 = *interest1p;
+  interest1.setInterestLifetime(time::milliseconds(8000));
+  shared_ptr<pit::Entry> pitEntry1 = pit.insert(interest1).first;
+
+  pitEntry1->insertOrUpdateInRecord(face3, interest1);
+  strategy->afterReceiveInterest(*face3, interest1, fibEntry, pitEntry1);
+
+  // forwards to face1 because routing says it's best
+  limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(1));
+  BOOST_REQUIRE_EQUAL(strategy->m_sendInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(strategy->m_sendInterestHistory[0].get<1>(), face1);
+
+  // forwards to face2 because face1 doesn't respond
+  limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(500));
+  BOOST_REQUIRE_EQUAL(strategy->m_sendInterestHistory.size(), 2);
+  BOOST_CHECK_EQUAL(strategy->m_sendInterestHistory[1].get<1>(), face2);
+
+  // face2 responds
+  shared_ptr<Data> data1p = makeData("ndn:/0Jm1ajrW/%00");
+  Data& data1 = *data1p;
+  strategy->beforeSatisfyPendingInterest(pitEntry1, *face2, data1);
+  limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(500));
+
+  // second Interest: strategy knows face2 is best
+  shared_ptr<Interest> interest2p = makeInterest("ndn:/0Jm1ajrW/%00%01");
+  Interest& interest2 = *interest2p;
+  interest2.setInterestLifetime(time::milliseconds(8000));
+  shared_ptr<pit::Entry> pitEntry2 = pit.insert(interest2).first;
+
+  pitEntry2->insertOrUpdateInRecord(face3, interest2);
+  strategy->afterReceiveInterest(*face3, interest2, fibEntry, pitEntry2);
+
+  // forwards to face2 because it responds previously
+  limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(1));
+  BOOST_REQUIRE_GE(strategy->m_sendInterestHistory.size(), 3);
+  BOOST_CHECK_EQUAL(strategy->m_sendInterestHistory[2].get<1>(), face2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/fw/strategy-tester.hpp b/tests/daemon/fw/strategy-tester.hpp
new file mode 100644
index 0000000..e3debef
--- /dev/null
+++ b/tests/daemon/fw/strategy-tester.hpp
@@ -0,0 +1,89 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_TESTS_NFD_FW_STRATEGY_TESTER_HPP
+#define NFD_TESTS_NFD_FW_STRATEGY_TESTER_HPP
+
+#include <boost/tuple/tuple_comparison.hpp>
+#include "fw/strategy.hpp"
+
+namespace nfd {
+namespace tests {
+
+/** \class StrategyTester
+ *  \brief extends strategy S for unit testing
+ *
+ *  Actions invoked by S are recorded but not passed to forwarder
+ */
+template<typename S>
+class StrategyTester : public S
+{
+public:
+  explicit
+  StrategyTester(Forwarder& forwarder)
+    : S(forwarder, Name(S::STRATEGY_NAME).append("tester"))
+  {
+  }
+
+  /// fires after each Action
+  EventEmitter<> onAction;
+
+protected:
+  virtual void
+  sendInterest(shared_ptr<pit::Entry> pitEntry,shared_ptr<Face> outFace);
+
+  virtual void
+  rejectPendingInterest(shared_ptr<pit::Entry> pitEntry);
+
+public:
+  typedef boost::tuple<shared_ptr<pit::Entry>, shared_ptr<Face> > SendInterestArgs;
+  std::vector<SendInterestArgs> m_sendInterestHistory;
+
+  typedef boost::tuple<shared_ptr<pit::Entry> > RejectPendingInterestArgs;
+  std::vector<RejectPendingInterestArgs> m_rejectPendingInterestHistory;
+};
+
+
+template<typename S>
+inline void
+StrategyTester<S>::sendInterest(shared_ptr<pit::Entry> pitEntry,
+                                shared_ptr<Face> outFace)
+{
+  m_sendInterestHistory.push_back(SendInterestArgs(pitEntry, outFace));
+  pitEntry->insertOrUpdateOutRecord(outFace, pitEntry->getInterest());
+  onAction();
+}
+
+template<typename S>
+inline void
+StrategyTester<S>::rejectPendingInterest(shared_ptr<pit::Entry> pitEntry)
+{
+  m_rejectPendingInterestHistory.push_back(RejectPendingInterestArgs(pitEntry));
+  onAction();
+}
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_FW_STRATEGY_TESTER_HPP
diff --git a/tests/daemon/mgmt/command-validator.cpp b/tests/daemon/mgmt/command-validator.cpp
new file mode 100644
index 0000000..cb8031a
--- /dev/null
+++ b/tests/daemon/mgmt/command-validator.cpp
@@ -0,0 +1,600 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/command-validator.hpp"
+#include "core/config-file.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <ndn-cpp-dev/util/command-interest-generator.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+#include <boost/filesystem.hpp>
+#include <fstream>
+
+namespace nfd {
+
+namespace tests {
+
+NFD_LOG_INIT("CommandValidatorTest");
+
+BOOST_FIXTURE_TEST_SUITE(MgmtCommandValidator, BaseFixture)
+
+// authorizations
+// {
+//   authorize
+//   {
+//     certfile "tests/daemon/mgmt/cert1.ndncert"
+//     privileges
+//     {
+//       fib
+//       stats
+//     }
+//   }
+
+//   authorize
+//   {
+//     certfile "tests/daemon/mgmt/cert2.ndncert"
+//     privileges
+//     {
+//       faces
+//     }
+//   }
+// }
+
+const std::string CONFIG =
+"authorizations\n"
+"{\n"
+"  authorize\n"
+"  {\n"
+"    certfile \"tests/daemon/mgmt/cert1.ndncert\"\n"
+"    privileges\n"
+"    {\n"
+"      fib\n"
+"      stats\n"
+"    }\n"
+"  }\n"
+"  authorize\n"
+"  {\n"
+"    certfile \"tests/daemon/mgmt/cert2.ndncert\"\n"
+"    privileges\n"
+"    {\n"
+"      faces\n"
+"    }\n"
+"  }\n"
+  "}\n";
+
+const boost::filesystem::path CONFIG_PATH =
+  boost::filesystem::current_path() /= std::string("unit-test-nfd.conf");
+
+class CommandValidatorTester
+{
+public:
+
+  CommandValidatorTester()
+    : m_validated(false),
+      m_validationFailed(false)
+  {
+
+  }
+
+  void
+  generateIdentity(const Name& prefix)
+  {
+    m_identityName = prefix;
+    m_identityName.appendVersion();
+
+    const Name certName = m_keys.createIdentity(m_identityName);
+
+    m_certificate = m_keys.getCertificate(certName);
+  }
+
+  void
+  saveIdentityToFile(const char* filename)
+  {
+    std::ofstream out;
+    out.open(filename);
+
+    BOOST_REQUIRE(out.is_open());
+    BOOST_REQUIRE(static_cast<bool>(m_certificate));
+
+    ndn::io::save<ndn::IdentityCertificate>(*m_certificate, out);
+
+    out.close();
+  }
+
+  const Name&
+  getIdentityName() const
+  {
+    BOOST_REQUIRE_NE(m_identityName, Name());
+    return m_identityName;
+  }
+
+  const Name&
+  getPublicKeyName() const
+  {
+    BOOST_REQUIRE(static_cast<bool>(m_certificate));
+    return m_certificate->getPublicKeyName();
+  }
+
+  void
+  onValidated(const shared_ptr<const Interest>& interest)
+  {
+    // NFD_LOG_DEBUG("validated command");
+    m_validated = true;
+  }
+
+  void
+  onValidationFailed(const shared_ptr<const Interest>& interest, const std::string& info)
+  {
+    NFD_LOG_DEBUG("validation failed: " << info);
+    m_validationFailed = true;
+  }
+
+  bool
+  commandValidated() const
+  {
+    return m_validated;
+  }
+
+  bool
+  commandValidationFailed() const
+  {
+    return m_validationFailed;
+  }
+
+  void
+  resetValidation()
+  {
+    m_validated = false;
+    m_validationFailed = false;
+  }
+
+  ~CommandValidatorTester()
+  {
+    m_keys.deleteIdentity(m_identityName);
+  }
+
+private:
+  bool m_validated;
+  bool m_validationFailed;
+
+  ndn::KeyChain m_keys;
+  Name m_identityName;
+  shared_ptr<ndn::IdentityCertificate> m_certificate;
+};
+
+class TwoValidatorFixture : public BaseFixture
+{
+public:
+  TwoValidatorFixture()
+  {
+    m_tester1.generateIdentity("/test/CommandValidator/TwoKeys/id1");
+    m_tester1.saveIdentityToFile("tests/daemon/mgmt/cert1.ndncert");
+
+    m_tester2.generateIdentity("/test/CommandValidator/TwoKeys/id2");
+    m_tester2.saveIdentityToFile("tests/daemon/mgmt/cert2.ndncert");
+  }
+
+  ~TwoValidatorFixture()
+  {
+    boost::system::error_code error;
+    boost::filesystem::remove("tests/daemon/mgmt/cert1.ndncert", error);
+    boost::filesystem::remove("tests/daemon/mgmt/cert2.ndncert", error);
+  }
+
+protected:
+  CommandValidatorTester m_tester1;
+  CommandValidatorTester m_tester2;
+};
+
+BOOST_FIXTURE_TEST_CASE(TwoKeys, TwoValidatorFixture)
+{
+  shared_ptr<Interest> fibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
+  shared_ptr<Interest> statsCommand = make_shared<Interest>("/localhost/nfd/stats/dosomething");
+  shared_ptr<Interest> facesCommand = make_shared<Interest>("/localhost/nfd/faces/create");
+
+  ndn::CommandInterestGenerator generator;
+  generator.generateWithIdentity(*fibCommand, m_tester1.getIdentityName());
+  generator.generateWithIdentity(*statsCommand, m_tester1.getIdentityName());
+  generator.generateWithIdentity(*facesCommand, m_tester2.getIdentityName());
+
+  ConfigFile config;
+  CommandValidator validator;
+  validator.addSupportedPrivilege("faces");
+  validator.addSupportedPrivilege("fib");
+  validator.addSupportedPrivilege("stats");
+
+  validator.setConfigFile(config);
+
+  config.parse(CONFIG, false, CONFIG_PATH.native());
+
+  validator.validate(*fibCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester1), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester1), _1, _2));
+
+  BOOST_REQUIRE(m_tester1.commandValidated());
+  m_tester1.resetValidation();
+
+  validator.validate(*statsCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester1), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester1), _1, _2));
+
+  BOOST_REQUIRE(m_tester1.commandValidated());
+
+  validator.validate(*facesCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester2), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester2), _1, _2));
+
+  BOOST_REQUIRE(m_tester2.commandValidated());
+  m_tester2.resetValidation();
+
+  // use cert2 for fib command (authorized for cert1 only)
+  shared_ptr<Interest> unauthorizedFibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
+  generator.generateWithIdentity(*unauthorizedFibCommand, m_tester2.getIdentityName());
+
+  validator.validate(*unauthorizedFibCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester2), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester2), _1, _2));
+
+  BOOST_REQUIRE(m_tester2.commandValidationFailed());
+}
+
+BOOST_FIXTURE_TEST_CASE(TwoKeysDryRun, TwoValidatorFixture)
+{
+  CommandValidatorTester tester1;
+  tester1.generateIdentity("/test/CommandValidator/TwoKeys/id1");
+  tester1.saveIdentityToFile("tests/daemon/mgmt/cert1.ndncert");
+
+  CommandValidatorTester tester2;
+  tester2.generateIdentity("/test/CommandValidator/TwoKeys/id2");
+  tester2.saveIdentityToFile("tests/daemon/mgmt/cert2.ndncert");
+
+  shared_ptr<Interest> fibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
+  shared_ptr<Interest> statsCommand = make_shared<Interest>("/localhost/nfd/stats/dosomething");
+  shared_ptr<Interest> facesCommand = make_shared<Interest>("/localhost/nfd/faces/create");
+
+  ndn::CommandInterestGenerator generator;
+  generator.generateWithIdentity(*fibCommand, m_tester1.getIdentityName());
+  generator.generateWithIdentity(*statsCommand, m_tester1.getIdentityName());
+  generator.generateWithIdentity(*facesCommand, m_tester2.getIdentityName());
+
+  ConfigFile config;
+  CommandValidator validator;
+  validator.addSupportedPrivilege("faces");
+  validator.addSupportedPrivilege("fib");
+  validator.addSupportedPrivilege("stats");
+
+  validator.setConfigFile(config);
+
+  config.parse(CONFIG, true, CONFIG_PATH.native());
+
+  validator.validate(*fibCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester1), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester1), _1, _2));
+
+  BOOST_REQUIRE(m_tester1.commandValidationFailed());
+  m_tester1.resetValidation();
+
+  validator.validate(*statsCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester1), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester1), _1, _2));
+
+  BOOST_REQUIRE(m_tester1.commandValidationFailed());
+
+  validator.validate(*facesCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester2), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester2), _1, _2));
+
+  BOOST_REQUIRE(m_tester2.commandValidationFailed());
+  m_tester2.resetValidation();
+
+  // use cert2 for fib command (authorized for cert1 only)
+  shared_ptr<Interest> unauthorizedFibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
+  generator.generateWithIdentity(*unauthorizedFibCommand, m_tester2.getIdentityName());
+
+  validator.validate(*unauthorizedFibCommand,
+                     bind(&CommandValidatorTester::onValidated, boost::ref(m_tester2), _1),
+                     bind(&CommandValidatorTester::onValidationFailed, boost::ref(m_tester2), _1, _2));
+
+  BOOST_REQUIRE(m_tester2.commandValidationFailed());
+}
+
+BOOST_AUTO_TEST_CASE(NoAuthorizeSections)
+{
+  const std::string NO_AUTHORIZE_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "}\n";
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+  BOOST_CHECK_THROW(config.parse(NO_AUTHORIZE_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(NoPrivilegesSections)
+{
+  const std::string NO_PRIVILEGES_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/cert1.ndncert\"\n"
+    "  }\n"
+    "}\n";
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+
+  BOOST_CHECK_THROW(config.parse(NO_PRIVILEGES_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(InvalidCertfile)
+{
+  const std::string INVALID_CERT_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/notacertfile.ndncert\"\n"
+    "    privileges\n"
+    "    {\n"
+    "      fib\n"
+    "      stats\n"
+    "    }\n"
+    "  }\n"
+    "}\n";
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+  BOOST_CHECK_THROW(config.parse(INVALID_CERT_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(NoCertfile)
+{
+  const std::string NO_CERT_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    privileges\n"
+    "    {\n"
+    "      fib\n"
+    "      stats\n"
+    "    }\n"
+    "  }\n"
+    "}\n";
+
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+  BOOST_CHECK_THROW(config.parse(NO_CERT_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(MalformedCert)
+{
+    const std::string MALFORMED_CERT_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/malformed.ndncert\"\n"
+    "    privileges\n"
+    "    {\n"
+    "      fib\n"
+    "      stats\n"
+    "    }\n"
+    "  }\n"
+    "}\n";
+
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+  BOOST_CHECK_THROW(config.parse(MALFORMED_CERT_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
+}
+
+bool
+validateErrorMessage(const std::string& expectedMessage, const ConfigFile::Error& error)
+{
+  bool gotExpected = error.what() == expectedMessage;
+  if (!gotExpected)
+    {
+      NFD_LOG_WARN("\ncaught exception: " << error.what()
+                    << "\n\nexpected exception: " << expectedMessage);
+    }
+  return gotExpected;
+}
+
+BOOST_AUTO_TEST_CASE(NoAuthorizeSectionsDryRun)
+{
+  const std::string NO_AUTHORIZE_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "}\n";
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+  BOOST_CHECK_EXCEPTION(config.parse(NO_AUTHORIZE_CONFIG, true, CONFIG_PATH.native()),
+                        ConfigFile::Error,
+                        bind(&validateErrorMessage,
+                             "No authorize sections found", _1));
+}
+
+BOOST_FIXTURE_TEST_CASE(NoPrivilegesSectionsDryRun, TwoValidatorFixture)
+{
+  const std::string NO_PRIVILEGES_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/cert1.ndncert\"\n"
+    "  }\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/cert2.ndncert\"\n"
+    "  }\n"
+    "}\n";
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+
+  std::stringstream expectedError;
+  expectedError << "No privileges section found for certificate file tests/daemon/mgmt/cert1.ndncert "
+                << "(" << m_tester1.getPublicKeyName().toUri() << ")\n"
+                << "No privileges section found for certificate file tests/daemon/mgmt/cert2.ndncert "
+                << "(" << m_tester2.getPublicKeyName().toUri() << ")";
+
+  BOOST_CHECK_EXCEPTION(config.parse(NO_PRIVILEGES_CONFIG, true, CONFIG_PATH.native()),
+                        ConfigFile::Error,
+                        bind(&validateErrorMessage, expectedError.str(), _1));
+}
+
+BOOST_AUTO_TEST_CASE(InvalidCertfileDryRun)
+{
+  using namespace boost::filesystem;
+
+  const std::string INVALID_KEY_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/notacertfile.ndncert\"\n"
+    "    privileges\n"
+    "    {\n"
+    "      fib\n"
+    "      stats\n"
+    "    }\n"
+    "  }\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/stillnotacertfile.ndncert\"\n"
+    "    privileges\n"
+    "    {\n"
+    "    }\n"
+    "  }\n"
+    "}\n";
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+
+  std::stringstream error;
+  error << "Unable to open certificate file "
+        << absolute("tests/daemon/mgmt/notacertfile.ndncert").native() << "\n"
+        << "Unable to open certificate file "
+        << absolute("tests/daemon/mgmt/stillnotacertfile.ndncert").native();
+
+  BOOST_CHECK_EXCEPTION(config.parse(INVALID_KEY_CONFIG, true, CONFIG_PATH.native()),
+                        ConfigFile::Error,
+                        bind(&validateErrorMessage, error.str(), _1));
+}
+
+BOOST_AUTO_TEST_CASE(NoCertfileDryRun)
+{
+  const std::string NO_CERT_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    privileges\n"
+    "    {\n"
+    "      fib\n"
+    "      stats\n"
+    "    }\n"
+    "  }\n"
+    "  authorize\n"
+    "  {\n"
+    "  }\n"
+    "}\n";
+
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+  BOOST_CHECK_EXCEPTION(config.parse(NO_CERT_CONFIG, true, CONFIG_PATH.native()),
+                        ConfigFile::Error,
+                        bind(&validateErrorMessage,
+                             "No certfile specified\n"
+                             "No certfile specified", _1));
+}
+
+BOOST_AUTO_TEST_CASE(MalformedCertDryRun)
+{
+  using namespace boost::filesystem;
+
+  const std::string MALFORMED_CERT_CONFIG =
+    "authorizations\n"
+    "{\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/malformed.ndncert\"\n"
+    "    privileges\n"
+    "    {\n"
+    "      fib\n"
+    "      stats\n"
+    "    }\n"
+    "  }\n"
+    "  authorize\n"
+    "  {\n"
+    "    certfile \"tests/daemon/mgmt/malformed.ndncert\"\n"
+    "  }\n"
+    "}\n";
+
+
+  ConfigFile config;
+  CommandValidator validator;
+
+  validator.setConfigFile(config);
+
+  std::stringstream error;
+  error << "Malformed certificate file "
+        << absolute("tests/daemon/mgmt/malformed.ndncert").native() << "\n"
+        << "Malformed certificate file "
+        << absolute("tests/daemon/mgmt/malformed.ndncert").native();
+
+  BOOST_CHECK_EXCEPTION(config.parse(MALFORMED_CERT_CONFIG, true, CONFIG_PATH.native()),
+                        ConfigFile::Error,
+                        bind(&validateErrorMessage, error.str(), _1));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+
+} // namespace nfd
diff --git a/tests/daemon/mgmt/face-flags.cpp b/tests/daemon/mgmt/face-flags.cpp
new file mode 100644
index 0000000..0aa6c09
--- /dev/null
+++ b/tests/daemon/mgmt/face-flags.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/face-flags.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceFlags, BaseFixture)
+
+template<typename DummyFaceBase>
+class DummyOnDemandFace : public DummyFaceBase
+{
+public:
+  DummyOnDemandFace()
+  {
+    this->setOnDemand(true);
+  }
+};
+
+BOOST_AUTO_TEST_CASE(Get)
+{
+  DummyFace face1;
+  BOOST_CHECK_EQUAL(getFaceFlags(face1), 0);
+
+  DummyLocalFace face2;
+  BOOST_CHECK_EQUAL(getFaceFlags(face2), static_cast<uint64_t>(ndn::nfd::FACE_IS_LOCAL));
+
+  DummyOnDemandFace<DummyFace> face3;
+  BOOST_CHECK_EQUAL(getFaceFlags(face3), static_cast<uint64_t>(ndn::nfd::FACE_IS_ON_DEMAND));
+
+  DummyOnDemandFace<DummyLocalFace> face4;
+  BOOST_CHECK_EQUAL(getFaceFlags(face4), static_cast<uint64_t>(ndn::nfd::FACE_IS_LOCAL |
+                                         ndn::nfd::FACE_IS_ON_DEMAND));
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/face-manager.cpp b/tests/daemon/mgmt/face-manager.cpp
new file mode 100644
index 0000000..e799944
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager.cpp
@@ -0,0 +1,1666 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/face-manager.hpp"
+#include "mgmt/internal-face.hpp"
+#include "mgmt/face-status-publisher.hpp"
+
+#include "face/face.hpp"
+#include "../face/dummy-face.hpp"
+#include "fw/face-table.hpp"
+#include "fw/forwarder.hpp"
+
+#include "common.hpp"
+#include "tests/test-common.hpp"
+#include "validation-common.hpp"
+#include "face-status-publisher-common.hpp"
+
+#include <ndn-cpp-dev/encoding/tlv.hpp>
+#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("FaceManagerTest");
+
+class FaceManagerTestFace : public DummyFace
+{
+public:
+
+  FaceManagerTestFace()
+    : m_closeFired(false)
+  {
+
+  }
+
+  virtual
+  ~FaceManagerTestFace()
+  {
+
+  }
+
+  virtual void
+  close()
+  {
+    m_closeFired = true;
+  }
+
+  bool
+  didCloseFire() const
+  {
+    return m_closeFired;
+  }
+
+private:
+  bool m_closeFired;
+};
+
+class TestFaceTable : public FaceTable
+{
+public:
+  TestFaceTable(Forwarder& forwarder)
+    : FaceTable(forwarder),
+      m_addFired(false),
+      m_getFired(false),
+      m_dummy(make_shared<FaceManagerTestFace>())
+  {
+
+  }
+
+  virtual
+  ~TestFaceTable()
+  {
+
+  }
+
+  virtual void
+  add(shared_ptr<Face> face)
+  {
+    m_addFired = true;
+  }
+
+  virtual shared_ptr<Face>
+  get(FaceId id) const
+  {
+    m_getFired = true;
+    return m_dummy;
+  }
+
+  bool
+  didAddFire() const
+  {
+    return m_addFired;
+  }
+
+  bool
+  didGetFire() const
+  {
+    return m_getFired;
+  }
+
+  void
+  reset()
+  {
+    m_addFired = false;
+    m_getFired = false;
+  }
+
+  shared_ptr<FaceManagerTestFace>&
+  getDummyFace()
+  {
+    return m_dummy;
+  }
+
+private:
+  bool m_addFired;
+  mutable bool m_getFired;
+  shared_ptr<FaceManagerTestFace> m_dummy;
+};
+
+
+class TestFaceTableFixture : public BaseFixture
+{
+public:
+  TestFaceTableFixture()
+    : m_faceTable(m_forwarder)
+  {
+
+  }
+
+  virtual
+  ~TestFaceTableFixture()
+  {
+
+  }
+
+protected:
+  Forwarder m_forwarder;
+  TestFaceTable m_faceTable;
+};
+
+class TestFaceManagerCommon
+{
+public:
+  TestFaceManagerCommon()
+    : m_face(make_shared<InternalFace>()),
+      m_callbackFired(false)
+  {
+
+  }
+
+  virtual
+  ~TestFaceManagerCommon()
+  {
+
+  }
+
+  shared_ptr<InternalFace>&
+  getFace()
+  {
+    return m_face;
+  }
+
+  void
+  validateControlResponseCommon(const Data& response,
+                                const Name& expectedName,
+                                uint32_t expectedCode,
+                                const std::string& expectedText,
+                                ControlResponse& control)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    control.wireDecode(controlRaw);
+
+    // NFD_LOG_DEBUG("received control response"
+    //               << " Name: " << response.getName()
+    //               << " code: " << control.getCode()
+    //               << " text: " << control.getText());
+
+    BOOST_CHECK_EQUAL(response.getName(), expectedName);
+    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
+    BOOST_CHECK_EQUAL(control.getText(), expectedText);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    if (!control.getBody().empty())
+      {
+        BOOST_FAIL("found unexpected control response body");
+      }
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText,
+                          const Block& expectedBody)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    BOOST_REQUIRE(!control.getBody().empty());
+    BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
+
+    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
+                       expectedBody.value_size()) == 0);
+
+  }
+
+  bool
+  didCallbackFire() const
+  {
+    return m_callbackFired;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
+protected:
+  shared_ptr<InternalFace> m_face;
+
+private:
+  bool m_callbackFired;
+};
+
+class FaceManagerFixture : public TestFaceTableFixture, public TestFaceManagerCommon
+{
+public:
+  FaceManagerFixture()
+    : m_manager(m_faceTable, m_face)
+  {
+    m_manager.setConfigFile(m_config);
+  }
+
+  virtual
+  ~FaceManagerFixture()
+  {
+
+  }
+
+  void
+  parseConfig(const std::string configuration, bool isDryRun)
+  {
+    m_config.parse(configuration, isDryRun, "dummy-config");
+  }
+
+  FaceManager&
+  getManager()
+  {
+    return m_manager;
+  }
+
+  void
+  addInterestRule(const std::string& regex,
+                  ndn::IdentityCertificate& certificate)
+  {
+    m_manager.addInterestRule(regex, certificate);
+  }
+
+  bool
+  didFaceTableAddFire() const
+  {
+    return m_faceTable.didAddFire();
+  }
+
+  bool
+  didFaceTableGetFire() const
+  {
+    return m_faceTable.didGetFire();
+  }
+
+  void
+  resetFaceTable()
+  {
+    m_faceTable.reset();
+  }
+
+private:
+  FaceManager m_manager;
+  ConfigFile m_config;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, FaceManagerFixture)
+
+bool
+isExpectedException(const ConfigFile::Error& error, const std::string& expectedMessage)
+{
+  if (error.what() != expectedMessage)
+    {
+      NFD_LOG_ERROR("expected: " << expectedMessage << "\tgot: " << error.what());
+    }
+  return error.what() == expectedMessage;
+}
+
+#ifdef HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnix)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    listen yes\n"
+    "    path /tmp/nfd.sock\n"
+    "  }\n"
+    "}\n";
+  BOOST_TEST_CHECKPOINT("Calling parse");
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnixDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    listen yes\n"
+    "    path /var/run/nfd.sock\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnixBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"listen\" in \"unix\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnixUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"unix\" section"));
+}
+
+#endif // HAVE_UNIX_SOCKETS
+
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 6363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "  }\n"
+    "}\n";
+  try
+    {
+      parseConfig(CONFIG, false);
+    }
+  catch (const std::runtime_error& e)
+    {
+      const std::string reason = e.what();
+      if (reason.find("Address in use") != std::string::npos)
+        {
+          BOOST_FAIL(reason);
+        }
+    }
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 6363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"listen\" in \"tcp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpChannelsDisabled)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "IPv4 and IPv6 channels have been disabled."
+                             " Remove \"tcp\" section to disable TCP channels or"
+                             " re-enable at least one channel type."));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"tcp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadIdleTimeout)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    idle_timeout hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"idle_timeout\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "    mcast_port 50\n"
+    "    mcast_group hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast_group\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcastGroupV6)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "    mcast_port 50\n"
+    "    mcast_group ::1\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast_group\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpChannelsDisabled)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 no\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "IPv4 and IPv6 channels have been disabled."
+                             " Remove \"udp\" section to disable UDP channels or"
+                             " re-enable at least one channel type."));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpConflictingMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 yes\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "IPv4 multicast requested, but IPv4 channels"
+                             " have been disabled (conflicting configuration options set)"));
+}
+
+
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"udp\" section"));
+}
+
+#ifdef HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEther)
+{
+
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group 01:00:5E:00:17:AA\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group 01:00:5E:00:17:AA\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast\" in \"ether\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast_group\" in \"ether\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"ether\" section"));
+}
+
+#endif
+
+BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this,  _1,
+         command->getName(), 400, "Malformed command");
+
+  getFace()->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(MalformedCommmand)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onFaceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(UnsignedCommand)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 401, "Signature required");
+
+  getManager().onFaceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedCommandFixture<FaceManagerFixture>)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 403, "Unauthorized command");
+
+  getManager().onFaceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+template <typename T> class AuthorizedCommandFixture : public CommandFixture<T>
+{
+public:
+  AuthorizedCommandFixture()
+  {
+    const std::string regex = "^<localhost><nfd><faces>";
+    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
+  }
+
+  virtual
+  ~AuthorizedCommandFixture()
+  {
+
+  }
+};
+
+BOOST_FIXTURE_TEST_CASE(UnsupportedCommand, AuthorizedCommandFixture<FaceManagerFixture>)
+{
+  ControlParameters parameters;
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("unsupported");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 501, "Unsupported command");
+
+  getManager().onFaceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+class ValidatedFaceRequestFixture : public TestFaceTableFixture,
+                                    public TestFaceManagerCommon,
+                                    public FaceManager
+{
+public:
+
+  ValidatedFaceRequestFixture()
+    : FaceManager(TestFaceTableFixture::m_faceTable, TestFaceManagerCommon::m_face),
+      m_createFaceFired(false),
+      m_destroyFaceFired(false)
+  {
+
+  }
+
+  virtual void
+  createFace(const Interest& request,
+             ControlParameters& parameters)
+  {
+    m_createFaceFired = true;
+  }
+
+  virtual void
+  destroyFace(const Interest& request,
+              ControlParameters& parameters)
+  {
+    m_destroyFaceFired = true;
+  }
+
+  virtual
+  ~ValidatedFaceRequestFixture()
+  {
+
+  }
+
+  bool
+  didCreateFaceFire() const
+  {
+    return m_createFaceFired;
+  }
+
+  bool
+  didDestroyFaceFire() const
+  {
+    return m_destroyFaceFired;
+  }
+
+private:
+  bool m_createFaceFired;
+  bool m_destroyFaceFired;
+};
+
+BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestBadOptionParse,
+                        AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
+{
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append("NotReallyParameters");
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&ValidatedFaceRequestFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  onValidatedFaceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestCreateFace,
+                        AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  onValidatedFaceRequest(command);
+  BOOST_CHECK(didCreateFaceFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestDestroyFace,
+                        AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("destroy");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  onValidatedFaceRequest(command);
+  BOOST_CHECK(didDestroyFaceFire());
+}
+
+class FaceTableFixture
+{
+public:
+  FaceTableFixture()
+    : m_faceTable(m_forwarder)
+  {
+  }
+
+  virtual
+  ~FaceTableFixture()
+  {
+  }
+
+protected:
+  Forwarder m_forwarder;
+  FaceTable m_faceTable;
+};
+
+class LocalControlFixture : public FaceTableFixture,
+                            public TestFaceManagerCommon,
+                            public FaceManager
+{
+public:
+  LocalControlFixture()
+    : FaceManager(FaceTableFixture::m_faceTable, TestFaceManagerCommon::m_face)
+  {
+  }
+};
+
+BOOST_FIXTURE_TEST_CASE(LocalControlInFaceId,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
+  BOOST_REQUIRE(dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setLocalControlFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 200, "Success", encodedParameters);
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  disable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(disable));
+  disableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 200, "Success", encodedParameters);
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+}
+
+BOOST_FIXTURE_TEST_CASE(LocalControlInFaceIdFaceNotFound,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
+  BOOST_REQUIRE(dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setLocalControlFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId() + 100);
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 410, "Face not found");
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  disable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(disable));
+  disableCommand->setIncomingFaceId(dummy->getId() + 100);
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 410, "Face not found");
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+}
+
+BOOST_FIXTURE_TEST_CASE(LocalControlMissingFeature,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
+  BOOST_REQUIRE(dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 400, "Malformed command");
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  disable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(disable));
+  disableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 400, "Malformed command");
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+}
+
+BOOST_FIXTURE_TEST_CASE(LocalControlInFaceIdNonLocal,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<DummyFace> dummy = make_shared<DummyFace>();
+  BOOST_REQUIRE(!dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setLocalControlFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 412, "Face is non-local");
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(enable));
+  disableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 412, "Face is non-local");
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(LocalControlNextHopFaceId,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
+  BOOST_REQUIRE(dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setLocalControlFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 200, "Success", encodedParameters);
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  disable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(disable));
+  disableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 200, "Success", encodedParameters);
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+}
+
+BOOST_FIXTURE_TEST_CASE(LocalControlNextHopFaceIdFaceNotFound,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<LocalFace> dummy = make_shared<DummyLocalFace>();
+  BOOST_REQUIRE(dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setLocalControlFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId() + 100);
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 410, "Face not found");
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  disable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(disable));
+  disableCommand->setIncomingFaceId(dummy->getId() + 100);
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 410, "Face not found");
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+  BOOST_CHECK(!dummy->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+}
+
+BOOST_FIXTURE_TEST_CASE(LocalControlNextHopFaceIdNonLocal,
+                        AuthorizedCommandFixture<LocalControlFixture>)
+{
+  shared_ptr<DummyFace> dummy = make_shared<DummyFace>();
+  BOOST_REQUIRE(!dummy->isLocal());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setLocalControlFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name enable("/localhost/nfd/faces/enable-local-control");
+  enable.append(encodedParameters);
+
+  shared_ptr<Interest> enableCommand(make_shared<Interest>(enable));
+  enableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*enableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         enableCommand->getName(), 412, "Face is non-local");
+
+  onValidatedFaceRequest(enableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  TestFaceManagerCommon::m_face->onReceiveData.clear();
+  resetCallbackFired();
+
+  Name disable("/localhost/nfd/faces/disable-local-control");
+  disable.append(encodedParameters);
+
+  shared_ptr<Interest> disableCommand(make_shared<Interest>(disable));
+  disableCommand->setIncomingFaceId(dummy->getId());
+
+  generateCommand(*disableCommand);
+
+  TestFaceManagerCommon::m_face->onReceiveData +=
+    bind(&LocalControlFixture::validateControlResponse, this, _1,
+         disableCommand->getName(), 412, "Face is non-local");
+
+  onValidatedFaceRequest(disableCommand);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+class FaceFixture : public FaceTableFixture,
+                    public TestFaceManagerCommon,
+                    public FaceManager
+{
+public:
+  FaceFixture()
+    : FaceManager(FaceTableFixture::m_faceTable,
+                  TestFaceManagerCommon::m_face)
+    , m_receivedNotification(false)
+  {
+
+  }
+
+  virtual
+  ~FaceFixture()
+  {
+
+  }
+
+  void
+  callbackDispatch(const Data& response,
+                   const Name& expectedName,
+                   uint32_t expectedCode,
+                   const std::string& expectedText,
+                   const Block& expectedBody,
+                   const ndn::nfd::FaceEventNotification& expectedFaceEvent)
+  {
+    Block payload = response.getContent().blockFromValue();
+    if (payload.type() == ndn::tlv::nfd::ControlResponse)
+      {
+        validateControlResponse(response, expectedName, expectedCode,
+                                expectedText, expectedBody);
+      }
+    else if (payload.type() == ndn::tlv::nfd::FaceEventNotification)
+      {
+        validateFaceEvent(payload, expectedFaceEvent);
+      }
+    else
+      {
+        BOOST_FAIL("Received unknown message type: #" << payload.type());
+      }
+  }
+
+  void
+  callbackDispatch(const Data& response,
+                   const Name& expectedName,
+                   uint32_t expectedCode,
+                   const std::string& expectedText,
+                   const ndn::nfd::FaceEventNotification& expectedFaceEvent)
+  {
+    Block payload = response.getContent().blockFromValue();
+    if (payload.type() == ndn::tlv::nfd::ControlResponse)
+      {
+        validateControlResponse(response, expectedName,
+                                expectedCode, expectedText);
+      }
+    else if (payload.type() == ndn::tlv::nfd::FaceEventNotification)
+      {
+        validateFaceEvent(payload, expectedFaceEvent);
+      }
+    else
+      {
+        BOOST_FAIL("Received unknown message type: #" << payload.type());
+      }
+  }
+
+  void
+  validateFaceEvent(const Block& wire,
+                    const ndn::nfd::FaceEventNotification& expectedFaceEvent)
+  {
+
+    m_receivedNotification = true;
+
+    ndn::nfd::FaceEventNotification notification(wire);
+
+    BOOST_CHECK_EQUAL(notification.getKind(), expectedFaceEvent.getKind());
+    BOOST_CHECK_EQUAL(notification.getFaceId(), expectedFaceEvent.getFaceId());
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), expectedFaceEvent.getRemoteUri());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), expectedFaceEvent.getLocalUri());
+  }
+
+  bool
+  didReceiveNotication() const
+  {
+    return m_receivedNotification;
+  }
+
+protected:
+  bool m_receivedNotification;
+};
+
+BOOST_FIXTURE_TEST_CASE(CreateFaceBadUri, AuthorizedCommandFixture<FaceFixture>)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp:/127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  createFace(*command, parameters);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(CreateFaceMissingUri, AuthorizedCommandFixture<FaceFixture>)
+{
+  ControlParameters parameters;
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  createFace(*command, parameters);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(CreateFaceUnknownScheme, AuthorizedCommandFixture<FaceFixture>)
+{
+  ControlParameters parameters;
+  // this will be an unsupported protocol because no factories have been
+  // added to the face manager
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         command->getName(), 501, "Unsupported protocol");
+
+  createFace(*command, parameters);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(OnCreated, AuthorizedCommandFixture<FaceFixture>)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  ControlParameters resultParameters;
+  resultParameters.setUri("tcp://127.0.0.1");
+  resultParameters.setFaceId(1);
+
+  shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
+
+  ndn::nfd::FaceEventNotification expectedFaceEvent;
+  expectedFaceEvent.setKind(ndn::nfd::FACE_EVENT_CREATED)
+                   .setFaceId(1)
+                   .setRemoteUri(dummy->getRemoteUri().toString())
+                   .setLocalUri(dummy->getLocalUri().toString())
+                   .setFlags(0);
+
+  Block encodedResultParameters(resultParameters.wireEncode());
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::callbackDispatch, this, _1,
+         command->getName(), 200, "Success",
+         encodedResultParameters, expectedFaceEvent);
+
+  onCreated(command->getName(), parameters, dummy);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(didReceiveNotication());
+}
+
+BOOST_FIXTURE_TEST_CASE(OnConnectFailed, AuthorizedCommandFixture<FaceFixture>)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://127.0.0.1");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         command->getName(), 408, "unit-test-reason");
+
+  onConnectFailed(command->getName(), "unit-test-reason");
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_CHECK_EQUAL(didReceiveNotication(), false);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(DestroyFace, AuthorizedCommandFixture<FaceFixture>)
+{
+  shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
+  FaceTableFixture::m_faceTable.add(dummy);
+
+  ControlParameters parameters;
+  parameters.setFaceId(dummy->getId());
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("destroy");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  ndn::nfd::FaceEventNotification expectedFaceEvent;
+  expectedFaceEvent.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
+                   .setFaceId(dummy->getId())
+                   .setRemoteUri(dummy->getRemoteUri().toString())
+                   .setLocalUri(dummy->getLocalUri().toString())
+                   .setFlags(0);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::callbackDispatch, this, _1,
+         command->getName(), 200, "Success", boost::ref(encodedParameters), expectedFaceEvent);
+
+  destroyFace(*command, parameters);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(didReceiveNotication());
+}
+
+class FaceListFixture : public FaceStatusPublisherFixture
+{
+public:
+  FaceListFixture()
+    : m_manager(m_table, m_face)
+  {
+
+  }
+
+  virtual
+  ~FaceListFixture()
+  {
+
+  }
+
+protected:
+  FaceManager m_manager;
+};
+
+BOOST_FIXTURE_TEST_CASE(TestFaceList, FaceListFixture)
+
+{
+  Name commandName("/localhost/nfd/faces/list");
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  // MAX_SEGMENT_SIZE == 4400, FaceStatus size with filler counters is 55
+  // 55 divides 4400 (== 80), so only use 79 FaceStatuses and then two smaller ones
+  // to force a FaceStatus to span Data packets
+  for (int i = 0; i < 79; i++)
+    {
+      shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
+
+      uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
+      dummy->setCounters(filler, filler, filler, filler);
+
+      m_referenceFaces.push_back(dummy);
+
+      add(dummy);
+    }
+
+  for (int i = 0; i < 2; i++)
+    {
+      shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
+      uint64_t filler = std::numeric_limits<uint32_t>::max() - 1;
+      dummy->setCounters(filler, filler, filler, filler);
+
+      m_referenceFaces.push_back(dummy);
+
+      add(dummy);
+    }
+
+  ndn::EncodingBuffer buffer;
+
+  m_face->onReceiveData +=
+    bind(&FaceStatusPublisherFixture::decodeFaceStatusBlock, this, _1);
+
+  m_manager.listFaces(*command);
+  BOOST_REQUIRE(m_finished);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/face-status-publisher-common.hpp b/tests/daemon/mgmt/face-status-publisher-common.hpp
new file mode 100644
index 0000000..11ed191
--- /dev/null
+++ b/tests/daemon/mgmt/face-status-publisher-common.hpp
@@ -0,0 +1,192 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_TESTS_NFD_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
+#define NFD_TESTS_NFD_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
+
+#include "mgmt/face-status-publisher.hpp"
+#include "mgmt/app-face.hpp"
+#include "mgmt/internal-face.hpp"
+#include "mgmt/face-flags.hpp"
+#include "fw/forwarder.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include <ndn-cpp-dev/management/nfd-face-status.hpp>
+
+namespace nfd {
+namespace tests {
+
+class TestCountersFace : public DummyFace
+{
+public:
+
+  TestCountersFace()
+  {
+  }
+
+  virtual
+  ~TestCountersFace()
+  {
+  }
+
+  void
+  setCounters(FaceCounter nInInterests,
+              FaceCounter nInDatas,
+              FaceCounter nOutInterests,
+              FaceCounter nOutDatas)
+  {
+    FaceCounters& counters = getMutableCounters();
+    counters.getNInInterests()  = nInInterests;
+    counters.getNInDatas()      = nInDatas;
+    counters.getNOutInterests() = nOutInterests;
+    counters.getNOutDatas()     = nOutDatas;
+  }
+
+
+};
+
+static inline uint64_t
+readNonNegativeIntegerType(const Block& block,
+                           uint32_t type)
+{
+  if (block.type() == type)
+    {
+      return readNonNegativeInteger(block);
+    }
+  std::stringstream error;
+  error << "expected type " << type << " got " << block.type();
+  throw ndn::Tlv::Error(error.str());
+}
+
+static inline uint64_t
+checkedReadNonNegativeIntegerType(Block::element_const_iterator& i,
+                                  Block::element_const_iterator end,
+                                  uint32_t type)
+{
+  if (i != end)
+    {
+      const Block& block = *i;
+      ++i;
+      return readNonNegativeIntegerType(block, type);
+    }
+  throw ndn::Tlv::Error("Unexpected end of FaceStatus");
+}
+
+class FaceStatusPublisherFixture : public BaseFixture
+{
+public:
+
+  FaceStatusPublisherFixture()
+    : m_table(m_forwarder)
+    , m_face(make_shared<InternalFace>())
+    , m_publisher(m_table, m_face, "/localhost/nfd/FaceStatusPublisherFixture")
+    , m_finished(false)
+  {
+
+  }
+
+  virtual
+  ~FaceStatusPublisherFixture()
+  {
+
+  }
+
+  void
+  add(shared_ptr<Face> face)
+  {
+    m_table.add(face);
+  }
+
+  void
+  validateFaceStatus(const Block& statusBlock, const shared_ptr<Face>& reference)
+  {
+    ndn::nfd::FaceStatus status;
+    BOOST_REQUIRE_NO_THROW(status.wireDecode(statusBlock));
+    const FaceCounters& counters = reference->getCounters();
+
+    BOOST_CHECK_EQUAL(status.getFaceId(), reference->getId());
+    BOOST_CHECK_EQUAL(status.getRemoteUri(), reference->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(status.getLocalUri(), reference->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(status.getFlags(), getFaceFlags(*reference));
+    BOOST_CHECK_EQUAL(status.getNInInterests(), counters.getNInInterests());
+    BOOST_CHECK_EQUAL(status.getNInDatas(), counters.getNInDatas());
+    BOOST_CHECK_EQUAL(status.getNOutInterests(), counters.getNOutInterests());
+    BOOST_CHECK_EQUAL(status.getNOutDatas(), counters.getNOutDatas());
+  }
+
+  void
+  decodeFaceStatusBlock(const Data& data)
+  {
+    Block payload = data.getContent();
+
+    m_buffer.appendByteArray(payload.value(), payload.value_size());
+
+    BOOST_CHECK_NO_THROW(data.getName()[-1].toSegment());
+    if (data.getFinalBlockId() != data.getName()[-1])
+      {
+        return;
+      }
+
+    // wrap the Face Statuses in a single Content TLV for easy parsing
+    m_buffer.prependVarNumber(m_buffer.size());
+    m_buffer.prependVarNumber(ndn::Tlv::Content);
+
+    ndn::Block parser(m_buffer.buf(), m_buffer.size());
+    parser.parse();
+
+    BOOST_REQUIRE_EQUAL(parser.elements_size(), m_referenceFaces.size());
+
+    std::list<shared_ptr<Face> >::const_iterator iReference = m_referenceFaces.begin();
+    for (Block::element_const_iterator i = parser.elements_begin();
+         i != parser.elements_end();
+         ++i)
+      {
+        if (i->type() != ndn::tlv::nfd::FaceStatus)
+          {
+            BOOST_FAIL("expected face status, got type #" << i->type());
+          }
+        validateFaceStatus(*i, *iReference);
+        ++iReference;
+      }
+    m_finished = true;
+  }
+
+protected:
+  Forwarder m_forwarder;
+  FaceTable m_table;
+  shared_ptr<InternalFace> m_face;
+  FaceStatusPublisher m_publisher;
+  ndn::EncodingBuffer m_buffer;
+  std::list<shared_ptr<Face> > m_referenceFaces;
+
+protected:
+  bool m_finished;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
diff --git a/tests/daemon/mgmt/face-status-publisher.cpp b/tests/daemon/mgmt/face-status-publisher.cpp
new file mode 100644
index 0000000..836ea2d
--- /dev/null
+++ b/tests/daemon/mgmt/face-status-publisher.cpp
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "face-status-publisher-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("FaceStatusPublisherTest");
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceSatusPublisher, FaceStatusPublisherFixture)
+
+BOOST_AUTO_TEST_CASE(EncodingDecoding)
+{
+  Name commandName("/localhost/nfd/faces/list");
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  // MAX_SEGMENT_SIZE == 4400, FaceStatus size with filler counters is 55
+  // 55 divides 4400 (== 80), so only use 79 FaceStatuses and then two smaller ones
+  // to force a FaceStatus to span Data packets
+  for (int i = 0; i < 79; i++)
+    {
+      shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
+
+      uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
+      dummy->setCounters(filler, filler, filler, filler);
+
+      m_referenceFaces.push_back(dummy);
+
+      add(dummy);
+    }
+
+  for (int i = 0; i < 2; i++)
+    {
+      shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
+      uint64_t filler = std::numeric_limits<uint32_t>::max() - 1;
+      dummy->setCounters(filler, filler, filler, filler);
+
+      m_referenceFaces.push_back(dummy);
+
+      add(dummy);
+    }
+
+  ndn::EncodingBuffer buffer;
+
+  m_face->onReceiveData +=
+    bind(&FaceStatusPublisherFixture::decodeFaceStatusBlock, this, _1);
+
+  m_publisher.publish();
+  BOOST_REQUIRE(m_finished);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp b/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp
new file mode 100644
index 0000000..6befe54
--- /dev/null
+++ b/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp
@@ -0,0 +1,219 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_TESTS_NFD_MGMT_FIB_ENUMERATION_PUBLISHER_COMMON_HPP
+#define NFD_TESTS_NFD_MGMT_FIB_ENUMERATION_PUBLISHER_COMMON_HPP
+
+#include "mgmt/fib-enumeration-publisher.hpp"
+
+#include "mgmt/app-face.hpp"
+#include "mgmt/internal-face.hpp"
+#include "table/fib.hpp"
+#include "table/name-tree.hpp"
+
+#include "tests/test-common.hpp"
+#include "../face/dummy-face.hpp"
+
+#include <ndn-cpp-dev/encoding/tlv.hpp>
+
+namespace nfd {
+namespace tests {
+
+static inline uint64_t
+readNonNegativeIntegerType(const Block& block,
+                           uint32_t type)
+{
+  if (block.type() == type)
+    {
+      return readNonNegativeInteger(block);
+    }
+  std::stringstream error;
+  error << "Expected type " << type << " got " << block.type();
+  throw ndn::Tlv::Error(error.str());
+}
+
+static inline uint64_t
+checkedReadNonNegativeIntegerType(Block::element_const_iterator& i,
+                                  Block::element_const_iterator end,
+                                  uint32_t type)
+{
+  if (i != end)
+    {
+      const Block& block = *i;
+      ++i;
+      return readNonNegativeIntegerType(block, type);
+    }
+  std::stringstream error;
+  error << "Unexpected end of Block while attempting to read type #"
+        << type;
+  throw ndn::Tlv::Error(error.str());
+}
+
+class FibEnumerationPublisherFixture : public BaseFixture
+{
+public:
+
+  FibEnumerationPublisherFixture()
+    : m_fib(m_nameTree)
+    , m_face(make_shared<InternalFace>())
+    , m_publisher(m_fib, m_face, "/localhost/nfd/FibEnumerationPublisherFixture")
+    , m_finished(false)
+  {
+  }
+
+  virtual
+  ~FibEnumerationPublisherFixture()
+  {
+  }
+
+  bool
+  hasNextHopWithCost(const fib::NextHopList& nextHops,
+                     FaceId faceId,
+                     uint64_t cost)
+  {
+    for (fib::NextHopList::const_iterator i = nextHops.begin();
+         i != nextHops.end();
+         ++i)
+      {
+        if (i->getFace()->getId() == faceId && i->getCost() == cost)
+          {
+            return true;
+          }
+      }
+    return false;
+  }
+
+  bool
+  entryHasPrefix(const shared_ptr<fib::Entry> entry, const Name& prefix)
+  {
+    return entry->getPrefix() == prefix;
+  }
+
+  void
+  validateFibEntry(const Block& entry)
+  {
+    entry.parse();
+
+    Block::element_const_iterator i = entry.elements_begin();
+    BOOST_REQUIRE(i != entry.elements_end());
+
+
+    BOOST_REQUIRE(i->type() == ndn::Tlv::Name);
+    Name prefix(*i);
+    ++i;
+
+    std::set<shared_ptr<fib::Entry> >::const_iterator referenceIter =
+      std::find_if(m_referenceEntries.begin(), m_referenceEntries.end(),
+                   boost::bind(&FibEnumerationPublisherFixture::entryHasPrefix,
+                               this, _1, prefix));
+
+    BOOST_REQUIRE(referenceIter != m_referenceEntries.end());
+
+    const shared_ptr<fib::Entry>& reference = *referenceIter;
+    BOOST_REQUIRE_EQUAL(prefix, reference->getPrefix());
+
+    // 0 or more next hop records
+    size_t nRecords = 0;
+    const fib::NextHopList& referenceNextHops = reference->getNextHops();
+    for (; i != entry.elements_end(); ++i)
+      {
+        const ndn::Block& nextHopRecord = *i;
+        BOOST_REQUIRE(nextHopRecord.type() == ndn::tlv::nfd::NextHopRecord);
+        nextHopRecord.parse();
+
+        Block::element_const_iterator j = nextHopRecord.elements_begin();
+
+        FaceId faceId =
+          checkedReadNonNegativeIntegerType(j,
+                                            entry.elements_end(),
+                                            ndn::tlv::nfd::FaceId);
+
+        uint64_t cost =
+          checkedReadNonNegativeIntegerType(j,
+                                            entry.elements_end(),
+                                            ndn::tlv::nfd::Cost);
+
+        BOOST_REQUIRE(hasNextHopWithCost(referenceNextHops, faceId, cost));
+
+        BOOST_REQUIRE(j == nextHopRecord.elements_end());
+        nRecords++;
+      }
+    BOOST_REQUIRE_EQUAL(nRecords, referenceNextHops.size());
+
+    BOOST_REQUIRE(i == entry.elements_end());
+    m_referenceEntries.erase(referenceIter);
+  }
+
+  void
+  decodeFibEntryBlock(const Data& data)
+  {
+    Block payload = data.getContent();
+
+    m_buffer.appendByteArray(payload.value(), payload.value_size());
+
+    BOOST_CHECK_NO_THROW(data.getName()[-1].toSegment());
+    if (data.getFinalBlockId() != data.getName()[-1])
+      {
+        return;
+      }
+
+    // wrap the FIB Entry blocks in a single Content TLV for easy parsing
+    m_buffer.prependVarNumber(m_buffer.size());
+    m_buffer.prependVarNumber(ndn::Tlv::Content);
+
+    ndn::Block parser(m_buffer.buf(), m_buffer.size());
+    parser.parse();
+
+    BOOST_REQUIRE_EQUAL(parser.elements_size(), m_referenceEntries.size());
+
+    for (Block::element_const_iterator i = parser.elements_begin();
+         i != parser.elements_end();
+         ++i)
+      {
+        if (i->type() != ndn::tlv::nfd::FibEntry)
+          {
+            BOOST_FAIL("expected fib entry, got type #" << i->type());
+          }
+
+        validateFibEntry(*i);
+      }
+    m_finished = true;
+  }
+
+protected:
+  NameTree m_nameTree;
+  Fib m_fib;
+  shared_ptr<InternalFace> m_face;
+  FibEnumerationPublisher m_publisher;
+  ndn::EncodingBuffer m_buffer;
+  std::set<shared_ptr<fib::Entry> > m_referenceEntries;
+
+protected:
+  bool m_finished;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_MGMT_FIB_ENUMERATION_PUBLISHER_COMMON_HPP
diff --git a/tests/daemon/mgmt/fib-enumeration-publisher.cpp b/tests/daemon/mgmt/fib-enumeration-publisher.cpp
new file mode 100644
index 0000000..725d51e
--- /dev/null
+++ b/tests/daemon/mgmt/fib-enumeration-publisher.cpp
@@ -0,0 +1,89 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/fib-enumeration-publisher.hpp"
+
+#include "mgmt/app-face.hpp"
+#include "mgmt/internal-face.hpp"
+
+#include "tests/test-common.hpp"
+#include "../face/dummy-face.hpp"
+
+#include "fib-enumeration-publisher-common.hpp"
+
+#include <ndn-cpp-dev/encoding/tlv.hpp>
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("TestFibEnumerationPublisher");
+
+
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFibEnumeration, FibEnumerationPublisherFixture)
+
+BOOST_AUTO_TEST_CASE(TestFibEnumerationPublisher)
+{
+  for (int i = 0; i < 87; i++)
+    {
+      Name prefix("/test");
+      prefix.appendSegment(i);
+
+      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
+      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
+
+      shared_ptr<fib::Entry> entry = m_fib.insert(prefix).first;
+      entry->addNextHop(dummy1, std::numeric_limits<uint64_t>::max() - 1);
+      entry->addNextHop(dummy2, std::numeric_limits<uint64_t>::max() - 2);
+
+      m_referenceEntries.insert(entry);
+    }
+  for (int i = 0; i < 2; i++)
+    {
+      Name prefix("/test2");
+      prefix.appendSegment(i);
+
+      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
+      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
+
+      shared_ptr<fib::Entry> entry = m_fib.insert(prefix).first;
+      entry->addNextHop(dummy1, std::numeric_limits<uint8_t>::max() - 1);
+      entry->addNextHop(dummy2, std::numeric_limits<uint8_t>::max() - 2);
+
+      m_referenceEntries.insert(entry);
+    }
+
+  ndn::EncodingBuffer buffer;
+
+  m_face->onReceiveData +=
+    bind(&FibEnumerationPublisherFixture::decodeFibEntryBlock, this, _1);
+
+  m_publisher.publish();
+  BOOST_REQUIRE(m_finished);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/fib-manager.cpp b/tests/daemon/mgmt/fib-manager.cpp
new file mode 100644
index 0000000..b38c3b8
--- /dev/null
+++ b/tests/daemon/mgmt/fib-manager.cpp
@@ -0,0 +1,920 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/fib-manager.hpp"
+#include "table/fib.hpp"
+#include "table/fib-nexthop.hpp"
+#include "face/face.hpp"
+#include "mgmt/internal-face.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "validation-common.hpp"
+#include "tests/test-common.hpp"
+
+#include "fib-enumeration-publisher-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("FibManagerTest");
+
+class FibManagerFixture : public FibEnumerationPublisherFixture
+{
+public:
+
+  virtual
+  ~FibManagerFixture()
+  {
+  }
+
+  shared_ptr<Face>
+  getFace(FaceId id)
+  {
+    if (id > 0 && static_cast<size_t>(id) <= m_faces.size())
+      {
+        return m_faces[id - 1];
+      }
+    NFD_LOG_DEBUG("No face found returning NULL");
+    return shared_ptr<DummyFace>();
+  }
+
+  void
+  addFace(shared_ptr<Face> face)
+  {
+    m_faces.push_back(face);
+  }
+
+  void
+  validateControlResponseCommon(const Data& response,
+                                const Name& expectedName,
+                                uint32_t expectedCode,
+                                const std::string& expectedText,
+                                ControlResponse& control)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    control.wireDecode(controlRaw);
+
+    // NFD_LOG_DEBUG("received control response"
+    //               << " Name: " << response.getName()
+    //               << " code: " << control.getCode()
+    //               << " text: " << control.getText());
+
+    BOOST_CHECK_EQUAL(response.getName(), expectedName);
+    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
+    BOOST_CHECK_EQUAL(control.getText(), expectedText);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    if (!control.getBody().empty())
+      {
+        BOOST_FAIL("found unexpected control response body");
+      }
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText,
+                          const Block& expectedBody)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    BOOST_REQUIRE(!control.getBody().empty());
+    BOOST_REQUIRE_EQUAL(control.getBody().value_size(), expectedBody.value_size());
+
+    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
+                       expectedBody.value_size()) == 0);
+
+  }
+
+  bool
+  didCallbackFire()
+  {
+    return m_callbackFired;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
+  shared_ptr<InternalFace>
+  getInternalFace()
+  {
+    return m_face;
+  }
+
+  FibManager&
+  getFibManager()
+  {
+    return m_manager;
+  }
+
+  Fib&
+  getFib()
+  {
+    return m_fib;
+  }
+
+  void
+  addInterestRule(const std::string& regex,
+                  ndn::IdentityCertificate& certificate)
+  {
+    m_manager.addInterestRule(regex, certificate);
+  }
+
+protected:
+    FibManagerFixture()
+      : m_manager(boost::ref(m_fib),
+                  bind(&FibManagerFixture::getFace, this, _1),
+                  m_face)
+    , m_callbackFired(false)
+  {
+  }
+
+protected:
+  FibManager m_manager;
+
+  std::vector<shared_ptr<Face> > m_faces;
+  bool m_callbackFired;
+};
+
+template <typename T> class AuthorizedCommandFixture:
+    public CommandFixture<T>
+{
+public:
+  AuthorizedCommandFixture()
+  {
+    const std::string regex = "^<localhost><nfd><fib>";
+    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
+  }
+
+  virtual
+  ~AuthorizedCommandFixture()
+  {
+  }
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFibManager, AuthorizedCommandFixture<FibManagerFixture>)
+
+bool
+foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
+{
+  return id == next.getFace()->getId() && next.getCost() == cost;
+}
+
+bool
+addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
+{
+  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
+
+  if (static_cast<bool>(entry))
+    {
+      const fib::NextHopList& hops = entry->getNextHops();
+      return hops.size() == oldSize + 1 &&
+        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
+    }
+  return false;
+}
+
+bool
+foundNextHopWithFace(FaceId id, uint32_t cost,
+                     shared_ptr<Face> face, const fib::NextHop& next)
+{
+  return id == next.getFace()->getId() && next.getCost() == cost && face == next.getFace();
+}
+
+bool
+addedNextHopWithFace(const Fib& fib, const Name& prefix, size_t oldSize,
+                     uint32_t cost, shared_ptr<Face> face)
+{
+  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
+
+  if (static_cast<bool>(entry))
+    {
+      const fib::NextHopList& hops = entry->getNextHops();
+      return hops.size() == oldSize + 1 &&
+        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
+    }
+  return false;
+}
+
+BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
+{
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  shared_ptr<Interest> command = makeInterest("/localhost/nfd/fib");
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this,  _1,
+         command->getName(), 400, "Malformed command");
+
+  face->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(MalformedCommmand)
+{
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  BOOST_REQUIRE(didCallbackFire() == false);
+
+  Interest command("/localhost/nfd/fib");
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command.getName(), 400, "Malformed command");
+
+  getFibManager().onFibRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(UnsupportedVerb)
+{
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+  parameters.setCost(1);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("unsupported");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 501, "Unsupported command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(UnsignedCommand)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+  parameters.setCost(101);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  Interest command(commandName);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse,
+         this, _1, command.getName(), 401, "Signature required");
+
+
+  getFibManager().onFibRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!addedNextHopWithCost(getFib(), "/hello", 0, 101));
+}
+
+BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedCommandFixture<FibManagerFixture>)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+  parameters.setCost(101);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse,
+         this, _1, command->getName(), 403, "Unauthorized command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(!addedNextHopWithCost(getFib(), "/hello", 0, 101));
+}
+
+BOOST_AUTO_TEST_CASE(BadOptionParse)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append("NotReallyParameters");
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(UnknownFaceId)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1000);
+  parameters.setCost(101);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 410, "Face not found");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(addedNextHopWithCost(getFib(), "/hello", 0, 101) == false);
+}
+
+BOOST_AUTO_TEST_CASE(TestImplicitFaceId)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(0);
+  parameters.setCost(101);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  ControlParameters expectedParameters;
+  expectedParameters.setName("/hello");
+  expectedParameters.setFaceId(1);
+  expectedParameters.setCost(101);
+
+  Block encodedExpectedParameters(expectedParameters.wireEncode());
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  command->setIncomingFaceId(1);
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedExpectedParameters);
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(addedNextHopWithFace(getFib(), "/hello", 0, 101, getFace(1)));
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+  parameters.setCost(101);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedParameters);
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(addedNextHopWithCost(getFib(), "/hello", 0, 101));
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbImplicitCost)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  ControlParameters resultParameters;
+  resultParameters.setName("/hello");
+  resultParameters.setFaceId(1);
+  resultParameters.setCost(0);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", resultParameters.wireEncode());
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE(addedNextHopWithCost(getFib(), "/hello", 0, 0));
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
+{
+  addFace(make_shared<DummyFace>());
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  for (int i = 1; i <= 2; i++)
+    {
+
+      ControlParameters parameters;
+      parameters.setName("/hello");
+      parameters.setFaceId(1);
+      parameters.setCost(100 + i);
+
+      Block encodedParameters(parameters.wireEncode());
+
+      Name commandName("/localhost/nfd/fib");
+      commandName.append("add-nexthop");
+      commandName.append(encodedParameters);
+
+      shared_ptr<Interest> command(make_shared<Interest>(commandName));
+      generateCommand(*command);
+
+      face->onReceiveData +=
+        bind(&FibManagerFixture::validateControlResponse, this, _1,
+             command->getName(), 200, "Success", encodedParameters);
+
+      getFibManager().onFibRequest(*command);
+      BOOST_REQUIRE(didCallbackFire());
+      resetCallbackFired();
+
+      shared_ptr<fib::Entry> entry = getFib().findExactMatch("/hello");
+
+      if (static_cast<bool>(entry))
+        {
+          const fib::NextHopList& hops = entry->getNextHops();
+          BOOST_REQUIRE(hops.size() == 1);
+          BOOST_REQUIRE(std::find_if(hops.begin(), hops.end(),
+                                     bind(&foundNextHop, -1, 100 + i, _1)) != hops.end());
+
+        }
+      else
+        {
+          BOOST_FAIL("Failed to find expected fib entry");
+        }
+
+      face->onReceiveData.clear();
+    }
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
+{
+  addFace(make_shared<DummyFace>());
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+
+  {
+    parameters.setCost(1);
+
+    Block encodedParameters(parameters.wireEncode());
+
+    Name commandName("/localhost/nfd/fib");
+    commandName.append("add-nexthop");
+    commandName.append(encodedParameters);
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    generateCommand(*command);
+
+    face->onReceiveData +=
+      bind(&FibManagerFixture::validateControlResponse, this, _1,
+           command->getName(), 200, "Success", encodedParameters);
+
+    getFibManager().onFibRequest(*command);
+
+    BOOST_REQUIRE(didCallbackFire());
+  }
+
+  resetCallbackFired();
+  face->onReceiveData.clear();
+
+  {
+    parameters.setCost(102);
+
+    Block encodedParameters(parameters.wireEncode());
+
+    Name commandName("/localhost/nfd/fib");
+    commandName.append("add-nexthop");
+    commandName.append(encodedParameters);
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    generateCommand(*command);
+
+    face->onReceiveData +=
+      bind(&FibManagerFixture::validateControlResponse, this, _1,
+           command->getName(), 200, "Success", encodedParameters);
+
+    getFibManager().onFibRequest(*command);
+
+    BOOST_REQUIRE(didCallbackFire());
+  }
+
+  shared_ptr<fib::Entry> entry = getFib().findExactMatch("/hello");
+
+  // Add faces with cost == FaceID for the name /hello
+  // This test assumes:
+  //   FaceIDs are -1 because we don't add them to a forwarder
+  if (static_cast<bool>(entry))
+    {
+      const fib::NextHopList& hops = entry->getNextHops();
+      BOOST_REQUIRE(hops.size() == 1);
+      BOOST_REQUIRE(std::find_if(hops.begin(),
+                                 hops.end(),
+                                 bind(&foundNextHop, -1, 102, _1)) != hops.end());
+    }
+  else
+    {
+      BOOST_FAIL("Failed to find expected fib entry");
+    }
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbMissingPrefix)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setFaceId(1);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbMissingFaceId)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("add-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+bool
+removedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
+{
+  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
+
+  if (static_cast<bool>(entry))
+    {
+      const fib::NextHopList& hops = entry->getNextHops();
+      return hops.size() == oldSize - 1 &&
+        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
+    }
+  return false;
+}
+
+void
+testRemoveNextHop(CommandFixture<FibManagerFixture>* fixture,
+                  FibManager& manager,
+                  Fib& fib,
+                  shared_ptr<Face> face,
+                  const Name& targetName,
+                  FaceId targetFace)
+{
+  ControlParameters parameters;
+  parameters.setName(targetName);
+  parameters.setFaceId(targetFace);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("remove-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  fixture->generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, fixture, _1,
+         command->getName(), 200, "Success", encodedParameters);
+
+  manager.onFibRequest(*command);
+
+  BOOST_REQUIRE(fixture->didCallbackFire());
+
+  fixture->resetCallbackFired();
+  face->onReceiveData.clear();
+}
+
+BOOST_AUTO_TEST_CASE(RemoveNextHop)
+{
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+  shared_ptr<Face> face3 = make_shared<DummyFace>();
+
+  addFace(face1);
+  addFace(face2);
+  addFace(face3);
+
+  shared_ptr<InternalFace> face = getInternalFace();
+  FibManager& manager = getFibManager();
+  Fib& fib = getFib();
+
+  shared_ptr<fib::Entry> entry = fib.insert("/hello").first;
+
+  entry->addNextHop(face1, 101);
+  entry->addNextHop(face2, 202);
+  entry->addNextHop(face3, 303);
+
+  testRemoveNextHop(this, manager, fib, face, "/hello", 2);
+  BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 3, 202));
+
+  testRemoveNextHop(this, manager, fib, face, "/hello", 3);
+  BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 2, 303));
+
+  testRemoveNextHop(this, manager, fib, face, "/hello", 1);
+  // BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 1, 101));
+
+  BOOST_CHECK(!static_cast<bool>(getFib().findExactMatch("/hello")));
+}
+
+BOOST_AUTO_TEST_CASE(RemoveFaceNotFound)
+{
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("remove-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedParameters);
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(RemovePrefixNotFound)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+  parameters.setFaceId(1);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("remove-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedParameters);
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(RemoveMissingPrefix)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setFaceId(1);
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("remove-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(RemoveMissingFaceId)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face = getInternalFace();
+
+  ControlParameters parameters;
+  parameters.setName("/hello");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/fib");
+  commandName.append("remove-nexthop");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  face->onReceiveData +=
+    bind(&FibManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getFibManager().onFibRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(TestFibEnumerationRequest, FibManagerFixture)
+{
+  for (int i = 0; i < 87; i++)
+    {
+      Name prefix("/test");
+      prefix.appendSegment(i);
+
+      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
+      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
+
+      shared_ptr<fib::Entry> entry = m_fib.insert(prefix).first;
+      entry->addNextHop(dummy1, std::numeric_limits<uint64_t>::max() - 1);
+      entry->addNextHop(dummy2, std::numeric_limits<uint64_t>::max() - 2);
+
+      m_referenceEntries.insert(entry);
+    }
+  for (int i = 0; i < 2; i++)
+    {
+      Name prefix("/test2");
+      prefix.appendSegment(i);
+
+      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
+      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
+
+      shared_ptr<fib::Entry> entry = m_fib.insert(prefix).first;
+      entry->addNextHop(dummy1, std::numeric_limits<uint8_t>::max() - 1);
+      entry->addNextHop(dummy2, std::numeric_limits<uint8_t>::max() - 2);
+
+      m_referenceEntries.insert(entry);
+    }
+
+  ndn::EncodingBuffer buffer;
+
+  m_face->onReceiveData +=
+    bind(&FibEnumerationPublisherFixture::decodeFibEntryBlock, this, _1);
+
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/fib/list"));
+
+  m_manager.onFibRequest(*command);
+  BOOST_REQUIRE(m_finished);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/internal-face.cpp b/tests/daemon/mgmt/internal-face.cpp
new file mode 100644
index 0000000..04ef4a2
--- /dev/null
+++ b/tests/daemon/mgmt/internal-face.cpp
@@ -0,0 +1,236 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/internal-face.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("InternalFaceTest");
+
+class InternalFaceFixture : protected BaseFixture
+{
+public:
+
+  InternalFaceFixture()
+    : m_onInterestFired(false),
+      m_noOnInterestFired(false)
+  {
+
+  }
+
+  void
+  validateOnInterestCallback(const Name& name, const Interest& interest)
+  {
+    m_onInterestFired = true;
+  }
+
+  void
+  validateNoOnInterestCallback(const Name& name, const Interest& interest)
+  {
+    m_noOnInterestFired = true;
+  }
+
+  void
+  addFace(shared_ptr<Face> face)
+  {
+    m_faces.push_back(face);
+  }
+
+  bool
+  didOnInterestFire()
+  {
+    return m_onInterestFired;
+  }
+
+  bool
+  didNoOnInterestFire()
+  {
+    return m_noOnInterestFired;
+  }
+
+  void
+  resetOnInterestFired()
+  {
+    m_onInterestFired = false;
+  }
+
+  void
+  resetNoOnInterestFired()
+  {
+    m_noOnInterestFired = false;
+  }
+
+private:
+  std::vector<shared_ptr<Face> > m_faces;
+  bool m_onInterestFired;
+  bool m_noOnInterestFired;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtInternalFace, InternalFaceFixture)
+
+void
+validatePutData(bool& called, const Name& expectedName, const Data& data)
+{
+  called = true;
+  BOOST_CHECK_EQUAL(expectedName, data.getName());
+}
+
+BOOST_AUTO_TEST_CASE(PutData)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face(new InternalFace);
+
+  bool didPutData = false;
+  Name dataName("/hello");
+  face->onReceiveData += bind(&validatePutData, boost::ref(didPutData), dataName, _1);
+
+  Data testData(dataName);
+  face->sign(testData);
+  face->put(testData);
+
+  BOOST_REQUIRE(didPutData);
+
+  BOOST_CHECK_THROW(face->close(), InternalFace::Error);
+}
+
+BOOST_AUTO_TEST_CASE(SendInterestHitEnd)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face(new InternalFace);
+
+  face->setInterestFilter("/localhost/nfd/fib",
+                          bind(&InternalFaceFixture::validateOnInterestCallback,
+                               this, _1, _2));
+
+  // generate command whose name is canonically
+  // ordered after /localhost/nfd/fib so that
+  // we hit the end of the std::map
+
+  Name commandName("/localhost/nfd/fib/end");
+  shared_ptr<Interest> command = makeInterest(commandName);
+  face->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didOnInterestFire());
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
+}
+
+BOOST_AUTO_TEST_CASE(SendInterestHitBegin)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face(new InternalFace);
+
+  face->setInterestFilter("/localhost/nfd/fib",
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
+
+  // generate command whose name is canonically
+  // ordered before /localhost/nfd/fib so that
+  // we hit the beginning of the std::map
+
+  Name commandName("/localhost/nfd");
+  shared_ptr<Interest> command = makeInterest(commandName);
+  face->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
+}
+
+BOOST_AUTO_TEST_CASE(SendInterestHitExact)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face(new InternalFace);
+
+  face->setInterestFilter("/localhost/nfd/eib",
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
+
+  face->setInterestFilter("/localhost/nfd/fib",
+                          bind(&InternalFaceFixture::validateOnInterestCallback,
+                           this, _1, _2));
+
+  face->setInterestFilter("/localhost/nfd/gib",
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
+
+  // generate command whose name exactly matches
+  // /localhost/nfd/fib
+
+  Name commandName("/localhost/nfd/fib");
+  shared_ptr<Interest> command = makeInterest(commandName);
+  face->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didOnInterestFire());
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
+}
+
+BOOST_AUTO_TEST_CASE(SendInterestHitPrevious)
+{
+  addFace(make_shared<DummyFace>());
+
+  shared_ptr<InternalFace> face(new InternalFace);
+
+  face->setInterestFilter("/localhost/nfd/fib",
+                          bind(&InternalFaceFixture::validateOnInterestCallback,
+                               this, _1, _2));
+
+  face->setInterestFilter("/localhost/nfd/fib/zzzzzzzzzzzzz/",
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
+
+  // generate command whose name exactly matches
+  // an Interest filter
+
+  Name commandName("/localhost/nfd/fib/previous");
+  shared_ptr<Interest> command = makeInterest(commandName);
+  face->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didOnInterestFire());
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
+}
+
+BOOST_AUTO_TEST_CASE(InterestGone)
+{
+  shared_ptr<InternalFace> face = make_shared<InternalFace>();
+  shared_ptr<Interest> interest = makeInterest("ndn:/localhost/nfd/gone");
+  face->sendInterest(*interest);
+
+  interest.reset();
+  BOOST_CHECK_NO_THROW(g_io.poll());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/malformed.ndncert b/tests/daemon/mgmt/malformed.ndncert
new file mode 100644
index 0000000..38b2fbb
--- /dev/null
+++ b/tests/daemon/mgmt/malformed.ndncert
@@ -0,0 +1 @@
+definitely not a key
\ No newline at end of file
diff --git a/tests/daemon/mgmt/manager-base.cpp b/tests/daemon/mgmt/manager-base.cpp
new file mode 100644
index 0000000..74fcb6e
--- /dev/null
+++ b/tests/daemon/mgmt/manager-base.cpp
@@ -0,0 +1,201 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/manager-base.hpp"
+#include "mgmt/internal-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("ManagerBaseTest");
+
+class ManagerBaseTest : public ManagerBase, protected BaseFixture
+{
+
+public:
+
+  ManagerBaseTest()
+    : ManagerBase(make_shared<InternalFace>(), "TEST-PRIVILEGE"),
+      m_callbackFired(false)
+  {
+
+  }
+
+  void
+  testSetResponse(ControlResponse& response,
+                  uint32_t code,
+                  const std::string& text)
+  {
+    setResponse(response, code, text);
+  }
+
+  void
+  testSendResponse(const Name& name,
+                   uint32_t code,
+                   const std::string& text,
+                   const Block& body)
+  {
+    sendResponse(name, code, text, body);
+  }
+
+  void
+  testSendResponse(const Name& name,
+                   uint32_t code,
+                   const std::string& text)
+  {
+    sendResponse(name, code, text);
+  }
+
+  void
+  testSendResponse(const Name& name,
+                   const ControlResponse& response)
+  {
+    sendResponse(name, response);
+  }
+
+  shared_ptr<InternalFace>
+  getInternalFace()
+  {
+    return ndn::ptr_lib::static_pointer_cast<InternalFace>(m_face);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    ControlResponse control;
+    control.wireDecode(controlRaw);
+
+    NFD_LOG_DEBUG("received control response"
+                  << " name: " << response.getName()
+                  << " code: " << control.getCode()
+                  << " text: " << control.getText());
+
+    BOOST_REQUIRE(response.getName() == expectedName);
+    BOOST_REQUIRE(control.getCode() == expectedCode);
+    BOOST_REQUIRE(control.getText() == expectedText);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText,
+                          const Block& expectedBody)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    ControlResponse control;
+    control.wireDecode(controlRaw);
+
+    NFD_LOG_DEBUG("received control response"
+                  << " name: " << response.getName()
+                  << " code: " << control.getCode()
+                  << " text: " << control.getText());
+
+    BOOST_REQUIRE(response.getName() == expectedName);
+    BOOST_REQUIRE(control.getCode() == expectedCode);
+    BOOST_REQUIRE(control.getText() == expectedText);
+
+    BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
+
+    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
+                       expectedBody.value_size()) == 0);
+  }
+
+  bool
+  didCallbackFire()
+  {
+    return m_callbackFired;
+  }
+
+private:
+
+  bool m_callbackFired;
+
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtManagerBase, ManagerBaseTest)
+
+BOOST_AUTO_TEST_CASE(SetResponse)
+{
+  ControlResponse response(200, "OK");
+
+  BOOST_CHECK_EQUAL(response.getCode(), 200);
+  BOOST_CHECK_EQUAL(response.getText(), "OK");
+
+  testSetResponse(response, 100, "test");
+
+  BOOST_CHECK_EQUAL(response.getCode(), 100);
+  BOOST_CHECK_EQUAL(response.getText(), "test");
+}
+
+BOOST_AUTO_TEST_CASE(SendResponse4Arg)
+{
+  ndn::nfd::ControlParameters parameters;
+  parameters.setName("/test/body");
+
+  getInternalFace()->onReceiveData +=
+    bind(&ManagerBaseTest::validateControlResponse, this, _1,
+         "/response", 100, "test", parameters.wireEncode());
+
+  testSendResponse("/response", 100, "test", parameters.wireEncode());
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+
+BOOST_AUTO_TEST_CASE(SendResponse3Arg)
+{
+  getInternalFace()->onReceiveData +=
+    bind(&ManagerBaseTest::validateControlResponse, this, _1,
+         "/response", 100, "test");
+
+  testSendResponse("/response", 100, "test");
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(SendResponse2Arg)
+{
+  getInternalFace()->onReceiveData +=
+    bind(&ManagerBaseTest::validateControlResponse, this, _1,
+         "/response", 100, "test");
+
+  ControlResponse response(100, "test");
+
+  testSendResponse("/response", 100, "test");
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/notification-stream.cpp b/tests/daemon/mgmt/notification-stream.cpp
new file mode 100644
index 0000000..32f5a20
--- /dev/null
+++ b/tests/daemon/mgmt/notification-stream.cpp
@@ -0,0 +1,140 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/notification-stream.hpp"
+#include "mgmt/internal-face.hpp"
+
+#include "tests/test-common.hpp"
+
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("NotificationStreamTest");
+
+
+
+class NotificationStreamFixture : public BaseFixture
+{
+public:
+  NotificationStreamFixture()
+    : m_callbackFired(false)
+    , m_prefix("/localhost/nfd/NotificationStreamTest")
+    , m_message("TestNotificationMessage")
+    , m_sequenceNo(0)
+  {
+  }
+
+  virtual
+  ~NotificationStreamFixture()
+  {
+  }
+
+  void
+  validateCallback(const Data& data)
+  {
+    Name expectedName(m_prefix);
+    expectedName.appendSegment(m_sequenceNo);
+    BOOST_REQUIRE_EQUAL(data.getName(), expectedName);
+
+    ndn::Block payload = data.getContent();
+    std::string message;
+
+    message.append(reinterpret_cast<const char*>(payload.value()), payload.value_size());
+
+    BOOST_REQUIRE_EQUAL(message, m_message);
+
+    m_callbackFired = true;
+    ++m_sequenceNo;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
+protected:
+  bool m_callbackFired;
+  const std::string m_prefix;
+  const std::string m_message;
+  uint64_t m_sequenceNo;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtNotificationStream, NotificationStreamFixture)
+
+class TestNotification
+{
+public:
+  TestNotification(const std::string& message)
+    : m_message(message)
+  {
+  }
+
+  ~TestNotification()
+  {
+  }
+
+  Block
+  wireEncode() const
+  {
+    ndn::EncodingBuffer buffer;
+
+    prependByteArrayBlock(buffer,
+                          ndn::Tlv::Content,
+                          reinterpret_cast<const uint8_t*>(m_message.c_str()),
+                          m_message.size());
+    return buffer.block();
+  }
+
+private:
+  const std::string m_message;
+};
+
+BOOST_AUTO_TEST_CASE(TestPostEvent)
+{
+  shared_ptr<InternalFace> face(make_shared<InternalFace>());
+  NotificationStream notificationStream(face, "/localhost/nfd/NotificationStreamTest");
+
+  face->onReceiveData += bind(&NotificationStreamFixture::validateCallback, this, _1);
+
+  TestNotification event1(m_message);
+  notificationStream.postNotification(event1);
+
+  BOOST_REQUIRE(m_callbackFired);
+
+  resetCallbackFired();
+
+  TestNotification event2(m_message);
+  notificationStream.postNotification(event2);
+
+  BOOST_REQUIRE(m_callbackFired);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/segment-publisher.cpp b/tests/daemon/mgmt/segment-publisher.cpp
new file mode 100644
index 0000000..e40f372
--- /dev/null
+++ b/tests/daemon/mgmt/segment-publisher.cpp
@@ -0,0 +1,151 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/segment-publisher.hpp"
+#include "mgmt/internal-face.hpp"
+#include "mgmt/app-face.hpp"
+
+#include "tests/test-common.hpp"
+#include <ndn-cpp-dev/encoding/tlv.hpp>
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("SegmentPublisherTest");
+
+class TestSegmentPublisher : public SegmentPublisher
+{
+public:
+  TestSegmentPublisher(shared_ptr<AppFace> face,
+                       const Name& prefix,
+                       const uint64_t limit=10000)
+    : SegmentPublisher(face, prefix)
+    , m_limit((limit == 0)?(1):(limit))
+  {
+
+  }
+
+  virtual
+  ~TestSegmentPublisher()
+  {
+
+  }
+
+  uint16_t
+  getLimit() const
+  {
+    return m_limit;
+  }
+
+protected:
+
+  virtual size_t
+  generate(ndn::EncodingBuffer& outBuffer)
+  {
+    size_t totalLength = 0;
+    for (uint64_t i = 0; i < m_limit; i++)
+      {
+        totalLength += prependNonNegativeIntegerBlock(outBuffer, ndn::Tlv::Content, i);
+      }
+    return totalLength;
+  }
+
+protected:
+  const uint64_t m_limit;
+};
+
+class SegmentPublisherFixture : public BaseFixture
+{
+public:
+  SegmentPublisherFixture()
+    : m_face(make_shared<InternalFace>())
+    , m_publisher(m_face, "/localhost/nfd/SegmentPublisherFixture")
+    , m_finished(false)
+  {
+
+  }
+
+  void
+  validate(const Data& data)
+  {
+    Block payload = data.getContent();
+    NFD_LOG_DEBUG("payload size (w/o Content TLV): " << payload.value_size());
+
+    m_buffer.appendByteArray(payload.value(), payload.value_size());
+
+    uint64_t segmentNo = data.getName()[-1].toSegment();
+    if (data.getFinalBlockId() != data.getName()[-1])
+      {
+        return;
+      }
+
+    NFD_LOG_DEBUG("got final block: #" << segmentNo);
+
+    // wrap data in a single Content TLV for easy parsing
+    m_buffer.prependVarNumber(m_buffer.size());
+    m_buffer.prependVarNumber(ndn::Tlv::Content);
+
+    BOOST_TEST_CHECKPOINT("creating parser");
+    ndn::Block parser(m_buffer.buf(), m_buffer.size());
+    BOOST_TEST_CHECKPOINT("parsing aggregated response");
+    parser.parse();
+
+    BOOST_REQUIRE_EQUAL(parser.elements_size(), m_publisher.getLimit());
+
+    uint64_t expectedNo = m_publisher.getLimit() - 1;
+    for (Block::element_const_iterator i = parser.elements_begin();
+         i != parser.elements_end();
+         ++i)
+      {
+        uint64_t number = readNonNegativeInteger(*i);
+        BOOST_REQUIRE_EQUAL(number, expectedNo);
+        --expectedNo;
+      }
+    m_finished = true;
+  }
+
+protected:
+  shared_ptr<InternalFace> m_face;
+  TestSegmentPublisher m_publisher;
+  ndn::EncodingBuffer m_buffer;
+
+protected:
+  bool m_finished;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtSegmentPublisher, SegmentPublisherFixture)
+
+BOOST_AUTO_TEST_CASE(Generate)
+{
+  m_face->onReceiveData +=
+    bind(&SegmentPublisherFixture::validate, this, _1);
+
+  m_publisher.publish();
+  BOOST_REQUIRE(m_finished);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/status-server.cpp b/tests/daemon/mgmt/status-server.cpp
new file mode 100644
index 0000000..75b4114
--- /dev/null
+++ b/tests/daemon/mgmt/status-server.cpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/status-server.hpp"
+#include "fw/forwarder.hpp"
+#include "version.hpp"
+#include "mgmt/internal-face.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(MgmtStatusServer, BaseFixture)
+
+shared_ptr<const Data> g_response;
+
+void
+interceptResponse(const Data& data)
+{
+  g_response = data.shared_from_this();
+}
+
+BOOST_AUTO_TEST_CASE(Status)
+{
+  // initialize
+  time::system_clock::TimePoint t1 = time::system_clock::now();
+  Forwarder forwarder;
+  shared_ptr<InternalFace> internalFace = make_shared<InternalFace>();
+  internalFace->onReceiveData += &interceptResponse;
+  StatusServer statusServer(internalFace, boost::ref(forwarder));
+  time::system_clock::TimePoint t2 = time::system_clock::now();
+
+  // populate tables
+  forwarder.getFib().insert("ndn:/fib1");
+  forwarder.getPit().insert(*makeInterest("ndn:/pit1"));
+  forwarder.getPit().insert(*makeInterest("ndn:/pit2"));
+  forwarder.getPit().insert(*makeInterest("ndn:/pit3"));
+  forwarder.getPit().insert(*makeInterest("ndn:/pit4"));
+  forwarder.getMeasurements().get("ndn:/measurements1");
+  forwarder.getMeasurements().get("ndn:/measurements2");
+  forwarder.getMeasurements().get("ndn:/measurements3");
+  BOOST_CHECK_GE(forwarder.getFib().size(), 1);
+  BOOST_CHECK_GE(forwarder.getPit().size(), 4);
+  BOOST_CHECK_GE(forwarder.getMeasurements().size(), 3);
+
+  // request
+  shared_ptr<Interest> request = makeInterest("ndn:/localhost/nfd/status");
+  request->setMustBeFresh(true);
+  request->setChildSelector(1);
+
+  g_response.reset();
+  time::system_clock::TimePoint t3 = time::system_clock::now();
+  internalFace->sendInterest(*request);
+  g_io.run_one();
+  time::system_clock::TimePoint t4 = time::system_clock::now();
+  BOOST_REQUIRE(static_cast<bool>(g_response));
+
+  // verify
+  ndn::nfd::ForwarderStatus status;
+  BOOST_REQUIRE_NO_THROW(status.wireDecode(g_response->getContent()));
+
+  BOOST_CHECK_EQUAL(status.getNfdVersion(), NFD_VERSION);
+  BOOST_CHECK_GE(time::toUnixTimestamp(status.getStartTimestamp()), time::toUnixTimestamp(t1));
+  BOOST_CHECK_LE(time::toUnixTimestamp(status.getStartTimestamp()), time::toUnixTimestamp(t2));
+  BOOST_CHECK_GE(time::toUnixTimestamp(status.getCurrentTimestamp()), time::toUnixTimestamp(t3));
+  BOOST_CHECK_LE(time::toUnixTimestamp(status.getCurrentTimestamp()), time::toUnixTimestamp(t4));
+
+  // StatusServer under test isn't added to Forwarder,
+  // so request and response won't affect table size
+  BOOST_CHECK_EQUAL(status.getNNameTreeEntries(), forwarder.getNameTree().size());
+  BOOST_CHECK_EQUAL(status.getNFibEntries(), forwarder.getFib().size());
+  BOOST_CHECK_EQUAL(status.getNPitEntries(), forwarder.getPit().size());
+  BOOST_CHECK_EQUAL(status.getNMeasurementsEntries(), forwarder.getMeasurements().size());
+  BOOST_CHECK_EQUAL(status.getNCsEntries(), forwarder.getCs().size());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/strategy-choice-manager.cpp b/tests/daemon/mgmt/strategy-choice-manager.cpp
new file mode 100644
index 0000000..99d5636
--- /dev/null
+++ b/tests/daemon/mgmt/strategy-choice-manager.cpp
@@ -0,0 +1,548 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "mgmt/strategy-choice-manager.hpp"
+#include "face/face.hpp"
+#include "mgmt/internal-face.hpp"
+#include "table/name-tree.hpp"
+#include "table/strategy-choice.hpp"
+#include "fw/forwarder.hpp"
+#include "fw/strategy.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+#include "tests/daemon/fw/dummy-strategy.hpp"
+
+#include "tests/test-common.hpp"
+#include "validation-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("StrategyChoiceManagerTest");
+
+class StrategyChoiceManagerFixture : protected BaseFixture
+{
+public:
+
+  StrategyChoiceManagerFixture()
+    : m_strategyChoice(m_forwarder.getStrategyChoice())
+    , m_face(make_shared<InternalFace>())
+    , m_manager(m_strategyChoice, m_face)
+    , m_callbackFired(false)
+  {
+    m_strategyChoice.install(make_shared<DummyStrategy>(boost::ref(m_forwarder), "/localhost/nfd/strategy/test-strategy-a"));
+    m_strategyChoice.insert("ndn:/", "/localhost/nfd/strategy/test-strategy-a");
+  }
+
+  virtual
+  ~StrategyChoiceManagerFixture()
+  {
+
+  }
+
+  void
+  validateControlResponseCommon(const Data& response,
+                                const Name& expectedName,
+                                uint32_t expectedCode,
+                                const std::string& expectedText,
+                                ControlResponse& control)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    control.wireDecode(controlRaw);
+
+    NFD_LOG_DEBUG("received control response"
+                  << " Name: " << response.getName()
+                  << " code: " << control.getCode()
+                  << " text: " << control.getText());
+
+    BOOST_CHECK_EQUAL(response.getName(), expectedName);
+    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
+    BOOST_CHECK_EQUAL(control.getText(), expectedText);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    if (!control.getBody().empty())
+      {
+        BOOST_FAIL("found unexpected control response body");
+      }
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText,
+                          const Block& expectedBody)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    BOOST_REQUIRE(!control.getBody().empty());
+    BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
+
+    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
+                       expectedBody.value_size()) == 0);
+
+  }
+
+  bool
+  didCallbackFire()
+  {
+    return m_callbackFired;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
+  shared_ptr<InternalFace>&
+  getFace()
+  {
+    return m_face;
+  }
+
+  StrategyChoiceManager&
+  getManager()
+  {
+    return m_manager;
+  }
+
+  StrategyChoice&
+  getStrategyChoice()
+  {
+    return m_strategyChoice;
+  }
+
+  void
+  addInterestRule(const std::string& regex,
+                  ndn::IdentityCertificate& certificate)
+  {
+    m_manager.addInterestRule(regex, certificate);
+  }
+
+protected:
+  Forwarder m_forwarder;
+  StrategyChoice& m_strategyChoice;
+  shared_ptr<InternalFace> m_face;
+  StrategyChoiceManager m_manager;
+
+private:
+  bool m_callbackFired;
+};
+
+class AllStrategiesFixture : public StrategyChoiceManagerFixture
+{
+public:
+  AllStrategiesFixture()
+  {
+    m_strategyChoice.install(make_shared<DummyStrategy>(boost::ref(m_forwarder), "/localhost/nfd/strategy/test-strategy-b"));
+  }
+
+  virtual
+  ~AllStrategiesFixture()
+  {
+
+  }
+};
+
+template <typename T> class AuthorizedCommandFixture : public CommandFixture<T>
+{
+public:
+  AuthorizedCommandFixture()
+  {
+    const std::string regex = "^<localhost><nfd><strategy-choice>";
+    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
+  }
+
+  virtual
+  ~AuthorizedCommandFixture()
+  {
+
+  }
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoiceManager,
+                         AuthorizedCommandFixture<AllStrategiesFixture>)
+
+BOOST_FIXTURE_TEST_CASE(TestFireInterestFilter, AllStrategiesFixture)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this,  _1,
+         command->getName(), 400, "Malformed command");
+
+  getFace()->sendInterest(*command);
+  g_io.run_one();
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(MalformedCommmand, AllStrategiesFixture)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onStrategyChoiceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(UnsignedCommand, AllStrategiesFixture)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+  parameters.setStrategy("/localhost/nfd/strategy/best-route");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 401, "Signature required");
+
+  getManager().onStrategyChoiceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand,
+                        UnauthorizedCommandFixture<StrategyChoiceManagerFixture>)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+  parameters.setStrategy("/localhost/nfd/strategy/best-route");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 403, "Unauthorized command");
+
+  getManager().onStrategyChoiceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(UnsupportedVerb)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+  parameters.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unsupported");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 501, "Unsupported command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(BadOptionParse)
+{
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append("NotReallyParameters");
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(SetStrategies)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+  parameters.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedParameters);
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+  BOOST_REQUIRE_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-b");
+}
+
+BOOST_AUTO_TEST_CASE(SetStrategiesMissingName)
+{
+  ControlParameters parameters;
+  parameters.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(SetStrategiesMissingStrategy)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+  BOOST_REQUIRE_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
+}
+
+BOOST_AUTO_TEST_CASE(SetUnsupportedStrategy)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+  parameters.setStrategy("/localhost/nfd/strategy/unit-test-doesnotexist");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("set");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 504, "Unsupported strategy");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+  fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+  BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
+}
+
+class DefaultStrategyOnlyFixture : public StrategyChoiceManagerFixture
+{
+public:
+  DefaultStrategyOnlyFixture()
+    : StrategyChoiceManagerFixture()
+  {
+
+  }
+
+  virtual
+  ~DefaultStrategyOnlyFixture()
+  {
+
+  }
+};
+
+
+/// \todo I'm not sure this code branch (code 405) can happen. The manager tests for the strategy first and will return 504.
+// BOOST_FIXTURE_TEST_CASE(SetNotInstalled, DefaultStrategyOnlyFixture)
+// {
+//   BOOST_REQUIRE(!getStrategyChoice().hasStrategy("/localhost/nfd/strategy/test-strategy-b"));
+//   ControlParameters parameters;
+//   parameters.setName("/test");
+//   parameters.setStrategy("/localhost/nfd/strategy/test-strategy-b");
+
+//   Block encodedParameters(parameters.wireEncode());
+
+//   Name commandName("/localhost/nfd/strategy-choice");
+//   commandName.append("set");
+//   commandName.append(encodedParameters);
+
+//   shared_ptr<Interest> command(make_shared<Interest>(commandName));
+//   generateCommand(*command);
+
+//   getFace()->onReceiveData +=
+//     bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+//          command->getName(), 405, "Strategy not installed");
+
+//   getManager().onValidatedStrategyChoiceRequest(command);
+
+//   BOOST_REQUIRE(didCallbackFire());
+//   fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
+//   BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
+// }
+
+BOOST_AUTO_TEST_CASE(Unset)
+{
+  ControlParameters parameters;
+  parameters.setName("/test");
+
+  BOOST_REQUIRE(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b"));
+  BOOST_REQUIRE_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                      "/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unset");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 200, "Success", encodedParameters);
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                    "/localhost/nfd/strategy/test-strategy-a");
+}
+
+BOOST_AUTO_TEST_CASE(UnsetRoot)
+{
+  ControlParameters parameters;
+  parameters.setName("/");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unset");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 403, "Cannot unset root prefix strategy");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                    "/localhost/nfd/strategy/test-strategy-a");
+}
+
+BOOST_AUTO_TEST_CASE(UnsetMissingName)
+{
+  ControlParameters parameters;
+
+  BOOST_REQUIRE(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b"));
+  BOOST_REQUIRE_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                      "/localhost/nfd/strategy/test-strategy-b");
+
+  Block encodedParameters(parameters.wireEncode());
+
+  Name commandName("/localhost/nfd/strategy-choice");
+  commandName.append("unset");
+  commandName.append(encodedParameters);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  generateCommand(*command);
+
+  getFace()->onReceiveData +=
+    bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onValidatedStrategyChoiceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+
+  BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
+                    "/localhost/nfd/strategy/test-strategy-b");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/validation-common.cpp b/tests/daemon/mgmt/validation-common.cpp
new file mode 100644
index 0000000..6065c27
--- /dev/null
+++ b/tests/daemon/mgmt/validation-common.cpp
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "validation-common.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+namespace nfd {
+namespace tests {
+
+const Name CommandIdentityGlobalFixture::s_identityName("/unit-test/CommandFixture/id");
+shared_ptr<ndn::IdentityCertificate> CommandIdentityGlobalFixture::s_certificate;
+
+CommandIdentityGlobalFixture::CommandIdentityGlobalFixture()
+{
+  BOOST_ASSERT(!static_cast<bool>(s_certificate));
+  s_certificate = m_keys.getCertificate(m_keys.createIdentity(s_identityName));
+}
+
+CommandIdentityGlobalFixture::~CommandIdentityGlobalFixture()
+{
+  s_certificate.reset();
+  m_keys.deleteIdentity(s_identityName);
+}
+
+BOOST_GLOBAL_FIXTURE(CommandIdentityGlobalFixture)
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/validation-common.hpp b/tests/daemon/mgmt/validation-common.hpp
new file mode 100644
index 0000000..9aa2e28
--- /dev/null
+++ b/tests/daemon/mgmt/validation-common.hpp
@@ -0,0 +1,125 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_TESTS_NFD_MGMT_VALIDATION_COMMON_HPP
+#define NFD_TESTS_NFD_MGMT_VALIDATION_COMMON_HPP
+
+#include "common.hpp"
+#include <ndn-cpp-dev/util/command-interest-generator.hpp>
+
+namespace nfd {
+namespace tests {
+
+// class ValidatedManagementFixture
+// {
+// public:
+//   ValidatedManagementFixture()
+//     : m_validator(make_shared<ndn::CommandInterestValidator>())
+//   {
+//   }
+
+//   virtual
+//   ~ValidatedManagementFixture()
+//   {
+//   }
+
+// protected:
+//   shared_ptr<ndn::CommandInterestValidator> m_validator;
+// };
+
+/// a global fixture that holds the identity for CommandFixture
+class CommandIdentityGlobalFixture
+{
+public:
+  CommandIdentityGlobalFixture();
+
+  ~CommandIdentityGlobalFixture();
+
+  static const Name& getIdentityName()
+  {
+    return s_identityName;
+  }
+
+  static shared_ptr<ndn::IdentityCertificate> getCertificate()
+  {
+    BOOST_ASSERT(static_cast<bool>(s_certificate));
+    return s_certificate;
+  }
+
+private:
+  ndn::KeyChain m_keys;
+  static const Name s_identityName;
+  static shared_ptr<ndn::IdentityCertificate> s_certificate;
+};
+
+template<typename T>
+class CommandFixture : public T
+{
+public:
+  virtual
+  ~CommandFixture()
+  {
+  }
+
+  void
+  generateCommand(Interest& interest)
+  {
+    m_generator.generateWithIdentity(interest, getIdentityName());
+  }
+
+  const Name&
+  getIdentityName() const
+  {
+    return CommandIdentityGlobalFixture::getIdentityName();
+  }
+
+protected:
+  CommandFixture()
+    : m_certificate(CommandIdentityGlobalFixture::getCertificate())
+  {
+  }
+
+protected:
+  shared_ptr<ndn::IdentityCertificate> m_certificate;
+  ndn::CommandInterestGenerator m_generator;
+};
+
+template <typename T>
+class UnauthorizedCommandFixture : public CommandFixture<T>
+{
+public:
+  UnauthorizedCommandFixture()
+  {
+  }
+
+  virtual
+  ~UnauthorizedCommandFixture()
+  {
+  }
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_MGMT_VALIDATION_COMMON_HPP
diff --git a/tests/daemon/table/cs.cpp b/tests/daemon/table/cs.cpp
new file mode 100644
index 0000000..cdcc0db
--- /dev/null
+++ b/tests/daemon/table/cs.cpp
@@ -0,0 +1,919 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ilya Moiseenko <iliamo@ucla.edu>
+ **/
+
+#include "table/cs.hpp"
+#include "table/cs-entry.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+class CsAccessor : public Cs
+{
+public:
+  bool
+  evictItem_accessor()
+  {
+    return evictItem();
+  }
+};
+
+BOOST_FIXTURE_TEST_SUITE(TableCs, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Insertion)
+{
+  Cs cs;
+
+  BOOST_CHECK_EQUAL(cs.insert(*makeData("/insertion")), true);
+}
+
+BOOST_AUTO_TEST_CASE(Insertion2)
+{
+  Cs cs;
+
+  cs.insert(*makeData("/a"));
+  cs.insert(*makeData("/b"));
+  cs.insert(*makeData("/c"));
+  cs.insert(*makeData("/d"));
+
+  BOOST_CHECK_EQUAL(cs.size(), 4);
+}
+
+
+BOOST_AUTO_TEST_CASE(DuplicateInsertion)
+{
+  Cs cs;
+
+  shared_ptr<Data> data0 = makeData("/insert/smth");
+  BOOST_CHECK_EQUAL(cs.insert(*data0), true);
+
+  shared_ptr<Data> data = makeData("/insert/duplicate");
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+
+  cs.insert(*data);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+}
+
+
+BOOST_AUTO_TEST_CASE(DuplicateInsertion2)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/insert/duplicate");
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+
+  cs.insert(*data);
+  BOOST_CHECK_EQUAL(cs.size(), 1);
+
+  shared_ptr<Data> data2 = makeData("/insert/original");
+  BOOST_CHECK_EQUAL(cs.insert(*data2), true);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(InsertAndFind)
+{
+  Cs cs;
+
+  Name name("/insert/and/find");
+
+  shared_ptr<Data> data = makeData(name);
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+
+  shared_ptr<Interest> interest = make_shared<Interest>(name);
+
+  const Data* found = cs.find(*interest);
+
+  BOOST_REQUIRE(found != 0);
+  BOOST_CHECK_EQUAL(data->getName(), found->getName());
+}
+
+BOOST_AUTO_TEST_CASE(InsertAndNotFind)
+{
+  Cs cs;
+
+  Name name("/insert/and/find");
+  shared_ptr<Data> data = makeData(name);
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+
+  Name name2("/not/find");
+  shared_ptr<Interest> interest = make_shared<Interest>(name2);
+
+  const Data* found = cs.find(*interest);
+
+  BOOST_CHECK_EQUAL(found, static_cast<const Data*>(0));
+}
+
+
+BOOST_AUTO_TEST_CASE(InsertAndErase)
+{
+  CsAccessor cs;
+
+  shared_ptr<Data> data = makeData("/insertandelete");
+  cs.insert(*data);
+  BOOST_CHECK_EQUAL(cs.size(), 1);
+
+  cs.evictItem_accessor();
+  BOOST_CHECK_EQUAL(cs.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(StalenessQueue)
+{
+  CsAccessor cs;
+
+  Name name2("/insert/fresh");
+  shared_ptr<Data> data2 = makeData(name2);
+  data2->setFreshnessPeriod(time::milliseconds(5000));
+  cs.insert(*data2);
+
+  Name name("/insert/expire");
+  shared_ptr<Data> data = makeData(name);
+  data->setFreshnessPeriod(time::milliseconds(500));
+  cs.insert(*data);
+
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+
+  sleep(3);
+
+  cs.evictItem_accessor();
+  BOOST_CHECK_EQUAL(cs.size(), 1);
+
+  shared_ptr<Interest> interest = make_shared<Interest>(name2);
+  const Data* found = cs.find(*interest);
+  BOOST_REQUIRE(found != 0);
+  BOOST_CHECK_EQUAL(found->getName(), name2);
+}
+
+//even max size
+BOOST_AUTO_TEST_CASE(ReplacementEvenSize)
+{
+  Cs cs(4);
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/c");
+  cs.insert(*data3);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = makeData("/e");
+  cs.insert(*data5);
+
+  BOOST_CHECK_EQUAL(cs.size(), 4);
+}
+
+//odd max size
+BOOST_AUTO_TEST_CASE(Replacement2)
+{
+  Cs cs(3);
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/c");
+  cs.insert(*data3);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  BOOST_CHECK_EQUAL(cs.size(), 3);
+}
+
+BOOST_AUTO_TEST_CASE(InsertAndEraseByName)
+{
+  CsAccessor cs;
+
+  Name name("/insertandremovebyname");
+  shared_ptr<Data> data = makeData(name);
+  cs.insert(*data);
+
+  ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
+                                                    data->wireEncode().size());
+
+  shared_ptr<Data> data2 = makeData("/a");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/z");
+  cs.insert(*data3);
+
+  BOOST_CHECK_EQUAL(cs.size(), 3);
+
+  name.append(digest1->buf(), digest1->size());
+  cs.erase(name);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(DigestCalculation)
+{
+  shared_ptr<Data> data = makeData("/digest/compute");
+
+  ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
+                                                    data->wireEncode().size());
+  BOOST_CHECK_EQUAL(digest1->size(), 32);
+
+  cs::Entry* entry = new cs::Entry();
+  entry->setData(*data, false);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(digest1->begin(), digest1->end(),
+                                entry->getDigest()->begin(), entry->getDigest()->end());
+}
+
+BOOST_AUTO_TEST_CASE(InsertCanonical)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/c");
+  cs.insert(*data3);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
+  cs.insert(*data5);
+
+  shared_ptr<Data> data6 = makeData("/c/c/1/2/3");
+  cs.insert(*data6);
+
+  shared_ptr<Data> data7 = makeData("/c/c/1");
+  cs.insert(*data7);
+}
+
+BOOST_AUTO_TEST_CASE(EraseCanonical)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/c");
+  cs.insert(*data3);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
+  cs.insert(*data5);
+
+  shared_ptr<Data> data6 = makeData("/c/c/1/2/3");
+  cs.insert(*data6);
+
+  shared_ptr<Data> data7 = makeData("/c/c/1");
+  cs.insert(*data7);
+
+  ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
+                                                    data->wireEncode().size());
+
+  Name name("/a");
+  name.append(digest1->buf(), digest1->size());
+  cs.erase(name);
+  BOOST_CHECK_EQUAL(cs.size(), 6);
+}
+
+BOOST_AUTO_TEST_CASE(ImplicitDigestSelector)
+{
+  CsAccessor cs;
+
+  Name name("/digest/works");
+  shared_ptr<Data> data = makeData(name);
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/a");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/z/z/z");
+  cs.insert(*data3);
+
+  ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
+                                                    data->wireEncode().size());
+  uint8_t digest2[32] = {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1};
+
+  shared_ptr<Interest> interest = make_shared<Interest>();
+  interest->setName(Name(name).append(digest1->buf(), digest1->size()));
+  interest->setMinSuffixComponents(0);
+  interest->setMaxSuffixComponents(0);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_NE(found, static_cast<const Data*>(0));
+  BOOST_CHECK_EQUAL(found->getName(), name);
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>();
+  interest2->setName(Name(name).append(digest2, 32));
+  interest2->setMinSuffixComponents(0);
+  interest2->setMaxSuffixComponents(0);
+
+  const Data* notfound = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(notfound, static_cast<const Data*>(0));
+}
+
+BOOST_AUTO_TEST_CASE(ChildSelector)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = makeData("/c/c");
+  cs.insert(*data5);
+
+  shared_ptr<Data> data6 = makeData("/c/f");
+  cs.insert(*data6);
+
+  shared_ptr<Data> data7 = makeData("/c/n");
+  cs.insert(*data7);
+
+  shared_ptr<Interest> interest = make_shared<Interest>("/c");
+  interest->setChildSelector(1);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/c/n");
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>("/c");
+  interest2->setChildSelector(0);
+
+  const Data* found2 = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
+}
+
+BOOST_AUTO_TEST_CASE(ChildSelector2)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/a/b/1");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/a/b/2");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/a/z/1");
+  cs.insert(*data3);
+
+  shared_ptr<Data> data4 = makeData("/a/z/2");
+  cs.insert(*data4);
+
+  shared_ptr<Interest> interest = make_shared<Interest>("/a");
+  interest->setChildSelector(1);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/a/z/1");
+}
+
+BOOST_AUTO_TEST_CASE(MustBeFreshSelector)
+{
+  Cs cs;
+
+  Name name("/insert/nonfresh");
+  shared_ptr<Data> data = makeData(name);
+  data->setFreshnessPeriod(time::milliseconds(500));
+  cs.insert(*data);
+
+  sleep(1);
+
+  shared_ptr<Interest> interest = make_shared<Interest>(name);
+  interest->setMustBeFresh(true);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found, static_cast<const Data*>(0));
+}
+
+BOOST_AUTO_TEST_CASE(PublisherKeySelector)
+{
+  Cs cs;
+
+  Name name("/insert/withkey");
+  shared_ptr<Data> data = makeData(name);
+  cs.insert(*data);
+
+  shared_ptr<Interest> interest = make_shared<Interest>(name);
+  Name keyName("/somewhere/key");
+
+  ndn::KeyLocator locator(keyName);
+  interest->setPublisherPublicKeyLocator(locator);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found, static_cast<const Data*>(0));
+}
+
+BOOST_AUTO_TEST_CASE(PublisherKeySelector2)
+{
+  Cs cs;
+  Name name("/insert/withkey");
+  shared_ptr<Data> data = makeData(name);
+  cs.insert(*data);
+
+  Name name2("/insert/withkey2");
+  shared_ptr<Data> data2 = make_shared<Data>(name2);
+
+  Name keyName("/somewhere/key");
+  const ndn::KeyLocator locator(keyName);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
+                                        reinterpret_cast<const uint8_t*>(0), 0));
+
+  fakeSignature.setKeyLocator(locator);
+  data2->setSignature(fakeSignature);
+
+  cs.insert(*data2);
+
+  shared_ptr<Interest> interest = make_shared<Interest>(name2);
+  interest->setPublisherPublicKeyLocator(locator);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_NE(found, static_cast<const Data*>(0));
+  BOOST_CHECK_EQUAL(found->getName(), data2->getName());
+}
+
+
+BOOST_AUTO_TEST_CASE(MinMaxComponentsSelector)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
+  cs.insert(*data5);
+
+  shared_ptr<Data> data6 = makeData("/c/c/6/7/8/9");
+  cs.insert(*data6);
+
+  shared_ptr<Data> data7 = makeData("/c/c/1/2/3");
+  cs.insert(*data7);
+
+  shared_ptr<Data> data8 = makeData("/c/c/1");
+  cs.insert(*data8);
+
+  shared_ptr<Interest> interest = make_shared<Interest>("/c/c");
+  interest->setMinSuffixComponents(3);
+  interest->setChildSelector(0);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/c/c/1/2/3/4/5/6");
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>("/c/c");
+  interest2->setMinSuffixComponents(4);
+  interest2->setChildSelector(1);
+
+  const Data* found2 = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(found2->getName(), "/c/c/6/7/8/9");
+
+  shared_ptr<Interest> interest3 = make_shared<Interest>("/c/c");
+  interest3->setMaxSuffixComponents(2);
+  interest3->setChildSelector(1);
+
+  const Data* found3 = cs.find(*interest3);
+  BOOST_CHECK_EQUAL(found3->getName(), "/c/c/1");
+}
+
+BOOST_AUTO_TEST_CASE(ExcludeSelector)
+{
+  Cs cs;
+
+  shared_ptr<Data> data = makeData("/a");
+  cs.insert(*data);
+
+  shared_ptr<Data> data2 = makeData("/b");
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = makeData("/c/a");
+  cs.insert(*data3);
+
+  shared_ptr<Data> data4 = makeData("/d");
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = makeData("/c/c");
+  cs.insert(*data5);
+
+  shared_ptr<Data> data6 = makeData("/c/f");
+  cs.insert(*data6);
+
+  shared_ptr<Data> data7 = makeData("/c/n");
+  cs.insert(*data7);
+
+  shared_ptr<Interest> interest = make_shared<Interest>("/c");
+  interest->setChildSelector(1);
+  Exclude e;
+  e.excludeOne (Name::Component("n"));
+  interest->setExclude(e);
+
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/c/f");
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>("/c");
+  interest2->setChildSelector(0);
+
+  Exclude e2;
+  e2.excludeOne (Name::Component("a"));
+  interest2->setExclude(e2);
+
+  const Data* found2 = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
+
+  shared_ptr<Interest> interest3 = make_shared<Interest>("/c");
+  interest3->setChildSelector(0);
+
+  Exclude e3;
+  e3.excludeOne (Name::Component("c"));
+  interest3->setExclude(e3);
+
+  const Data* found3 = cs.find(*interest3);
+  BOOST_CHECK_EQUAL(found3->getName(), "/c/a");
+}
+
+//
+
+class FindFixture : protected BaseFixture
+{
+protected:
+  void
+  insert(uint32_t id, const Name& name)
+  {
+    shared_ptr<Data> data = makeData(name);
+    data->setFreshnessPeriod(time::milliseconds(99999));
+    data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
+
+    m_cs.insert(*data);
+  }
+
+  Interest&
+  startInterest(const Name& name)
+  {
+    m_interest = make_shared<Interest>(name);
+    return *m_interest;
+  }
+
+  uint32_t
+  find()
+  {
+    const Data* found = m_cs.find(*m_interest);
+    if (found == 0) {
+      return 0;
+    }
+    const Block& content = found->getContent();
+    if (content.value_size() != sizeof(uint32_t)) {
+      return 0;
+    }
+    return *reinterpret_cast<const uint32_t*>(content.value());
+  }
+
+protected:
+  Cs m_cs;
+  shared_ptr<Interest> m_interest;
+};
+
+BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
+
+BOOST_AUTO_TEST_CASE(EmptyDataName)
+{
+  insert(1, "ndn:/");
+
+  startInterest("ndn:/");
+  BOOST_CHECK_EQUAL(find(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(EmptyInterestName)
+{
+  insert(1, "ndn:/A");
+
+  startInterest("ndn:/");
+  BOOST_CHECK_EQUAL(find(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(Leftmost)
+{
+  insert(1, "ndn:/A");
+  insert(2, "ndn:/B/p/1");
+  insert(3, "ndn:/B/p/2");
+  insert(4, "ndn:/B/q/1");
+  insert(5, "ndn:/B/q/2");
+  insert(6, "ndn:/C");
+
+  startInterest("ndn:/B");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(Rightmost)
+{
+  insert(1, "ndn:/A");
+  insert(2, "ndn:/B/p/1");
+  insert(3, "ndn:/B/p/2");
+  insert(4, "ndn:/B/q/1");
+  insert(5, "ndn:/B/q/2");
+  insert(6, "ndn:/C");
+
+  startInterest("ndn:/B")
+    .setChildSelector(1);
+  BOOST_CHECK_EQUAL(find(), 4);
+}
+
+BOOST_AUTO_TEST_CASE(Leftmost_ExactName1)
+{
+  insert(1, "ndn:/");
+  insert(2, "ndn:/A/B");
+  insert(3, "ndn:/A/C");
+  insert(4, "ndn:/A");
+  insert(5, "ndn:/D");
+
+  // Intuitively you would think Data 4 should be between Data 1 and 2,
+  // but Data 4 has full Name ndn:/A/<32-octet hash>.
+  startInterest("ndn:/A");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(Leftmost_ExactName33)
+{
+  insert(1, "ndn:/");
+  insert(2, "ndn:/A");
+  insert(3, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 33 'B's
+  insert(4, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
+  insert(5, "ndn:/D");
+
+  // Data 2 is returned, because <32-octet hash> is less than Data 3.
+  startInterest("ndn:/A");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(MinSuffixComponents)
+{
+  insert(1, "ndn:/A/1/2/3/4");
+  insert(2, "ndn:/B/1/2/3");
+  insert(3, "ndn:/C/1/2");
+  insert(4, "ndn:/D/1");
+  insert(5, "ndn:/E");
+  insert(6, "ndn:/");
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(0);
+  BOOST_CHECK_EQUAL(find(), 6);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(1);
+  BOOST_CHECK_EQUAL(find(), 6);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(2);
+  BOOST_CHECK_EQUAL(find(), 5);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(3);
+  BOOST_CHECK_EQUAL(find(), 4);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(4);
+  BOOST_CHECK_EQUAL(find(), 3);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(5);
+  BOOST_CHECK_EQUAL(find(), 2);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(6);
+  BOOST_CHECK_EQUAL(find(), 1);
+
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(7);
+  BOOST_CHECK_EQUAL(find(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
+{
+  insert(1, "ndn:/");
+  insert(2, "ndn:/A");
+  insert(3, "ndn:/A/B");
+  insert(4, "ndn:/A/B/C");
+  insert(5, "ndn:/A/B/C/D");
+  insert(6, "ndn:/A/B/C/D/E");
+  // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(0);
+  BOOST_CHECK_EQUAL(find(), 0);
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(1);
+  BOOST_CHECK_EQUAL(find(), 1);
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(2);
+  BOOST_CHECK_EQUAL(find(), 2);
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(3);
+  BOOST_CHECK_EQUAL(find(), 3);
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(4);
+  BOOST_CHECK_EQUAL(find(), 4);
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(5);
+  BOOST_CHECK_EQUAL(find(), 5);
+
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(6);
+  BOOST_CHECK_EQUAL(find(), 6);
+}
+
+BOOST_AUTO_TEST_CASE(DigestOrder)
+{
+  insert(1, "ndn:/A");
+  insert(2, "ndn:/A");
+  // We don't know which comes first, but there must be some order
+
+  startInterest("ndn:/A")
+    .setChildSelector(0);
+  uint32_t leftmost = find();
+
+  startInterest("ndn:/A")
+    .setChildSelector(1);
+  uint32_t rightmost = find();
+
+  BOOST_CHECK_NE(leftmost, rightmost);
+}
+
+BOOST_AUTO_TEST_CASE(DigestExclude)
+{
+  insert(1, "ndn:/A/B");
+  insert(2, "ndn:/A");
+  insert(3, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
+
+  startInterest("ndn:/A")
+    .setExclude(Exclude().excludeBefore(name::Component(reinterpret_cast<const uint8_t*>(
+        "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+        "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"), 31))); // 31 0xFF's
+  BOOST_CHECK_EQUAL(find(), 2);
+
+  startInterest("ndn:/A")
+    .setChildSelector(1)
+    .setExclude(Exclude().excludeAfter(name::Component(reinterpret_cast<const uint8_t*>(
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00"), 33))); // 33 0x00's
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(ExactName32)
+{
+  insert(1, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 32 'B's
+  insert(2, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 32 'C's
+
+  startInterest("ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
+  BOOST_CHECK_EQUAL(find(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(MinSuffixComponents32)
+{
+  insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/1/2/3/4"); // 32 'x's
+  insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B/1/2/3");
+  insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/C/1/2");
+  insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/D/1");
+  insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/E");
+  insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(0);
+  BOOST_CHECK_EQUAL(find(), 6);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(1);
+  BOOST_CHECK_EQUAL(find(), 6);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(2);
+  BOOST_CHECK_EQUAL(find(), 5);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(3);
+  BOOST_CHECK_EQUAL(find(), 4);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(4);
+  BOOST_CHECK_EQUAL(find(), 3);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(5);
+  BOOST_CHECK_EQUAL(find(), 2);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(6);
+  BOOST_CHECK_EQUAL(find(), 1);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setChildSelector(1)
+    .setMinSuffixComponents(7);
+  BOOST_CHECK_EQUAL(find(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(MaxSuffixComponents32)
+{
+  insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/"); // 32 'x's
+  insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A");
+  insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B");
+  insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C");
+  insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D");
+  insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D/E");
+  // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(0);
+  BOOST_CHECK_EQUAL(find(), 0);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(1);
+  BOOST_CHECK_EQUAL(find(), 1);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(2);
+  BOOST_CHECK_EQUAL(find(), 2);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(3);
+  BOOST_CHECK_EQUAL(find(), 3);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(4);
+  BOOST_CHECK_EQUAL(find(), 4);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(5);
+  BOOST_CHECK_EQUAL(find(), 5);
+
+  startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+    .setMaxSuffixComponents(6);
+  BOOST_CHECK_EQUAL(find(), 6);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Find
+
+BOOST_AUTO_TEST_SUITE_END() // TableCs
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/fib.cpp b/tests/daemon/table/fib.cpp
new file mode 100644
index 0000000..bdf2fca
--- /dev/null
+++ b/tests/daemon/table/fib.cpp
@@ -0,0 +1,381 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/fib.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TableFib, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Entry)
+{
+  Name prefix("ndn:/pxWhfFza");
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+
+  fib::Entry entry(prefix);
+  BOOST_CHECK_EQUAL(entry.getPrefix(), prefix);
+
+  const fib::NextHopList& nexthops1 = entry.getNextHops();
+  // []
+  BOOST_CHECK_EQUAL(nexthops1.size(), 0);
+
+  entry.addNextHop(face1, 20);
+  const fib::NextHopList& nexthops2 = entry.getNextHops();
+  // [(face1,20)]
+  BOOST_CHECK_EQUAL(nexthops2.size(), 1);
+  BOOST_CHECK_EQUAL(nexthops2.begin()->getFace(), face1);
+  BOOST_CHECK_EQUAL(nexthops2.begin()->getCost(), 20);
+
+  entry.addNextHop(face1, 30);
+  const fib::NextHopList& nexthops3 = entry.getNextHops();
+  // [(face1,30)]
+  BOOST_CHECK_EQUAL(nexthops3.size(), 1);
+  BOOST_CHECK_EQUAL(nexthops3.begin()->getFace(), face1);
+  BOOST_CHECK_EQUAL(nexthops3.begin()->getCost(), 30);
+
+  entry.addNextHop(face2, 40);
+  const fib::NextHopList& nexthops4 = entry.getNextHops();
+  // [(face1,30), (face2,40)]
+  BOOST_CHECK_EQUAL(nexthops4.size(), 2);
+  int i = -1;
+  for (fib::NextHopList::const_iterator it = nexthops4.begin();
+    it != nexthops4.end(); ++it) {
+    ++i;
+    switch (i) {
+      case 0 :
+        BOOST_CHECK_EQUAL(it->getFace(), face1);
+        BOOST_CHECK_EQUAL(it->getCost(), 30);
+        break;
+      case 1 :
+        BOOST_CHECK_EQUAL(it->getFace(), face2);
+        BOOST_CHECK_EQUAL(it->getCost(), 40);
+        break;
+    }
+  }
+
+  entry.addNextHop(face2, 10);
+  const fib::NextHopList& nexthops5 = entry.getNextHops();
+  // [(face2,10), (face1,30)]
+  BOOST_CHECK_EQUAL(nexthops5.size(), 2);
+  i = -1;
+  for (fib::NextHopList::const_iterator it = nexthops5.begin();
+    it != nexthops5.end(); ++it) {
+    ++i;
+    switch (i) {
+      case 0 :
+        BOOST_CHECK_EQUAL(it->getFace(), face2);
+        BOOST_CHECK_EQUAL(it->getCost(), 10);
+        break;
+      case 1 :
+        BOOST_CHECK_EQUAL(it->getFace(), face1);
+        BOOST_CHECK_EQUAL(it->getCost(), 30);
+        break;
+    }
+  }
+
+  entry.removeNextHop(face1);
+  const fib::NextHopList& nexthops6 = entry.getNextHops();
+  // [(face2,10)]
+  BOOST_CHECK_EQUAL(nexthops6.size(), 1);
+  BOOST_CHECK_EQUAL(nexthops6.begin()->getFace(), face2);
+  BOOST_CHECK_EQUAL(nexthops6.begin()->getCost(), 10);
+
+  entry.removeNextHop(face1);
+  const fib::NextHopList& nexthops7 = entry.getNextHops();
+  // [(face2,10)]
+  BOOST_CHECK_EQUAL(nexthops7.size(), 1);
+  BOOST_CHECK_EQUAL(nexthops7.begin()->getFace(), face2);
+  BOOST_CHECK_EQUAL(nexthops7.begin()->getCost(), 10);
+
+  entry.removeNextHop(face2);
+  const fib::NextHopList& nexthops8 = entry.getNextHops();
+  // []
+  BOOST_CHECK_EQUAL(nexthops8.size(), 0);
+
+  entry.removeNextHop(face2);
+  const fib::NextHopList& nexthops9 = entry.getNextHops();
+  // []
+  BOOST_CHECK_EQUAL(nexthops9.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(Insert_LongestPrefixMatch)
+{
+  Name nameEmpty;
+  Name nameA   ("ndn:/A");
+  Name nameAB  ("ndn:/A/B");
+  Name nameABC ("ndn:/A/B/C");
+  Name nameABCD("ndn:/A/B/C/D");
+  Name nameE   ("ndn:/E");
+
+  std::pair<shared_ptr<fib::Entry>, bool> insertRes;
+  shared_ptr<fib::Entry> entry;
+
+  NameTree nameTree;
+  Fib fib(nameTree);
+  // []
+  BOOST_CHECK_EQUAL(fib.size(), 0);
+
+  entry = fib.findLongestPrefixMatch(nameA);
+  BOOST_REQUIRE(static_cast<bool>(entry)); // the empty entry
+
+  insertRes = fib.insert(nameEmpty);
+  BOOST_CHECK_EQUAL(insertRes.second, true);
+  BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameEmpty);
+  // ['/']
+  BOOST_CHECK_EQUAL(fib.size(), 1);
+
+  entry = fib.findLongestPrefixMatch(nameA);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
+
+  insertRes = fib.insert(nameA);
+  BOOST_CHECK_EQUAL(insertRes.second, true);
+  BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
+  // ['/', '/A']
+  BOOST_CHECK_EQUAL(fib.size(), 2);
+
+  insertRes = fib.insert(nameA);
+  BOOST_CHECK_EQUAL(insertRes.second, false);
+  BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
+  // ['/', '/A']
+  BOOST_CHECK_EQUAL(fib.size(), 2);
+
+  entry = fib.findLongestPrefixMatch(nameA);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
+
+  entry = fib.findLongestPrefixMatch(nameABCD);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
+
+  insertRes = fib.insert(nameABC);
+  BOOST_CHECK_EQUAL(insertRes.second, true);
+  BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameABC);
+  // ['/', '/A', '/A/B/C']
+  BOOST_CHECK_EQUAL(fib.size(), 3);
+
+  entry = fib.findLongestPrefixMatch(nameA);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
+
+  entry = fib.findLongestPrefixMatch(nameAB);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
+
+  entry = fib.findLongestPrefixMatch(nameABCD);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameABC);
+
+  entry = fib.findLongestPrefixMatch(nameE);
+  BOOST_REQUIRE(static_cast<bool>(entry));
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
+}
+
+BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
+{
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+  Name nameEmpty("ndn:/");
+  Name nameA("ndn:/A");
+  Name nameB("ndn:/B");
+
+  std::pair<shared_ptr<fib::Entry>, bool> insertRes;
+  shared_ptr<fib::Entry> entry;
+
+  NameTree nameTree;
+  Fib fib(nameTree);
+  // {}
+
+  insertRes = fib.insert(nameA);
+  insertRes.first->addNextHop(face1, 0);
+  insertRes.first->addNextHop(face2, 0);
+  // {'/A':[1,2]}
+
+  insertRes = fib.insert(nameB);
+  insertRes.first->addNextHop(face1, 0);
+  // {'/A':[1,2], '/B':[1]}
+  BOOST_CHECK_EQUAL(fib.size(), 2);
+
+  fib.removeNextHopFromAllEntries(face1);
+  // {'/A':[2]}
+  BOOST_CHECK_EQUAL(fib.size(), 1);
+
+  entry = fib.findLongestPrefixMatch(nameA);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
+  const fib::NextHopList& nexthopsA = entry->getNextHops();
+  BOOST_CHECK_EQUAL(nexthopsA.size(), 1);
+  BOOST_CHECK_EQUAL(nexthopsA.begin()->getFace(), face2);
+
+  entry = fib.findLongestPrefixMatch(nameB);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
+}
+
+void
+validateFindExactMatch(const Fib& fib, const Name& target)
+{
+  shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
+  if (static_cast<bool>(entry))
+    {
+      BOOST_CHECK_EQUAL(entry->getPrefix(), target);
+    }
+  else
+    {
+      BOOST_FAIL("No entry found for " << target);
+    }
+}
+
+void
+validateNoExactMatch(const Fib& fib, const Name& target)
+{
+  shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
+  if (static_cast<bool>(entry))
+    {
+      BOOST_FAIL("Found unexpected entry for " << target);
+    }
+}
+
+BOOST_AUTO_TEST_CASE(FindExactMatch)
+{
+  NameTree nameTree;
+  Fib fib(nameTree);
+  fib.insert("/A");
+  fib.insert("/A/B");
+  fib.insert("/A/B/C");
+
+  validateFindExactMatch(fib, "/A");
+  validateFindExactMatch(fib, "/A/B");
+  validateFindExactMatch(fib, "/A/B/C");
+  validateNoExactMatch(fib, "/");
+
+  validateNoExactMatch(fib, "/does/not/exist");
+
+  NameTree gapNameTree;
+  Fib gapFib(nameTree);
+  fib.insert("/X");
+  fib.insert("/X/Y/Z");
+
+  validateNoExactMatch(gapFib, "/X/Y");
+
+  NameTree emptyNameTree;
+  Fib emptyFib(emptyNameTree);
+  validateNoExactMatch(emptyFib, "/nothing/here");
+}
+
+void
+validateRemove(Fib& fib, const Name& target)
+{
+  fib.erase(target);
+
+  shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
+  if (static_cast<bool>(entry))
+    {
+      BOOST_FAIL("Found \"removed\" entry for " << target);
+    }
+}
+
+BOOST_AUTO_TEST_CASE(Remove)
+{
+  NameTree emptyNameTree;
+  Fib emptyFib(emptyNameTree);
+
+  emptyFib.erase("/does/not/exist"); // crash test
+
+  validateRemove(emptyFib, "/");
+
+  emptyFib.erase("/still/does/not/exist"); // crash test
+
+  NameTree nameTree;
+  Fib fib(nameTree);
+  fib.insert("/");
+  fib.insert("/A");
+  fib.insert("/A/B");
+  fib.insert("/A/B/C");
+
+  // check if we remove the right thing and leave
+  // everything else alone
+
+  validateRemove(fib, "/A/B");
+  validateFindExactMatch(fib, "/A");
+  validateFindExactMatch(fib, "/A/B/C");
+  validateFindExactMatch(fib, "/");
+
+  validateRemove(fib, "/A/B/C");
+  validateFindExactMatch(fib, "/A");
+  validateFindExactMatch(fib, "/");
+
+  validateRemove(fib, "/A");
+  validateFindExactMatch(fib, "/");
+
+  validateRemove(fib, "/");
+  validateNoExactMatch(fib, "/");
+
+  NameTree gapNameTree;
+  Fib gapFib(gapNameTree);
+  gapFib.insert("/X");
+  gapFib.insert("/X/Y/Z");
+
+  gapFib.erase("/X/Y"); //should do nothing
+  validateFindExactMatch(gapFib, "/X");
+  validateFindExactMatch(gapFib, "/X/Y/Z");
+}
+
+BOOST_AUTO_TEST_CASE(Iterator)
+{
+  NameTree nameTree;
+  Fib fib(nameTree);
+  Name nameA("/A");
+  Name nameAB("/A/B");
+  Name nameABC("/A/B/C");
+  Name nameRoot("/");
+
+  fib.insert(nameA);
+  fib.insert(nameAB);
+  fib.insert(nameABC);
+  fib.insert(nameRoot);
+
+  std::set<Name> expected;
+  expected.insert(nameA);
+  expected.insert(nameAB);
+  expected.insert(nameABC);
+  expected.insert(nameRoot);
+
+  for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++)
+  {
+    bool isInSet = expected.find(it->getPrefix()) != expected.end();
+    BOOST_CHECK(isInSet);
+    expected.erase(it->getPrefix());
+  }
+
+  BOOST_CHECK_EQUAL(expected.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/measurements-accessor.cpp b/tests/daemon/table/measurements-accessor.cpp
new file mode 100644
index 0000000..6dc8ff3
--- /dev/null
+++ b/tests/daemon/table/measurements-accessor.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/measurements-accessor.hpp"
+#include "fw/strategy.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TableMeasurementsAccessor, BaseFixture)
+
+class MeasurementsAccessorTestStrategy : public fw::Strategy
+{
+public:
+  MeasurementsAccessorTestStrategy(Forwarder& forwarder, const Name& name)
+    : Strategy(forwarder, name)
+  {
+  }
+
+  virtual
+  ~MeasurementsAccessorTestStrategy()
+
+  {
+  }
+
+  virtual void
+  afterReceiveInterest(const Face& inFace,
+                       const Interest& interest,
+                       shared_ptr<fib::Entry> fibEntry,
+                       shared_ptr<pit::Entry> pitEntry)
+  {
+    BOOST_ASSERT(false);
+  }
+
+public: // accessors
+  MeasurementsAccessor&
+  getMeasurements_accessor()
+  {
+    return this->getMeasurements();
+  }
+};
+
+BOOST_AUTO_TEST_CASE(Access)
+{
+  Forwarder forwarder;
+
+  shared_ptr<MeasurementsAccessorTestStrategy> strategy1 =
+    make_shared<MeasurementsAccessorTestStrategy>(boost::ref(forwarder), "ndn:/strategy1");
+  shared_ptr<MeasurementsAccessorTestStrategy> strategy2 =
+    make_shared<MeasurementsAccessorTestStrategy>(boost::ref(forwarder), "ndn:/strategy2");
+
+  Name nameRoot("ndn:/");
+  Name nameA   ("ndn:/A");
+  Name nameAB  ("ndn:/A/B");
+  Name nameABC ("ndn:/A/B/C");
+  Name nameAD  ("ndn:/A/D");
+
+  StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
+  strategyChoice.install(strategy1);
+  strategyChoice.install(strategy2);
+  strategyChoice.insert(nameRoot, strategy1->getName());
+  strategyChoice.insert(nameA   , strategy2->getName());
+  strategyChoice.insert(nameAB  , strategy1->getName());
+
+  MeasurementsAccessor& accessor1 = strategy1->getMeasurements_accessor();
+  MeasurementsAccessor& accessor2 = strategy2->getMeasurements_accessor();
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor1.get(nameRoot)), true);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor1.get(nameA   )), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor1.get(nameAB  )), true);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor1.get(nameABC )), true);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor1.get(nameAD  )), false);
+
+  shared_ptr<measurements::Entry> entryRoot = forwarder.getMeasurements().get(nameRoot);
+  BOOST_CHECK_NO_THROW(accessor1.getParent(entryRoot));
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor2.get(nameRoot)), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor2.get(nameA   )), true);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor2.get(nameAB  )), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor2.get(nameABC )), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(accessor2.get(nameAD  )), true);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/measurements.cpp b/tests/daemon/table/measurements.cpp
new file mode 100644
index 0000000..98676b5
--- /dev/null
+++ b/tests/daemon/table/measurements.cpp
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/measurements.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TableMeasurements, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Get_Parent)
+{
+  NameTree nameTree;
+  Measurements measurements(nameTree);
+
+  Name name0;
+  Name nameA ("ndn:/A");
+  Name nameAB("ndn:/A/B");
+
+  shared_ptr<measurements::Entry> entryAB = measurements.get(nameAB);
+  BOOST_REQUIRE(static_cast<bool>(entryAB));
+  BOOST_CHECK_EQUAL(entryAB->getName(), nameAB);
+
+  shared_ptr<measurements::Entry> entry0 = measurements.get(name0);
+  BOOST_REQUIRE(static_cast<bool>(entry0));
+
+  shared_ptr<measurements::Entry> entryA = measurements.getParent(entryAB);
+  BOOST_REQUIRE(static_cast<bool>(entryA));
+  BOOST_CHECK_EQUAL(entryA->getName(), nameA);
+
+  shared_ptr<measurements::Entry> entry0c = measurements.getParent(entryA);
+  BOOST_CHECK_EQUAL(entry0, entry0c);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/name-tree.cpp b/tests/daemon/table/name-tree.cpp
new file mode 100644
index 0000000..e5e9089
--- /dev/null
+++ b/tests/daemon/table/name-tree.cpp
@@ -0,0 +1,801 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/name-tree.hpp"
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+using name_tree::Entry;
+
+BOOST_FIXTURE_TEST_SUITE(TableNameTree, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Hash)
+{
+  Name root("/");
+  root.wireEncode();
+  size_t hashValue = name_tree::computeHash(root);
+  BOOST_CHECK_EQUAL(hashValue, static_cast<size_t>(0));
+
+  Name prefix("/nohello/world/ndn/research");
+  prefix.wireEncode();
+  std::vector<size_t> hashSet = name_tree::computeHashSet(prefix);
+  BOOST_CHECK_EQUAL(hashSet.size(), prefix.size() + 1);
+}
+
+BOOST_AUTO_TEST_CASE(Entry)
+{
+  Name prefix("ndn:/named-data/research/abc/def/ghi");
+
+  shared_ptr<name_tree::Entry> npe = make_shared<name_tree::Entry>(prefix);
+  BOOST_CHECK_EQUAL(npe->getPrefix(), prefix);
+
+  // examine all the get methods
+
+  size_t hash = npe->getHash();
+  BOOST_CHECK_EQUAL(hash, static_cast<size_t>(0));
+
+  shared_ptr<name_tree::Entry> parent = npe->getParent();
+  BOOST_CHECK(!static_cast<bool>(parent));
+
+  std::vector<shared_ptr<name_tree::Entry> >& childList = npe->getChildren();
+  BOOST_CHECK_EQUAL(childList.size(), static_cast<size_t>(0));
+
+  shared_ptr<fib::Entry> fib = npe->getFibEntry();
+  BOOST_CHECK(!static_cast<bool>(fib));
+
+  const std::vector< shared_ptr<pit::Entry> >& pitList = npe->getPitEntries();
+  BOOST_CHECK_EQUAL(pitList.size(), static_cast<size_t>(0));
+
+  // examine all the set method
+
+  npe->setHash(static_cast<size_t>(12345));
+  BOOST_CHECK_EQUAL(npe->getHash(), static_cast<size_t>(12345));
+
+  Name parentName("ndn:/named-data/research/abc/def");
+  parent = make_shared<name_tree::Entry>(parentName);
+  npe->setParent(parent);
+  BOOST_CHECK_EQUAL(npe->getParent(), parent);
+
+  // Insert FIB
+
+  shared_ptr<fib::Entry> fibEntry(new fib::Entry(prefix));
+  shared_ptr<fib::Entry> fibEntryParent(new fib::Entry(parentName));
+
+  npe->setFibEntry(fibEntry);
+  BOOST_CHECK_EQUAL(npe->getFibEntry(), fibEntry);
+
+  npe->setFibEntry(shared_ptr<fib::Entry>());
+  BOOST_CHECK(!static_cast<bool>(npe->getFibEntry()));
+
+  // Insert a PIT
+
+  shared_ptr<pit::Entry> PitEntry(make_shared<pit::Entry>(prefix));
+  shared_ptr<pit::Entry> PitEntry2(make_shared<pit::Entry>(parentName));
+
+  npe->insertPitEntry(PitEntry);
+  BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 1);
+
+  npe->insertPitEntry(PitEntry2);
+  BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 2);
+
+  npe->erasePitEntry(PitEntry);
+  BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 1);
+
+  npe->erasePitEntry(PitEntry2);
+  BOOST_CHECK_EQUAL(npe->getPitEntries().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(NameTreeBasic)
+{
+  size_t nBuckets = 16;
+  NameTree nt(nBuckets);
+
+  BOOST_CHECK_EQUAL(nt.size(), 0);
+  BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
+
+  Name nameABC("ndn:/a/b/c");
+  shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
+  BOOST_CHECK_EQUAL(nt.size(), 4);
+
+  Name nameABD("/a/b/d");
+  shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
+  BOOST_CHECK_EQUAL(nt.size(), 5);
+
+  Name nameAE("/a/e/");
+  shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
+  BOOST_CHECK_EQUAL(nt.size(), 6);
+
+  Name nameF("/f");
+  shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  // validate lookup() and findExactMatch()
+
+  Name nameAB ("/a/b");
+  BOOST_CHECK_EQUAL(npeABC->getParent(), nt.findExactMatch(nameAB));
+  BOOST_CHECK_EQUAL(npeABD->getParent(), nt.findExactMatch(nameAB));
+
+  Name nameA ("/a");
+  BOOST_CHECK_EQUAL(npeAE->getParent(), nt.findExactMatch(nameA));
+
+  Name nameRoot ("/");
+  BOOST_CHECK_EQUAL(npeF->getParent(), nt.findExactMatch(nameRoot));
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  Name name0("/does/not/exist");
+  shared_ptr<name_tree::Entry> npe0 = nt.findExactMatch(name0);
+  BOOST_CHECK(!static_cast<bool>(npe0));
+
+
+  // Longest Prefix Matching
+  shared_ptr<name_tree::Entry> temp;
+  Name nameABCLPM("/a/b/c/def/asdf/nlf");
+  temp = nt.findLongestPrefixMatch(nameABCLPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABC));
+
+  Name nameABDLPM("/a/b/d/def/asdf/nlf");
+  temp = nt.findLongestPrefixMatch(nameABDLPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABD));
+
+  Name nameABLPM("/a/b/hello/world");
+  temp = nt.findLongestPrefixMatch(nameABLPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAB));
+
+  Name nameAELPM("/a/e/hello/world");
+  temp = nt.findLongestPrefixMatch(nameAELPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAE));
+
+  Name nameALPM("/a/hello/world");
+  temp = nt.findLongestPrefixMatch(nameALPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameA));
+
+  Name nameFLPM("/f/hello/world");
+  temp = nt.findLongestPrefixMatch(nameFLPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameF));
+
+  Name nameRootLPM("/does_not_exist");
+  temp = nt.findLongestPrefixMatch(nameRootLPM);
+  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameRoot));
+
+  bool eraseResult = false;
+  temp = nt.findExactMatch(nameABC);
+  if (static_cast<bool>(temp))
+    eraseResult = nt.
+  eraseEntryIfEmpty(temp);
+  BOOST_CHECK_EQUAL(nt.size(), 6);
+  BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
+  BOOST_CHECK_EQUAL(eraseResult, true);
+
+  eraseResult = false;
+  temp = nt.findExactMatch(nameABCLPM);
+  if (static_cast<bool>(temp))
+    eraseResult = nt.
+  eraseEntryIfEmpty(temp);
+  BOOST_CHECK(!static_cast<bool>(temp));
+  BOOST_CHECK_EQUAL(nt.size(), 6);
+  BOOST_CHECK_EQUAL(eraseResult, false);
+
+  // nt.dump(std::cout);
+
+  nt.lookup(nameABC);
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  eraseResult = false;
+  temp = nt.findExactMatch(nameABC);
+  if (static_cast<bool>(temp))
+    eraseResult = nt.
+  eraseEntryIfEmpty(temp);
+  BOOST_CHECK_EQUAL(nt.size(), 6);
+  BOOST_CHECK_EQUAL(eraseResult, true);
+  BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
+
+  BOOST_CHECK_EQUAL(nt.getNBuckets(), 16);
+
+  // should resize now
+  Name nameABCD("a/b/c/d");
+  nt.lookup(nameABCD);
+  Name nameABCDE("a/b/c/d/e");
+  nt.lookup(nameABCDE);
+  BOOST_CHECK_EQUAL(nt.size(), 9);
+  BOOST_CHECK_EQUAL(nt.getNBuckets(), 32);
+
+  // try to erase /a/b/c, should return false
+  temp = nt.findExactMatch(nameABC);
+  BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
+  eraseResult = nt.
+  eraseEntryIfEmpty(temp);
+  BOOST_CHECK_EQUAL(eraseResult, false);
+  temp = nt.findExactMatch(nameABC);
+  BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
+
+  temp = nt.findExactMatch(nameABD);
+  if (static_cast<bool>(temp))
+    nt.
+  eraseEntryIfEmpty(temp);
+  BOOST_CHECK_EQUAL(nt.size(), 8);
+}
+
+BOOST_AUTO_TEST_CASE(NameTreeIteratorFullEnumerate)
+{
+  size_t nBuckets = 1024;
+  NameTree nt(nBuckets);
+
+  BOOST_CHECK_EQUAL(nt.size(), 0);
+  BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
+
+  Name nameABC("ndn:/a/b/c");
+  shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
+  BOOST_CHECK_EQUAL(nt.size(), 4);
+
+  Name nameABD("/a/b/d");
+  shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
+  BOOST_CHECK_EQUAL(nt.size(), 5);
+
+  Name nameAE("/a/e/");
+  shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
+  BOOST_CHECK_EQUAL(nt.size(), 6);
+
+  Name nameF("/f");
+  shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  Name nameRoot("/");
+  shared_ptr<name_tree::Entry> npeRoot = nt.lookup(nameRoot);
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  Name nameA("/a");
+  Name nameAB("/a/b");
+
+  bool hasRoot  = false;
+  bool hasA     = false;
+  bool hasAB    = false;
+  bool hasABC   = false;
+  bool hasABD   = false;
+  bool hasAE    = false;
+  bool hasF     = false;
+
+  int counter = 0;
+  NameTree::const_iterator it = nt.fullEnumerate();
+
+  for(; it != nt.end(); it++)
+  {
+    counter++;
+
+    if (it->getPrefix() == nameRoot)
+      hasRoot = true;
+    if (it->getPrefix() == nameA)
+      hasA    = true;
+    if (it->getPrefix() == nameAB)
+      hasAB   = true;
+    if (it->getPrefix() == nameABC)
+      hasABC  = true;
+    if (it->getPrefix() == nameABD)
+      hasABD  = true;
+    if (it->getPrefix() == nameAE)
+      hasAE   = true;
+    if (it->getPrefix() == nameF)
+      hasF    = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasRoot , true);
+  BOOST_CHECK_EQUAL(hasA    , true);
+  BOOST_CHECK_EQUAL(hasAB   , true);
+  BOOST_CHECK_EQUAL(hasABC  , true);
+  BOOST_CHECK_EQUAL(hasABD  , true);
+  BOOST_CHECK_EQUAL(hasAE   , true);
+  BOOST_CHECK_EQUAL(hasF    , true);
+
+  BOOST_CHECK_EQUAL(counter , 7);
+}
+
+// Predicates for testing the partial enumerate function
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NameA_Only(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  bool first = nameA.equals(entry.getPrefix());
+  return std::make_pair(first, true);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_Except_NameA(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  bool first = !(nameA.equals(entry.getPrefix()));
+  return std::make_pair(first, true);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NoSubNameA(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  bool second = !(nameA.equals(entry.getPrefix()));
+  return std::make_pair(true, second);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NoNameA_NoSubNameAB(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  Name nameAB("/a/b");
+  bool first = !(nameA.equals(entry.getPrefix()));
+  bool second = !(nameAB.equals(entry.getPrefix()));
+  return std::make_pair(first, second);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NoNameA_NoSubNameAC(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  Name nameAC("/a/c");
+  bool first = !(nameA.equals(entry.getPrefix()));
+  bool second = !(nameAC.equals(entry.getPrefix()));
+  return std::make_pair(first, second);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_Example(const name_tree::Entry& entry)
+{
+  Name nameRoot("/");
+  Name nameA("/a");
+  Name nameAB("/a/b");
+  Name nameABC("/a/b/c");
+  Name nameAD("/a/d");
+  Name nameE("/e");
+  Name nameF("/f");
+
+  bool first = false;
+  bool second = false;
+
+  Name name = entry.getPrefix();
+
+  if (name == nameRoot || name == nameAB || name == nameABC || name == nameAD)
+  {
+    first = true;
+  }
+
+  if(name == nameRoot || name == nameA || name == nameF)
+  {
+    second = true;
+  }
+
+  return std::make_pair(first, second);
+}
+
+BOOST_AUTO_TEST_CASE(NameTreeIteratorPartialEnumerate)
+{
+  typedef NameTree::const_iterator const_iterator;
+
+  size_t nBuckets = 16;
+  NameTree nameTree(nBuckets);
+  int counter = 0;
+
+  // empty nameTree, should return end();
+  Name nameA("/a");
+  bool hasA = false;
+  const_iterator itA = nameTree.partialEnumerate(nameA);
+  BOOST_CHECK(itA == nameTree.end());
+
+  // We have "/", "/a", "/a/b", "a/c" now.
+  Name nameAB("/a/b");
+  bool hasAB = false;
+  nameTree.lookup(nameAB);
+
+  Name nameAC("/a/c");
+  bool hasAC = false;
+  nameTree.lookup(nameAC);
+  BOOST_CHECK_EQUAL(nameTree.size(), 4);
+
+  // Enumerate on some name that is not in nameTree
+  Name name0="/0";
+  const_iterator it0 = nameTree.partialEnumerate(name0);
+  BOOST_CHECK(it0 == nameTree.end());
+
+  // Accept "root" nameA only
+  const_iterator itAOnly = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NameA_Only);
+  BOOST_CHECK_EQUAL(itAOnly->getPrefix(), nameA);
+  BOOST_CHECK(++itAOnly == nameTree.end());
+
+  // Accept anything except "root" nameA
+  const_iterator itExceptA = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_Except_NameA);
+  hasA = false;
+  hasAB = false;
+  hasAC = false;
+
+  counter = 0;
+  for (; itExceptA != nameTree.end(); itExceptA++)
+  {
+    counter++;
+
+    if (itExceptA->getPrefix() == nameA)
+      hasA  = true;
+
+    if (itExceptA->getPrefix() == nameAB)
+      hasAB = true;
+
+    if (itExceptA->getPrefix() == nameAC)
+      hasAC = true;
+  }
+  BOOST_CHECK_EQUAL(hasA,  false);
+  BOOST_CHECK_EQUAL(hasAB, true);
+  BOOST_CHECK_EQUAL(hasAC, true);
+
+  BOOST_CHECK_EQUAL(counter, 2);
+
+  Name nameAB1("a/b/1");
+  bool hasAB1 = false;
+  nameTree.lookup(nameAB1);
+
+  Name nameAB2("a/b/2");
+  bool hasAB2 = false;
+  nameTree.lookup(nameAB2);
+
+  Name nameAC1("a/c/1");
+  bool hasAC1 = false;
+  nameTree.lookup(nameAC1);
+
+  Name nameAC2("a/c/2");
+  bool hasAC2 = false;
+  nameTree.lookup(nameAC2);
+
+  BOOST_CHECK_EQUAL(nameTree.size(), 8);
+
+  // No NameA
+  // No SubTree from NameAB
+  const_iterator itNoNameANoSubNameAB = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoNameA_NoSubNameAB);
+  hasA   = false;
+  hasAB  = false;
+  hasAB1 = false;
+  hasAB2 = false;
+  hasAC  = false;
+  hasAC1 = false;
+  hasAC2 = false;
+
+  counter = 0;
+
+  for (; itNoNameANoSubNameAB != nameTree.end(); itNoNameANoSubNameAB++)
+  {
+    counter++;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameA)
+      hasA   = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAB)
+      hasAB  = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAB1)
+      hasAB1 = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAB2)
+      hasAB2 = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAC)
+      hasAC  = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAC1)
+      hasAC1 = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAC2)
+      hasAC2 = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasA,   false);
+  BOOST_CHECK_EQUAL(hasAB,  true);
+  BOOST_CHECK_EQUAL(hasAB1, false);
+  BOOST_CHECK_EQUAL(hasAB2, false);
+  BOOST_CHECK_EQUAL(hasAC,  true);
+  BOOST_CHECK_EQUAL(hasAC1, true);
+  BOOST_CHECK_EQUAL(hasAC2, true);
+
+  BOOST_CHECK_EQUAL(counter, 4);
+
+  // No NameA
+  // No SubTree from NameAC
+  const_iterator itNoNameANoSubNameAC = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoNameA_NoSubNameAC);
+  hasA   = false;
+  hasAB  = false;
+  hasAB1 = false;
+  hasAB2 = false;
+  hasAC  = false;
+  hasAC1 = false;
+  hasAC2 = false;
+
+  counter = 0;
+
+  for (; itNoNameANoSubNameAC != nameTree.end(); itNoNameANoSubNameAC++)
+  {
+    counter++;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameA)
+      hasA   = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAB)
+      hasAB  = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAB1)
+      hasAB1 = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAB2)
+      hasAB2 = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAC)
+      hasAC  = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAC1)
+      hasAC1 = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAC2)
+      hasAC2 = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasA,   false);
+  BOOST_CHECK_EQUAL(hasAB,  true);
+  BOOST_CHECK_EQUAL(hasAB1, true);
+  BOOST_CHECK_EQUAL(hasAB2, true);
+  BOOST_CHECK_EQUAL(hasAC,  true);
+  BOOST_CHECK_EQUAL(hasAC1, false);
+  BOOST_CHECK_EQUAL(hasAC2, false);
+
+  BOOST_CHECK_EQUAL(counter, 4);
+
+  // No Subtree from NameA
+  const_iterator itNoANoSubNameA = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoSubNameA);
+
+  hasA   = false;
+  hasAB  = false;
+  hasAB1 = false;
+  hasAB2 = false;
+  hasAC  = false;
+  hasAC1 = false;
+  hasAC2 = false;
+
+  counter = 0;
+
+  for (; itNoANoSubNameA != nameTree.end(); itNoANoSubNameA++)
+  {
+    counter++;
+
+    if (itNoANoSubNameA->getPrefix() == nameA)
+      hasA   = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAB)
+      hasAB  = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAB1)
+      hasAB1 = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAB2)
+      hasAB2 = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAC)
+      hasAC  = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAC1)
+      hasAC1 = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAC2)
+      hasAC2 = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasA,   true);
+  BOOST_CHECK_EQUAL(hasAB,  false);
+  BOOST_CHECK_EQUAL(hasAB1, false);
+  BOOST_CHECK_EQUAL(hasAB2, false);
+  BOOST_CHECK_EQUAL(hasAC,  false);
+  BOOST_CHECK_EQUAL(hasAC1, false);
+  BOOST_CHECK_EQUAL(hasAC2, false);
+
+  BOOST_CHECK_EQUAL(counter, 1);
+
+  // Example
+  // /
+  // /A
+  // /A/B x
+  // /A/B/C
+  // /A/D x
+  // /E
+  // /F
+
+  NameTree nameTreeExample(nBuckets);
+
+  Name nameRoot("/");
+  bool hasRoot = false;
+
+  nameTreeExample.lookup(nameA);
+  hasA = false;
+  nameTreeExample.lookup(nameAB);
+  hasAB = false;
+
+  Name nameABC("a/b/c");
+  bool hasABC = false;
+  nameTreeExample.lookup(nameABC);
+
+  Name nameAD("/a/d");
+  nameTreeExample.lookup(nameAD);
+  bool hasAD = false;
+
+  Name nameE("/e");
+  nameTreeExample.lookup(nameE);
+  bool hasE = false;
+
+  Name nameF("/f");
+  nameTreeExample.lookup(nameF);
+  bool hasF = false;
+
+  counter = 0;
+  const_iterator itExample = nameTreeExample.partialEnumerate(nameA, &predicate_NameTreeEntry_Example);
+
+  for (; itExample != nameTreeExample.end(); itExample++)
+  {
+    counter++;
+
+    if (itExample->getPrefix() == nameRoot)
+      hasRoot = true;
+
+    if (itExample->getPrefix() == nameA)
+     hasA     = true;
+
+    if (itExample->getPrefix() == nameAB)
+     hasAB    = true;
+
+    if (itExample->getPrefix() == nameABC)
+     hasABC   = true;
+
+    if (itExample->getPrefix() == nameAD)
+     hasAD    = true;
+
+    if (itExample->getPrefix() == nameE)
+     hasE     = true;
+
+    if (itExample->getPrefix() == nameF)
+      hasF    = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasRoot, false);
+  BOOST_CHECK_EQUAL(hasA,    false);
+  BOOST_CHECK_EQUAL(hasAB,   true);
+  BOOST_CHECK_EQUAL(hasABC,  false);
+  BOOST_CHECK_EQUAL(hasAD,   true);
+  BOOST_CHECK_EQUAL(hasE,    false);
+  BOOST_CHECK_EQUAL(hasF,    false);
+
+  BOOST_CHECK_EQUAL(counter, 2);
+}
+
+
+BOOST_AUTO_TEST_CASE(NameTreeIteratorFindAllMatches)
+{
+  size_t nBuckets = 16;
+  NameTree nt(nBuckets);
+  int counter = 0;
+
+  Name nameABCDEF("a/b/c/d/e/f");
+  shared_ptr<name_tree::Entry> npeABCDEF = nt.lookup(nameABCDEF);
+
+  Name nameAAC("a/a/c");
+  shared_ptr<name_tree::Entry> npeAAC = nt.lookup(nameAAC);
+
+  Name nameAAD1("a/a/d/1");
+  shared_ptr<name_tree::Entry> npeAAD1 = nt.lookup(nameAAD1);
+
+  Name nameAAD2("a/a/d/2");
+  shared_ptr<name_tree::Entry> npeAAD2 = nt.lookup(nameAAD2);
+
+
+  BOOST_CHECK_EQUAL(nt.size(), 12);
+
+  Name nameRoot ("/");
+  Name nameA    ("/a");
+  Name nameAB   ("/a/b");
+  Name nameABC  ("/a/b/c");
+  Name nameABCD ("/a/b/c/d");
+  Name nameABCDE("/a/b/c/d/e");
+  Name nameAA   ("/a/a");
+  Name nameAAD  ("/a/a/d");
+
+  bool hasRoot    = false;
+  bool hasA       = false;
+  bool hasAB      = false;
+  bool hasABC     = false;
+  bool hasABCD    = false;
+  bool hasABCDE   = false;
+  bool hasABCDEF  = false;
+  bool hasAA      = false;
+  bool hasAAC     = false;
+  bool hasAAD     = false;
+  bool hasAAD1    = false;
+  bool hasAAD2    = false;
+
+  counter = 0;
+
+  for (NameTree::const_iterator it = nt.findAllMatches(nameABCDEF);
+      it != nt.end(); it++)
+  {
+    counter++;
+
+    if (it->getPrefix() == nameRoot)
+      hasRoot   = true;
+    if (it->getPrefix() == nameA)
+      hasA      = true;
+    if (it->getPrefix() == nameAB)
+      hasAB     = true;
+    if (it->getPrefix() == nameABC)
+      hasABC    = true;
+    if (it->getPrefix() == nameABCD)
+      hasABCD   = true;
+    if (it->getPrefix() == nameABCDE)
+      hasABCDE  = true;
+    if (it->getPrefix() == nameABCDEF)
+      hasABCDEF = true;
+    if (it->getPrefix() == nameAA)
+      hasAA     = true;
+    if (it->getPrefix() == nameAAC)
+      hasAAC    = true;
+    if (it->getPrefix() == nameAAD)
+      hasAAD    = true;
+    if (it->getPrefix() == nameAAD1)
+      hasAAD1   = true;
+    if (it->getPrefix() == nameAAD2)
+      hasAAD2   = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasRoot   , true);
+  BOOST_CHECK_EQUAL(hasA      , true);
+  BOOST_CHECK_EQUAL(hasAB     , true);
+  BOOST_CHECK_EQUAL(hasABC    , true);
+  BOOST_CHECK_EQUAL(hasABCD   , true);
+  BOOST_CHECK_EQUAL(hasABCDE  , true);
+  BOOST_CHECK_EQUAL(hasABCDEF , true);
+  BOOST_CHECK_EQUAL(hasAA     , false);
+  BOOST_CHECK_EQUAL(hasAAC    , false);
+  BOOST_CHECK_EQUAL(hasAAD    , false);
+  BOOST_CHECK_EQUAL(hasAAD1   , false);
+  BOOST_CHECK_EQUAL(hasAAD2   , false);
+
+  BOOST_CHECK_EQUAL(counter, 7);
+}
+
+BOOST_AUTO_TEST_CASE(NameTreeHashTableResizeShrink)
+{
+  size_t nBuckets = 16;
+  NameTree nameTree(nBuckets);
+
+  Name prefix("/a/b/c/d/e/f/g/h"); // requires 9 buckets
+
+  shared_ptr<name_tree::Entry> entry = nameTree.lookup(prefix);
+  BOOST_CHECK_EQUAL(nameTree.size(), 9);
+  BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 32);
+
+  nameTree.eraseEntryIfEmpty(entry);
+  BOOST_CHECK_EQUAL(nameTree.size(), 0);
+  BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 16);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/pit.cpp b/tests/daemon/table/pit.cpp
new file mode 100644
index 0000000..c77c909
--- /dev/null
+++ b/tests/daemon/table/pit.cpp
@@ -0,0 +1,383 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/pit.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TablePit, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(EntryInOutRecords)
+{
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+  Name name("ndn:/KuYfjtRq");
+  shared_ptr<Interest> interest  = makeInterest(name);
+  shared_ptr<Interest> interest1 = makeInterest(name);
+  interest1->setInterestLifetime(time::milliseconds(2528));
+  interest1->setNonce(25559);
+  shared_ptr<Interest> interest2 = makeInterest(name);
+  interest2->setInterestLifetime(time::milliseconds(6464));
+  interest2->setNonce(19004);
+  shared_ptr<Interest> interest3 = makeInterest(name);
+  interest3->setInterestLifetime(time::milliseconds(3585));
+  interest3->setNonce(24216);
+  shared_ptr<Interest> interest4 = makeInterest(name);
+  interest4->setInterestLifetime(time::milliseconds(8795));
+  interest4->setNonce(17365);
+
+  pit::Entry entry(*interest);
+
+  BOOST_CHECK_EQUAL(entry.getInterest().getName(), name);
+  BOOST_CHECK_EQUAL(entry.getName(), name);
+
+  const pit::InRecordCollection& inRecords1 = entry.getInRecords();
+  BOOST_CHECK_EQUAL(inRecords1.size(), 0);
+  const pit::OutRecordCollection& outRecords1 = entry.getOutRecords();
+  BOOST_CHECK_EQUAL(outRecords1.size(), 0);
+
+  // insert InRecord
+  time::steady_clock::TimePoint before1 = time::steady_clock::now();
+  pit::InRecordCollection::iterator in1 =
+    entry.insertOrUpdateInRecord(face1, *interest1);
+  time::steady_clock::TimePoint after1 = time::steady_clock::now();
+  const pit::InRecordCollection& inRecords2 = entry.getInRecords();
+  BOOST_CHECK_EQUAL(inRecords2.size(), 1);
+  BOOST_CHECK(in1 == inRecords2.begin());
+  BOOST_CHECK_EQUAL(in1->getFace(), face1);
+  BOOST_CHECK_EQUAL(in1->getLastNonce(), interest1->getNonce());
+  BOOST_CHECK_GE(in1->getLastRenewed(), before1);
+  BOOST_CHECK_LE(in1->getLastRenewed(), after1);
+  BOOST_CHECK_LE(in1->getExpiry() - in1->getLastRenewed()
+                 - interest1->getInterestLifetime(),
+                 (after1 - before1));
+
+  // insert OutRecord
+  time::steady_clock::TimePoint before2 = time::steady_clock::now();
+  pit::OutRecordCollection::iterator out1 =
+    entry.insertOrUpdateOutRecord(face1, *interest1);
+  time::steady_clock::TimePoint after2 = time::steady_clock::now();
+  const pit::OutRecordCollection& outRecords2 = entry.getOutRecords();
+  BOOST_CHECK_EQUAL(outRecords2.size(), 1);
+  BOOST_CHECK(out1 == outRecords2.begin());
+  BOOST_CHECK_EQUAL(out1->getFace(), face1);
+  BOOST_CHECK_EQUAL(out1->getLastNonce(), interest1->getNonce());
+  BOOST_CHECK_GE(out1->getLastRenewed(), before2);
+  BOOST_CHECK_LE(out1->getLastRenewed(), after2);
+  BOOST_CHECK_LE(out1->getExpiry() - out1->getLastRenewed()
+                 - interest1->getInterestLifetime(),
+                 (after2 - before2));
+
+  // update InRecord
+  time::steady_clock::TimePoint before3 = time::steady_clock::now();
+  pit::InRecordCollection::iterator in2 =
+    entry.insertOrUpdateInRecord(face1, *interest2);
+  time::steady_clock::TimePoint after3 = time::steady_clock::now();
+  const pit::InRecordCollection& inRecords3 = entry.getInRecords();
+  BOOST_CHECK_EQUAL(inRecords3.size(), 1);
+  BOOST_CHECK(in2 == inRecords3.begin());
+  BOOST_CHECK_EQUAL(in2->getFace(), face1);
+  BOOST_CHECK_EQUAL(in2->getLastNonce(), interest2->getNonce());
+  BOOST_CHECK_LE(in2->getExpiry() - in2->getLastRenewed()
+                 - interest2->getInterestLifetime(),
+                 (after3 - before3));
+
+  // insert another InRecord
+  pit::InRecordCollection::iterator in3 =
+    entry.insertOrUpdateInRecord(face2, *interest3);
+  const pit::InRecordCollection& inRecords4 = entry.getInRecords();
+  BOOST_CHECK_EQUAL(inRecords4.size(), 2);
+  BOOST_CHECK_EQUAL(in3->getFace(), face2);
+
+  // delete all InRecords
+  entry.deleteInRecords();
+  const pit::InRecordCollection& inRecords5 = entry.getInRecords();
+  BOOST_CHECK_EQUAL(inRecords5.size(), 0);
+
+  // insert another OutRecord
+  pit::OutRecordCollection::iterator out2 =
+    entry.insertOrUpdateOutRecord(face2, *interest4);
+  const pit::OutRecordCollection& outRecords3 = entry.getOutRecords();
+  BOOST_CHECK_EQUAL(outRecords3.size(), 2);
+  BOOST_CHECK_EQUAL(out2->getFace(), face2);
+
+  // delete OutRecord
+  entry.deleteOutRecord(face2);
+  const pit::OutRecordCollection& outRecords4 = entry.getOutRecords();
+  BOOST_REQUIRE_EQUAL(outRecords4.size(), 1);
+  BOOST_CHECK_EQUAL(outRecords4.begin()->getFace(), face1);
+}
+
+BOOST_AUTO_TEST_CASE(EntryNonce)
+{
+  shared_ptr<Interest> interest = makeInterest("ndn:/qtCQ7I1c");
+
+  pit::Entry entry(*interest);
+
+  BOOST_CHECK_EQUAL(entry.addNonce(25559), true);
+  BOOST_CHECK_EQUAL(entry.addNonce(25559), false);
+  BOOST_CHECK_EQUAL(entry.addNonce(19004), true);
+  BOOST_CHECK_EQUAL(entry.addNonce(19004), false);
+}
+
+BOOST_AUTO_TEST_CASE(EntryLifetime)
+{
+  shared_ptr<Interest> interest = makeInterest("ndn:/7oIEurbgy6");
+  BOOST_ASSERT(interest->getInterestLifetime() < time::milliseconds::zero()); // library uses -1 to indicate unset lifetime
+
+  shared_ptr<Face> face = make_shared<DummyFace>();
+  pit::Entry entry(*interest);
+
+  pit::InRecordCollection::iterator inIt = entry.insertOrUpdateInRecord(face, *interest);
+  BOOST_CHECK_GT(inIt->getExpiry(), time::steady_clock::now());
+
+  pit::OutRecordCollection::iterator outIt = entry.insertOrUpdateOutRecord(face, *interest);
+  BOOST_CHECK_GT(outIt->getExpiry(), time::steady_clock::now());
+}
+
+BOOST_AUTO_TEST_CASE(EntryCanForwardTo)
+{
+  shared_ptr<Interest> interest = makeInterest("ndn:/WDsuBLIMG");
+  pit::Entry entry(*interest);
+
+  shared_ptr<Face> face1 = make_shared<DummyFace>();
+  shared_ptr<Face> face2 = make_shared<DummyFace>();
+
+  entry.insertOrUpdateInRecord(face1, *interest);
+  BOOST_CHECK_EQUAL(entry.canForwardTo(*face1), false);
+  BOOST_CHECK_EQUAL(entry.canForwardTo(*face2), true);
+
+  entry.insertOrUpdateInRecord(face2, *interest);
+  BOOST_CHECK_EQUAL(entry.canForwardTo(*face1), true);
+  BOOST_CHECK_EQUAL(entry.canForwardTo(*face2), true);
+
+  entry.insertOrUpdateOutRecord(face1, *interest);
+  BOOST_CHECK_EQUAL(entry.canForwardTo(*face1), false);
+  BOOST_CHECK_EQUAL(entry.canForwardTo(*face2), true);
+}
+
+BOOST_AUTO_TEST_CASE(Insert)
+{
+  Name name1("ndn:/5vzBNnMst");
+  Name name2("ndn:/igSGfEIM62");
+  Exclude exclude1;
+  exclude1.excludeOne(Name::Component("u26p47oep"));
+  Exclude exclude2;
+  exclude2.excludeBefore(Name::Component("u26p47oep"));
+  ndn::KeyLocator keyLocator1("ndn:/sGAE3peMHA");
+  ndn::KeyLocator keyLocator2("ndn:/nIJH6pr4");
+
+  NameTree nameTree(16);
+  Pit pit(nameTree);
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+  std::pair<shared_ptr<pit::Entry>, bool> insertResult;
+
+  // base
+  shared_ptr<Interest> interestA = make_shared<Interest>(name1);
+  insertResult = pit.insert(*interestA);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 1);
+
+  // A+MinSuffixComponents
+  shared_ptr<Interest> interestB = make_shared<Interest>(*interestA);
+  interestB->setMinSuffixComponents(2);
+  insertResult = pit.insert(*interestB);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 2);
+
+  // A+MaxSuffixComponents
+  shared_ptr<Interest> interestC = make_shared<Interest>(*interestA);
+  interestC->setMaxSuffixComponents(4);
+  insertResult = pit.insert(*interestC);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 3);
+
+  // A+KeyLocator1
+  shared_ptr<Interest> interestD = make_shared<Interest>(*interestA);
+  interestD->setPublisherPublicKeyLocator(keyLocator1);
+  insertResult = pit.insert(*interestD);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 4);
+
+  // A+KeyLocator2
+  shared_ptr<Interest> interestE = make_shared<Interest>(*interestA);
+  interestE->setPublisherPublicKeyLocator(keyLocator2);
+  insertResult = pit.insert(*interestE);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 5);
+
+  // A+Exclude1
+  shared_ptr<Interest> interestF = make_shared<Interest>(*interestA);
+  interestF->setExclude(exclude1);
+  insertResult = pit.insert(*interestF);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 6);
+
+  // A+Exclude2
+  shared_ptr<Interest> interestG = make_shared<Interest>(*interestA);
+  interestG->setExclude(exclude2);
+  insertResult = pit.insert(*interestG);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 7);
+
+  // A+ChildSelector0
+  shared_ptr<Interest> interestH = make_shared<Interest>(*interestA);
+  interestH->setChildSelector(0);
+  insertResult = pit.insert(*interestH);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 8);
+
+  // A+ChildSelector1
+  shared_ptr<Interest> interestI = make_shared<Interest>(*interestA);
+  interestI->setChildSelector(1);
+  insertResult = pit.insert(*interestI);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 9);
+
+  // A+MustBeFresh
+  shared_ptr<Interest> interestJ = make_shared<Interest>(*interestA);
+  interestJ->setMustBeFresh(true);
+  insertResult = pit.insert(*interestJ);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 10);
+
+  // A+InterestLifetime
+  shared_ptr<Interest> interestK = make_shared<Interest>(*interestA);
+  interestK->setInterestLifetime(time::milliseconds(1000));
+  insertResult = pit.insert(*interestK);
+  BOOST_CHECK_EQUAL(insertResult.second, false);// only guiders differ
+  BOOST_CHECK_EQUAL(pit.size(), 10);
+
+  // A+Nonce
+  shared_ptr<Interest> interestL = make_shared<Interest>(*interestA);
+  interestL->setNonce(2192);
+  insertResult = pit.insert(*interestL);
+  BOOST_CHECK_EQUAL(insertResult.second, false);// only guiders differ
+  BOOST_CHECK_EQUAL(pit.size(), 10);
+
+  // different Name+Exclude1
+  shared_ptr<Interest> interestM = make_shared<Interest>(name2);
+  interestM->setExclude(exclude1);
+  insertResult = pit.insert(*interestM);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 11);
+}
+
+BOOST_AUTO_TEST_CASE(Erase)
+{
+  Interest interest(Name("ndn:/z88Admz6A2"));
+
+  NameTree nameTree(16);
+  Pit pit(nameTree);
+
+  std::pair<shared_ptr<pit::Entry>, bool> insertResult;
+
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+
+  insertResult = pit.insert(interest);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 1);
+
+  insertResult = pit.insert(interest);
+  BOOST_CHECK_EQUAL(insertResult.second, false);
+  BOOST_CHECK_EQUAL(pit.size(), 1);
+
+  pit.erase(insertResult.first);
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+
+  insertResult = pit.insert(interest);
+  BOOST_CHECK_EQUAL(insertResult.second, true);
+  BOOST_CHECK_EQUAL(pit.size(), 1);
+
+}
+
+BOOST_AUTO_TEST_CASE(FindAllDataMatches)
+{
+  Name nameA   ("ndn:/A");
+  Name nameAB  ("ndn:/A/B");
+  Name nameABC ("ndn:/A/B/C");
+  Name nameABCD("ndn:/A/B/C/D");
+  Name nameD   ("ndn:/D");
+
+  Interest interestA  (nameA  );
+  Interest interestABC(nameABC);
+  Interest interestD  (nameD  );
+
+  NameTree nameTree(16);
+  Pit pit(nameTree);
+  int count = 0;
+
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+
+  pit.insert(interestA  );
+  pit.insert(interestABC);
+  pit.insert(interestD  );
+
+  nameTree.lookup(nameABCD); // make sure /A/B/C/D is in nameTree
+
+  BOOST_CHECK_EQUAL(pit.size(), 3);
+
+  Data data(nameABCD);
+
+  shared_ptr<pit::DataMatchResult> matches = pit.findAllDataMatches(data);
+
+  bool hasA   = false;
+  bool hasAB  = false;
+  bool hasABC = false;
+  bool hasD   = false;
+
+  for (pit::DataMatchResult::iterator it = matches->begin();
+       it != matches->end(); ++it) {
+    ++count;
+    shared_ptr<pit::Entry> entry = *it;
+
+    if (entry->getName().equals(nameA ))
+      hasA   = true;
+
+    if (entry->getName().equals(nameAB))
+      hasAB  = true;
+
+    if (entry->getName().equals(nameABC))
+      hasABC = true;
+
+    if (entry->getName().equals(nameD))
+      hasD   = true;
+  }
+  BOOST_CHECK_EQUAL(hasA  , true);
+  BOOST_CHECK_EQUAL(hasAB , false);
+  BOOST_CHECK_EQUAL(hasABC, true);
+  BOOST_CHECK_EQUAL(hasD  , false);
+
+  BOOST_CHECK_EQUAL(count, 2);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/strategy-choice.cpp b/tests/daemon/table/strategy-choice.cpp
new file mode 100644
index 0000000..6927375
--- /dev/null
+++ b/tests/daemon/table/strategy-choice.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/strategy-choice.hpp"
+#include "tests/daemon/fw/dummy-strategy.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TableStrategyChoice, BaseFixture)
+
+using fw::Strategy;
+
+BOOST_AUTO_TEST_CASE(Effective)
+{
+  Forwarder forwarder;
+  Name nameP("ndn:/strategy/P");
+  Name nameQ("ndn:/strategy/Q");
+  Name nameZ("ndn:/strategy/Z");
+  shared_ptr<Strategy> strategyP = make_shared<DummyStrategy>(boost::ref(forwarder), nameP);
+  shared_ptr<Strategy> strategyQ = make_shared<DummyStrategy>(boost::ref(forwarder), nameQ);
+
+  StrategyChoice& table = forwarder.getStrategyChoice();
+
+  // install
+  BOOST_CHECK_EQUAL(table.install(strategyP), true);
+  BOOST_CHECK_EQUAL(table.install(strategyQ), true);
+  BOOST_CHECK_EQUAL(table.install(strategyQ), false);
+
+  BOOST_CHECK(table.insert("ndn:/", nameP));
+  // { '/'=>P }
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+
+  BOOST_CHECK(table.insert("ndn:/A/B", nameP));
+  // { '/'=>P, '/A/B'=>P }
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  // same instance
+  BOOST_CHECK_EQUAL(&table.findEffectiveStrategy("ndn:/"),    strategyP.get());
+  BOOST_CHECK_EQUAL(&table.findEffectiveStrategy("ndn:/A"),   strategyP.get());
+  BOOST_CHECK_EQUAL(&table.findEffectiveStrategy("ndn:/A/B"), strategyP.get());
+
+  table.erase("ndn:/A"); // no effect
+  // { '/'=>P, '/A/B'=>P }
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+
+  BOOST_CHECK(table.insert("ndn:/A", nameQ));
+  // { '/'=>P, '/A/B'=>P, '/A'=>Q }
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameQ);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+
+  table.erase("ndn:/A/B");
+  // { '/'=>P, '/A'=>Q }
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameQ);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameQ);
+
+  BOOST_CHECK(!table.insert("ndn:/", nameZ)); // non existent strategy
+
+  BOOST_CHECK(table.insert("ndn:/", nameQ));
+  BOOST_CHECK(table.insert("ndn:/A", nameP));
+  // { '/'=>Q, '/A'=>P }
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameQ);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/D")  .getName(), nameQ);
+}
+
+class PStrategyInfo : public fw::StrategyInfo
+{
+};
+
+BOOST_AUTO_TEST_CASE(ClearStrategyInfo)
+{
+  Forwarder forwarder;
+  Name nameP("ndn:/strategy/P");
+  Name nameQ("ndn:/strategy/Q");
+  shared_ptr<Strategy> strategyP = make_shared<DummyStrategy>(boost::ref(forwarder), nameP);
+  shared_ptr<Strategy> strategyQ = make_shared<DummyStrategy>(boost::ref(forwarder), nameQ);
+
+  StrategyChoice& table = forwarder.getStrategyChoice();
+  Measurements& measurements = forwarder.getMeasurements();
+
+  // install
+  table.install(strategyP);
+  table.install(strategyQ);
+
+  BOOST_CHECK(table.insert("ndn:/", nameP));
+  // { '/'=>P }
+  measurements.get("ndn:/")     ->getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/A")    ->getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/A/B")  ->getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/A/C")  ->getOrCreateStrategyInfo<PStrategyInfo>();
+
+  BOOST_CHECK(table.insert("ndn:/A/B", nameP));
+  // { '/'=>P, '/A/B'=>P }
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/")   ->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/A")  ->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/A/B")->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/A/C")->getStrategyInfo<PStrategyInfo>()));
+
+  BOOST_CHECK(table.insert("ndn:/A", nameQ));
+  // { '/'=>P, '/A/B'=>P, '/A'=>Q }
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/")   ->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK(!static_cast<bool>(measurements.get("ndn:/A")  ->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/A/B")->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK(!static_cast<bool>(measurements.get("ndn:/A/C")->getStrategyInfo<PStrategyInfo>()));
+
+  table.erase("ndn:/A/B");
+  // { '/'=>P, '/A'=>Q }
+  BOOST_CHECK( static_cast<bool>(measurements.get("ndn:/")   ->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK(!static_cast<bool>(measurements.get("ndn:/A")  ->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK(!static_cast<bool>(measurements.get("ndn:/A/B")->getStrategyInfo<PStrategyInfo>()));
+  BOOST_CHECK(!static_cast<bool>(measurements.get("ndn:/A/C")->getStrategyInfo<PStrategyInfo>()));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/table/strategy-info-host.cpp b/tests/daemon/table/strategy-info-host.cpp
new file mode 100644
index 0000000..82d4fcc
--- /dev/null
+++ b/tests/daemon/table/strategy-info-host.cpp
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "table/strategy-info-host.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+static int g_DummyStrategyInfo_count = 0;
+
+class DummyStrategyInfo : public fw::StrategyInfo
+{
+public:
+  DummyStrategyInfo(int id)
+    : m_id(id)
+  {
+    ++g_DummyStrategyInfo_count;
+  }
+
+  virtual ~DummyStrategyInfo()
+  {
+    --g_DummyStrategyInfo_count;
+  }
+
+  int m_id;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TableStrategyInfoHost, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(SetGetClear)
+{
+  StrategyInfoHost host;
+
+  BOOST_CHECK(!static_cast<bool>(host.getStrategyInfo<DummyStrategyInfo>()));
+
+  g_DummyStrategyInfo_count = 0;
+
+  shared_ptr<DummyStrategyInfo> info = make_shared<DummyStrategyInfo>(7591);
+  host.setStrategyInfo(info);
+  BOOST_REQUIRE(static_cast<bool>(host.getStrategyInfo<DummyStrategyInfo>()));
+  BOOST_CHECK_EQUAL(host.getStrategyInfo<DummyStrategyInfo>()->m_id, 7591);
+
+  info.reset(); // unlink local reference
+  // host should still have a reference to info
+  BOOST_REQUIRE(static_cast<bool>(host.getStrategyInfo<DummyStrategyInfo>()));
+  BOOST_CHECK_EQUAL(host.getStrategyInfo<DummyStrategyInfo>()->m_id, 7591);
+
+  host.clearStrategyInfo();
+  BOOST_CHECK(!static_cast<bool>(host.getStrategyInfo<DummyStrategyInfo>()));
+  BOOST_CHECK_EQUAL(g_DummyStrategyInfo_count, 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
