diff --git a/common.hpp b/common.hpp
index bd8f10b..9e44569 100644
--- a/common.hpp
+++ b/common.hpp
@@ -97,6 +97,7 @@
 using ndn::Interest;
 using ndn::Data;
 using ndn::Name;
+using ndn::PartialName;
 using ndn::Exclude;
 using ndn::Link;
 using ndn::Block;
diff --git a/core/config-file.cpp b/core/config-file.cpp
index 9724168..d989455 100644
--- a/core/config-file.cpp
+++ b/core/config-file.cpp
@@ -52,6 +52,25 @@
   // do nothing
 }
 
+bool
+ConfigFile::parseYesNo(const ConfigSection::const_iterator& i,
+                        const std::string& optionName,
+                        const std::string& sectionName)
+{
+  const std::string value = i->second.get_value<std::string>();
+  if (value == "yes") {
+    return true;
+  }
+
+  if (value == "no") {
+    return false;
+  }
+
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                          optionName + "\" in \"" +
+                                          sectionName + "\" section"));
+}
+
 ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
   : m_unknownSectionCallback(unknownSectionCallback)
 {
diff --git a/core/config-file.hpp b/core/config-file.hpp
index 9991484..ae9102e 100644
--- a/core/config-file.hpp
+++ b/core/config-file.hpp
@@ -73,6 +73,16 @@
                        const ConfigSection& section,
                        bool isDryRun);
 
+  /** @brief parse a config option that can be either "yes" or "no"
+   *
+   *  @throw ConfigFile::Error value is neither "yes" nor "no"
+   *  @return true if "yes", false if "no"
+   */
+  static bool
+  parseYesNo(const ConfigSection::const_iterator& i,
+             const std::string& optionName,
+             const std::string& sectionName);
+
   /// \brief setup notification of configuration file sections
   void
   addSectionHandler(const std::string& sectionName,
diff --git a/daemon/face/internal-client-face.cpp b/daemon/face/internal-client-face.cpp
new file mode 100644
index 0000000..510b087
--- /dev/null
+++ b/daemon/face/internal-client-face.cpp
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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 "internal-client-face.hpp"
+#include "internal-face.hpp"
+#include "core/global-io.hpp"
+
+#include <ndn-cxx/management/nfd-local-control-header.hpp>
+
+namespace nfd {
+
+void
+InternalClientFace::Transport::receive(const Block& block)
+{
+  if (m_receiveCallback) {
+    m_receiveCallback(block);
+  }
+}
+
+void
+InternalClientFace::Transport::close()
+{
+}
+
+void
+InternalClientFace::Transport::send(const Block& wire)
+{
+  onSendBlock(wire);
+}
+
+void
+InternalClientFace::Transport::send(const Block& header, const Block& payload)
+{
+  ndn::EncodingBuffer encoder(header.size() + payload.size(), header.size() + payload.size());
+  encoder.appendByteArray(header.wire(), header.size());
+  encoder.appendByteArray(payload.wire(), payload.size());
+
+  this->send(encoder.block());
+}
+
+void
+InternalClientFace::Transport::pause()
+{
+}
+
+void
+InternalClientFace::Transport::resume()
+{
+}
+
+InternalClientFace::InternalClientFace(const shared_ptr<InternalFace>& face,
+                                       const shared_ptr<InternalClientFace::Transport>& transport,
+                                       ndn::KeyChain& keyChain)
+  : ndn::Face(transport, getGlobalIoService(), keyChain)
+  , m_face(face)
+  , m_transport(transport)
+{
+  construct();
+}
+
+void
+InternalClientFace::construct()
+{
+  m_face->onSendInterest.connect(bind(&InternalClientFace::receive<Interest>, this, _1));
+  m_face->onSendData.connect(bind(&InternalClientFace::receive<Data>, this, _1));
+  m_transport->onSendBlock.connect(bind(&InternalFace::receive, m_face, _1));
+}
+
+shared_ptr<InternalClientFace>
+makeInternalClientFace(const shared_ptr<InternalFace>& face,
+                       ndn::KeyChain& keyChain)
+{
+  auto transport = make_shared<InternalClientFace::Transport>();
+  return shared_ptr<InternalClientFace>(new InternalClientFace(face, transport, keyChain));
+}
+
+} // namespace nfd
diff --git a/daemon/face/internal-client-face.hpp b/daemon/face/internal-client-face.hpp
new file mode 100644
index 0000000..8eb3c46
--- /dev/null
+++ b/daemon/face/internal-client-face.hpp
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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_DAEMON_FACE_INTERNAL_CLIENT_FACE_HPP
+#define NFD_DAEMON_FACE_INTERNAL_CLIENT_FACE_HPP
+
+#include "common.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/transport/transport.hpp>
+
+namespace nfd {
+
+class InternalFace;
+class InternalClientFace;
+
+shared_ptr<InternalClientFace>
+makeInternalClientFace(const shared_ptr<InternalFace>& face, ndn::KeyChain& keyChain);
+
+/** \brief a client face that is connected to NFD InternalFace
+ */
+class InternalClientFace : public ndn::Face
+{
+public:
+  template<typename Packet>
+  void
+  receive(const Packet& packet);
+
+private:
+  class Transport : public ndn::Transport
+  {
+  public:
+    signal::Signal<Transport, Block> onSendBlock;
+
+    void
+    receive(const Block& block);
+
+    virtual void
+    close() DECL_OVERRIDE;
+
+    virtual void
+    send(const Block& wire) DECL_OVERRIDE;
+
+    virtual void
+    send(const Block& header, const Block& payload) DECL_OVERRIDE;
+
+    virtual void
+    pause() DECL_OVERRIDE;
+
+    virtual void
+    resume() DECL_OVERRIDE;
+  };
+
+private:
+  InternalClientFace(const shared_ptr<InternalFace>& face,
+                     const shared_ptr<InternalClientFace::Transport>& transport,
+                     ndn::KeyChain& keyChain);
+
+  void
+  construct();
+
+  friend shared_ptr<InternalClientFace>
+  makeInternalClientFace(const shared_ptr<InternalFace>& face,
+                         ndn::KeyChain& keyChain);
+
+private:
+  shared_ptr<InternalFace> m_face;
+  shared_ptr<InternalClientFace::Transport> m_transport;
+};
+
+template<typename Packet>
+void
+InternalClientFace::receive(const Packet& packet)
+{
+  if (!packet.getLocalControlHeader().empty(ndn::nfd::LocalControlHeader::ENCODE_ALL)) {
+
+    Block header = packet.getLocalControlHeader()
+                         .wireEncode(packet, ndn::nfd::LocalControlHeader::ENCODE_ALL);
+    Block payload = packet.wireEncode();
+
+    ndn::EncodingBuffer encoder(header.size() + payload.size(),
+                                header.size() + payload.size());
+    encoder.appendByteArray(header.wire(), header.size());
+    encoder.appendByteArray(payload.wire(), payload.size());
+
+    m_transport->receive(encoder.block());
+  }
+  else {
+    m_transport->receive(packet.wireEncode());
+  }
+}
+
+} // namespace nfd
+
+#endif // NFD_DAEMON_FACE_INTERNAL_CLIENT_FACE_HPP
diff --git a/daemon/face/internal-face.cpp b/daemon/face/internal-face.cpp
new file mode 100644
index 0000000..c5ab2ca
--- /dev/null
+++ b/daemon/face/internal-face.cpp
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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 "internal-face.hpp"
+
+namespace nfd {
+
+InternalFace::InternalFace()
+  : Face(FaceUri("internal://"), FaceUri("internal://"), true)
+{
+}
+
+void
+InternalFace::sendInterest(const Interest& interest)
+{
+  this->emitSignal(onSendInterest, interest);
+}
+
+void
+InternalFace::sendData(const Data& data)
+{
+  this->emitSignal(onSendData, data);
+}
+
+void
+InternalFace::close()
+{
+}
+
+void
+InternalFace::receive(const Block& blockFromClient)
+{
+  const Block& payLoad = ndn::nfd::LocalControlHeader::getPayload(blockFromClient);
+  if (payLoad.type() == ndn::tlv::Interest) {
+    receiveInterest(*extractPacketFromBlock<Interest>(blockFromClient, payLoad));
+  }
+  else if (payLoad.type() == ndn::tlv::Data) {
+    receiveData(*extractPacketFromBlock<Data>(blockFromClient, payLoad));
+  }
+}
+
+void
+InternalFace::receiveInterest(const Interest& interest)
+{
+  this->emitSignal(onReceiveInterest, interest);
+}
+
+void
+InternalFace::receiveData(const Data& data)
+{
+  this->emitSignal(onReceiveData, data);
+}
+
+template<typename Packet>
+shared_ptr<Packet>
+InternalFace::extractPacketFromBlock(const Block& blockFromClient, const Block& payLoad)
+{
+  auto packet = make_shared<Packet>(payLoad);
+  if (&payLoad != &blockFromClient) {
+    packet->getLocalControlHeader().wireDecode(blockFromClient);
+  }
+  return packet;
+}
+
+template shared_ptr<Interest>
+InternalFace::extractPacketFromBlock<Interest>(const Block& blockFromClient, const Block& payLoad);
+
+template shared_ptr<Data>
+InternalFace::extractPacketFromBlock<Data>(const Block& blockFromClient, const Block& payLoad);
+
+} // namespace nfd
diff --git a/daemon/face/internal-face.hpp b/daemon/face/internal-face.hpp
new file mode 100644
index 0000000..1014fca
--- /dev/null
+++ b/daemon/face/internal-face.hpp
@@ -0,0 +1,102 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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_DAEMON_FACE_INTERNAL_FACE_HPP
+#define NFD_DAEMON_FACE_INTERNAL_FACE_HPP
+
+#include "face.hpp"
+
+namespace nfd {
+
+/**
+ * @brief represents a face for internal use in NFD.
+ */
+class InternalFace : public Face
+{
+public:
+
+  InternalFace();
+
+  virtual void
+  sendInterest(const Interest& interest) DECL_OVERRIDE;
+
+  virtual void
+  sendData(const Data& data) DECL_OVERRIDE;
+
+  virtual void
+  close() DECL_OVERRIDE;
+
+  /**
+   * @brief receive a block from a client face
+   *
+   * step1. extracte the packet payload from the received block.
+   * step2. check the type (either Interest or Data) through the payload.
+   * step3. call receiveInterest / receiveData respectively according to the type.
+   *
+   * @param blockFromClient the block from a client face
+   */
+  void
+  receive(const Block& blockFromClient);
+
+  /**
+   * @brief receive an Interest from a client face
+   *
+   * emit the onReceiveInterest signal.
+   *
+   * @param interest the received Interest packet
+   */
+  void
+  receiveInterest(const Interest& interest);
+
+  /**
+   * @brief receive a Data from a client face
+   *
+   * emit the onReceiveData signal.
+   *
+   * @param data the received Data packet
+   */
+  void
+  receiveData(const Data& data);
+
+  /**
+   * @brief compose the whole packet from the received block after payload is extracted
+   *
+   * construct a packet from the extracted payload, and then decode the localControlHeader if the
+   * received block holds more information than the payload.
+   *
+   * @tparam Packet the type of packet, Interest or Data
+   * @param blockFromClient the received block
+   * @param payLoad the extracted payload
+   *
+   * @return a complete packet
+   */
+  template<typename Packet>
+  static shared_ptr<Packet>
+  extractPacketFromBlock(const Block& blockFromClient, const Block& payLoad);
+};
+
+} // namespace nfd
+
+#endif // NFD_DAEMON_FACE_INTERNAL_FACE_HPP
diff --git a/daemon/mgmt/channel-status-publisher.cpp b/daemon/mgmt/channel-status-publisher.cpp
deleted file mode 100644
index bb14879..0000000
--- a/daemon/mgmt/channel-status-publisher.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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 "channel-status-publisher.hpp"
-#include "face/protocol-factory.hpp"
-#include "face/channel.hpp"
-
-#include <ndn-cxx/management/nfd-channel-status.hpp>
-
-namespace nfd {
-
-ChannelStatusPublisher::ChannelStatusPublisher(const FactoryMap& factories,
-                                               AppFace& face,
-                                               const Name& prefix,
-                                               ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_factories(factories)
-{
-}
-
-ChannelStatusPublisher::~ChannelStatusPublisher()
-{
-}
-
-size_t
-ChannelStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-  std::set<shared_ptr<ProtocolFactory> > seenFactories;
-
-  for (FactoryMap::const_iterator i = m_factories.begin();
-       i != m_factories.end(); ++i)
-    {
-      const shared_ptr<ProtocolFactory>& factory = i->second;
-
-      if (seenFactories.find(factory) != seenFactories.end())
-        {
-          continue;
-        }
-      seenFactories.insert(factory);
-
-      std::list<shared_ptr<const Channel> > channels = factory->getChannels();
-
-      for (std::list<shared_ptr<const Channel> >::const_iterator j = channels.begin();
-           j != channels.end(); ++j)
-        {
-          ndn::nfd::ChannelStatus entry;
-          entry.setLocalUri((*j)->getUri().toString());
-
-          totalLength += entry.wireEncode(outBuffer);
-        }
-    }
-
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/channel-status-publisher.hpp b/daemon/mgmt/channel-status-publisher.hpp
deleted file mode 100644
index ef660a3..0000000
--- a/daemon/mgmt/channel-status-publisher.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_DAEMON_MGMT_CHANNEL_STATUS_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_CHANNEL_STATUS_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class ProtocolFactory;
-
-class ChannelStatusPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  typedef std::map< std::string/*protocol*/, shared_ptr<ProtocolFactory> > FactoryMap;
-
-  ChannelStatusPublisher(const FactoryMap& factories,
-                         AppFace& face,
-                         const Name& prefix,
-                         ndn::KeyChain& keyChain);
-
-  virtual
-  ~ChannelStatusPublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const FactoryMap& m_factories;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_CHANNEL_STATUS_PUBLISHER_HPP
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index db3b92f..2991ee6 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -25,12 +25,14 @@
 
 #include "face-manager.hpp"
 
-#include "core/logger.hpp"
 #include "core/network-interface.hpp"
 #include "fw/face-table.hpp"
 #include "face/tcp-factory.hpp"
 #include "face/udp-factory.hpp"
-#include "core/config-file.hpp"
+
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/management/nfd-channel-status.hpp>
+#include <ndn-cxx/management/nfd-face-event-notification.hpp>
 
 #ifdef HAVE_UNIX_SOCKETS
 #include "face/unix-stream-factory.hpp"
@@ -45,120 +47,304 @@
 #include "face/websocket-factory.hpp"
 #endif // HAVE_WEBSOCKET
 
-#include <ndn-cxx/management/nfd-face-event-notification.hpp>
-#include <ndn-cxx/management/nfd-face-query-filter.hpp>
-
 namespace nfd {
 
 NFD_LOG_INIT("FaceManager");
 
-const Name FaceManager::COMMAND_PREFIX("/localhost/nfd/faces");
-
-const size_t FaceManager::COMMAND_UNSIGNED_NCOMPS =
-  FaceManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb parameters
-
-const size_t FaceManager::COMMAND_SIGNED_NCOMPS =
-  FaceManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const FaceManager::SignedVerbAndProcessor FaceManager::SIGNED_COMMAND_VERBS[] =
-  {
-    SignedVerbAndProcessor(
-                           Name::Component("create"),
-                           &FaceManager::createFace
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("destroy"),
-                           &FaceManager::destroyFace
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("enable-local-control"),
-                           &FaceManager::enableLocalControl
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("disable-local-control"),
-                           &FaceManager::disableLocalControl
-                           ),
-  };
-
-const FaceManager::UnsignedVerbAndProcessor FaceManager::UNSIGNED_COMMAND_VERBS[] =
-  {
-    UnsignedVerbAndProcessor(
-                             Name::Component("list"),
-                             &FaceManager::listFaces
-                             ),
-
-    UnsignedVerbAndProcessor(
-                             Name::Component("events"),
-                             &FaceManager::ignoreUnsignedVerb
-                             ),
-
-    UnsignedVerbAndProcessor(
-                             Name::Component("channels"),
-                             &FaceManager::listChannels
-                             ),
-
-    UnsignedVerbAndProcessor(
-                             Name::Component("query"),
-                             &FaceManager::listQueriedFaces
-                             ),
-  };
-
-const Name FaceManager::FACES_LIST_DATASET_PREFIX("/localhost/nfd/faces/list");
-const size_t FaceManager::FACES_LIST_DATASET_NCOMPS = FACES_LIST_DATASET_PREFIX.size();
-
-const Name FaceManager::FACE_EVENTS_PREFIX("/localhost/nfd/faces/events");
-
-const Name FaceManager::CHANNELS_LIST_DATASET_PREFIX("/localhost/nfd/faces/channels");
-const size_t FaceManager::CHANNELS_LIST_DATASET_NCOMPS = CHANNELS_LIST_DATASET_PREFIX.size();
-
-const Name FaceManager::FACES_QUERY_DATASET_PREFIX("/localhost/nfd/faces/query");
-const size_t FaceManager::FACES_QUERY_DATASET_NCOMPS = FACES_QUERY_DATASET_PREFIX.size() + 1;
-
 FaceManager::FaceManager(FaceTable& faceTable,
-                         shared_ptr<InternalFace> face,
-                         ndn::KeyChain& keyChain)
-  : ManagerBase(face, FACE_MANAGER_PRIVILEGE, keyChain)
+                         Dispatcher& dispatcher,
+                         CommandValidator& validator)
+  : ManagerBase(dispatcher, validator, "faces")
   , m_faceTable(faceTable)
-  , m_faceAddConn(m_faceTable.onAdd.connect(bind(&FaceManager::onAddFace, this, _1)))
-  , m_faceRemoveConn(m_faceTable.onRemove.connect(bind(&FaceManager::onRemoveFace, this, _1)))
-  , m_faceStatusPublisher(m_faceTable, *m_face, FACES_LIST_DATASET_PREFIX, keyChain)
-  , m_channelStatusPublisher(m_factories, *m_face, CHANNELS_LIST_DATASET_PREFIX, keyChain)
-  , m_notificationStream(*m_face, FACE_EVENTS_PREFIX, keyChain)
-  , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
-                         SIGNED_COMMAND_VERBS +
-                         (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
-  , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
-                           UNSIGNED_COMMAND_VERBS +
-                           (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
-
 {
-  face->setInterestFilter("/localhost/nfd/faces",
-                          bind(&FaceManager::onFaceRequest, this, _2));
-}
+  registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
+    bind(&FaceManager::createFace, this, _2, _3, _4, _5));
 
-FaceManager::~FaceManager()
-{
+  registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
+    bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
 
+  registerCommandHandler<ndn::nfd::FaceEnableLocalControlCommand>("enable-local-control",
+    bind(&FaceManager::enableLocalControl, this, _2, _3, _4, _5));
+
+  registerCommandHandler<ndn::nfd::FaceDisableLocalControlCommand>("disable-local-control",
+    bind(&FaceManager::disableLocalControl, this, _2, _3, _4, _5));
+
+  registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
+  registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
+  registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
+
+  auto postNotification = registerNotificationStream("events");
+  m_faceAddConn =
+    m_faceTable.onAdd.connect(bind(&FaceManager::afterFaceAdded, this, _1, postNotification));
+  m_faceRemoveConn =
+    m_faceTable.onRemove.connect(bind(&FaceManager::afterFaceRemoved, this, _1, postNotification));
 }
 
 void
 FaceManager::setConfigFile(ConfigFile& configFile)
 {
-  configFile.addSectionHandler("face_system",
-                               bind(&FaceManager::onConfig, this, _1, _2, _3));
+  configFile.addSectionHandler("face_system", bind(&FaceManager::processConfig, this, _1, _2, _3));
 }
 
+void
+FaceManager::createFace(const Name& topPrefix, const Interest& interest,
+                        const ControlParameters& parameters,
+                        const ndn::mgmt::CommandContinuation& done)
+{
+  FaceUri uri;
+  if (!uri.parse(parameters.getUri())) {
+    NFD_LOG_TRACE("failed to parse URI");
+    return done(ControlResponse(400, "Malformed command"));
+  }
+
+  if (!uri.isCanonical()) {
+    NFD_LOG_TRACE("received non-canonical URI");
+    return done(ControlResponse(400, "Non-canonical URI"));
+  }
+
+  FactoryMap::iterator factory = m_factories.find(uri.getScheme());
+  if (factory == m_factories.end()) {
+    return done(ControlResponse(501, "Unsupported protocol"));
+  }
+
+  try {
+    factory->second->createFace(uri,
+                                parameters.getFacePersistency(),
+                                bind(&FaceManager::afterCreateFaceSuccess,
+                                     this, parameters, _1, done),
+                                bind(&FaceManager::afterCreateFaceFailure,
+                                     this, _1, done));
+  }
+  catch (const std::runtime_error& error) {
+    std::string errorMessage = "Face creation failed: ";
+    errorMessage += error.what();
+
+    NFD_LOG_ERROR(errorMessage);
+    return done(ControlResponse(500, errorMessage));
+  }
+  catch (const std::logic_error& error) {
+    std::string errorMessage = "Face creation failed: ";
+    errorMessage += error.what();
+
+    NFD_LOG_ERROR(errorMessage);
+    return done(ControlResponse(500, errorMessage));
+  }
+}
 
 void
-FaceManager::onConfig(const ConfigSection& configSection,
-                      bool isDryRun,
-                      const std::string& filename)
+FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
+                         const ControlParameters& parameters,
+                         const ndn::mgmt::CommandContinuation& done)
+{
+  shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
+  if (target) {
+    target->close();
+  }
+
+  done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+}
+
+void
+FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
+                                const ControlParameters& parameters,
+                                const ndn::mgmt::CommandContinuation& done)
+{
+  auto result = extractLocalControlParameters(interest, parameters, done);
+  if (result.isValid) {
+    result.face->setLocalControlHeaderFeature(result.feature, true);
+    return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+  }
+}
+
+void
+FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
+                                 const ControlParameters& parameters,
+                                 const ndn::mgmt::CommandContinuation& done)
+{
+  auto result = extractLocalControlParameters(interest, parameters, done);
+  if (result.isValid) {
+    result.face->setLocalControlHeaderFeature(result.feature, false);
+    return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+  }
+}
+
+void
+FaceManager::afterCreateFaceSuccess(ControlParameters& parameters,
+                                    const shared_ptr<Face>& newFace,
+                                    const ndn::mgmt::CommandContinuation& done)
+{
+  addCreatedFaceToForwarder(newFace);
+  parameters.setFaceId(newFace->getId());
+  parameters.setUri(newFace->getRemoteUri().toString());
+  parameters.setFacePersistency(newFace->getPersistency());
+
+  done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+}
+
+void
+FaceManager::afterCreateFaceFailure(const std::string& reason,
+                                    const ndn::mgmt::CommandContinuation& done)
+{
+  NFD_LOG_DEBUG("Failed to create face: " << reason);
+
+  done(ControlResponse(408, "Failed to create face: " + reason));
+}
+
+FaceManager::ExtractLocalControlParametersResult
+FaceManager::extractLocalControlParameters(const Interest& request,
+                                           const ControlParameters& parameters,
+                                           const ndn::mgmt::CommandContinuation& done)
+{
+  ExtractLocalControlParametersResult result;
+  result.isValid = false;
+
+  auto face = m_faceTable.get(request.getIncomingFaceId());
+  if (!static_cast<bool>(face)) {
+    NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
+    done(ControlResponse(410, "Face not found"));
+    return result;
+  }
+
+  if (!face->isLocal()) {
+    NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
+                  face->getId());
+    done(ControlResponse(412, "Face is non-local"));
+    return result;
+  }
+
+  result.isValid = true;
+  result.face = dynamic_pointer_cast<LocalFace>(face);
+  result.feature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
+
+  return result;
+}
+
+void
+FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
+                       ndn::mgmt::StatusDatasetContext& context)
+{
+  for (const auto& face : m_faceTable) {
+    context.append(face->getFaceStatus().wireEncode());
+  }
+  context.end();
+}
+
+void
+FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
+                          ndn::mgmt::StatusDatasetContext& context)
+{
+  std::set<shared_ptr<ProtocolFactory>> seenFactories;
+
+  for (auto i = m_factories.begin(); i != m_factories.end(); ++i) {
+    const shared_ptr<ProtocolFactory>& factory = i->second;
+
+    if (seenFactories.find(factory) != seenFactories.end()) {
+      continue;
+    }
+    seenFactories.insert(factory);
+
+    std::list<shared_ptr<const Channel>> channels = factory->getChannels();
+
+    for (auto j = channels.begin(); j != channels.end(); ++j) {
+      ndn::nfd::ChannelStatus entry;
+      entry.setLocalUri((*j)->getUri().toString());
+      context.append(entry.wireEncode());
+    }
+  }
+
+  context.end();
+}
+
+void
+FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
+                        ndn::mgmt::StatusDatasetContext& context)
+{
+  ndn::nfd::FaceQueryFilter faceFilter;
+  const Name& query = interest.getName();
+  try {
+    faceFilter.wireDecode(query[-1].blockFromValue());
+  }
+  catch (const tlv::Error&) {
+    NFD_LOG_DEBUG("query result: malformed filter");
+    return context.reject(ControlResponse(400, "malformed filter"));
+  }
+
+  for (const auto& face : m_faceTable) {
+    if (doesMatchFilter(faceFilter, face)) {
+      context.append(face->getFaceStatus().wireEncode());
+    }
+  }
+  context.end();
+}
+
+bool
+FaceManager::doesMatchFilter(const ndn::nfd::FaceQueryFilter& filter, shared_ptr<Face> face)
+{
+  if (filter.hasFaceId() &&
+      filter.getFaceId() != static_cast<uint64_t>(face->getId())) {
+    return false;
+  }
+
+  if (filter.hasUriScheme() &&
+      filter.getUriScheme() != face->getRemoteUri().getScheme() &&
+      filter.getUriScheme() != face->getLocalUri().getScheme()) {
+    return false;
+  }
+
+  if (filter.hasRemoteUri() &&
+      filter.getRemoteUri() != face->getRemoteUri().toString()) {
+    return false;
+  }
+
+  if (filter.hasLocalUri() &&
+      filter.getLocalUri() != face->getLocalUri().toString()) {
+    return false;
+  }
+
+  if (filter.hasFaceScope() &&
+      (filter.getFaceScope() == ndn::nfd::FACE_SCOPE_LOCAL) != face->isLocal()) {
+    return false;
+  }
+
+  if (filter.hasFacePersistency() &&
+      filter.getFacePersistency() != face->getPersistency()) {
+    return false;
+  }
+
+  if (filter.hasLinkType() &&
+      (filter.getLinkType() == ndn::nfd::LINK_TYPE_MULTI_ACCESS) != face->isMultiAccess()) {
+    return false;
+  }
+
+  return true;
+}
+
+void
+FaceManager::afterFaceAdded(shared_ptr<Face> face,
+                            const ndn::mgmt::PostNotification& post)
+{
+  ndn::nfd::FaceEventNotification notification;
+  notification.setKind(ndn::nfd::FACE_EVENT_CREATED);
+  face->copyStatusTo(notification);
+
+  post(notification.wireEncode());
+}
+
+void
+FaceManager::afterFaceRemoved(shared_ptr<Face> face,
+                              const ndn::mgmt::PostNotification& post)
+{
+  ndn::nfd::FaceEventNotification notification;
+  notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED);
+  face->copyStatusTo(notification);
+
+  post(notification.wireEncode());
+}
+
+void
+FaceManager::processConfig(const ConfigSection& configSection,
+                           bool isDryRun,
+                           const std::string& filename)
 {
   bool hasSeenUnix = false;
   bool hasSeenTcp = false;
@@ -168,53 +354,51 @@
 
   const std::vector<NetworkInterfaceInfo> nicList(listNetworkInterfaces());
 
-  for (const auto& item : configSection)
-    {
-      if (item.first == "unix")
-        {
-          if (hasSeenUnix)
-            BOOST_THROW_EXCEPTION(Error("Duplicate \"unix\" section"));
-          hasSeenUnix = true;
+  for (const auto& item : configSection) {
+    if (item.first == "unix") {
+      if (hasSeenUnix) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"unix\" section"));
+      }
+      hasSeenUnix = true;
 
-          processSectionUnix(item.second, isDryRun);
-        }
-      else if (item.first == "tcp")
-        {
-          if (hasSeenTcp)
-            BOOST_THROW_EXCEPTION(Error("Duplicate \"tcp\" section"));
-          hasSeenTcp = true;
-
-          processSectionTcp(item.second, isDryRun);
-        }
-      else if (item.first == "udp")
-        {
-          if (hasSeenUdp)
-            BOOST_THROW_EXCEPTION(Error("Duplicate \"udp\" section"));
-          hasSeenUdp = true;
-
-          processSectionUdp(item.second, isDryRun, nicList);
-        }
-      else if (item.first == "ether")
-        {
-          if (hasSeenEther)
-            BOOST_THROW_EXCEPTION(Error("Duplicate \"ether\" section"));
-          hasSeenEther = true;
-
-          processSectionEther(item.second, isDryRun, nicList);
-        }
-      else if (item.first == "websocket")
-        {
-          if (hasSeenWebSocket)
-            BOOST_THROW_EXCEPTION(Error("Duplicate \"websocket\" section"));
-          hasSeenWebSocket = true;
-
-          processSectionWebSocket(item.second, isDryRun);
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(Error("Unrecognized option \"" + item.first + "\""));
-        }
+      processSectionUnix(item.second, isDryRun);
     }
+    else if (item.first == "tcp") {
+      if (hasSeenTcp) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"tcp\" section"));
+      }
+      hasSeenTcp = true;
+
+      processSectionTcp(item.second, isDryRun);
+    }
+    else if (item.first == "udp") {
+      if (hasSeenUdp) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"udp\" section"));
+      }
+      hasSeenUdp = true;
+
+      processSectionUdp(item.second, isDryRun, nicList);
+    }
+    else if (item.first == "ether") {
+      if (hasSeenEther) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"ether\" section"));
+      }
+      hasSeenEther = true;
+
+      processSectionEther(item.second, isDryRun, nicList);
+    }
+    else if (item.first == "websocket") {
+      if (hasSeenWebSocket) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"websocket\" section"));
+      }
+      hasSeenWebSocket = true;
+
+      processSectionWebSocket(item.second, isDryRun);
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Unrecognized option \"" + item.first + "\""));
+    }
+  }
 }
 
 void
@@ -230,50 +414,34 @@
 
   std::string path = "/var/run/nfd.sock";
 
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "path")
-        {
-          path = i->second.get_value<std::string>();
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
-                                                  "\"unix\" section"));
-        }
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "path") {
+      path = i->second.get_value<std::string>();
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"unix\" section"));
+    }
+  }
+
+  if (!isDryRun) {
+    if (m_factories.count("unix") > 0) {
+      return;
     }
 
-  if (!isDryRun)
-    {
-      if (m_factories.count("unix") > 0)
-        {
-          return;
-          // shared_ptr<UnixStreamFactory> factory
-          //   = static_pointer_cast<UnixStreamFactory>(m_factories["unix"]);
-          // shared_ptr<UnixStreamChannel> unixChannel = factory->findChannel(path);
+    shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
+    shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
 
-          // if (static_cast<bool>(unixChannel))
-          //   {
-          //     return;
-          //   }
-        }
+    // Should acceptFailed callback be used somehow?
+    unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                        UnixStreamChannel::ConnectFailedCallback());
 
-      shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
-      shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
-
-      // Should acceptFailed callback be used somehow?
-      unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                          UnixStreamChannel::ConnectFailedCallback());
-
-      m_factories.insert(std::make_pair("unix", factory));
-    }
+    m_factories.insert(std::make_pair("unix", factory));
+  }
 #else
   BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without Unix sockets support, "
                                           "cannot process \"unix\" section"));
 #endif // HAVE_UNIX_SOCKETS
-
 }
 
 void
@@ -291,86 +459,69 @@
   bool enableV4 = true;
   bool enableV6 = true;
 
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "port")
-        {
-          port = i->second.get_value<std::string>();
-          try
-            {
-              uint16_t portNo = boost::lexical_cast<uint16_t>(port);
-              NFD_LOG_TRACE("TCP port set to " << portNo);
-            }
-          catch (const std::bad_cast& error)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                      i->first + "\" in \"tcp\" section"));
-            }
-        }
-      else if (i->first == "listen")
-        {
-          needToListen = parseYesNo(i, i->first, "tcp");
-        }
-      else if (i->first == "enable_v4")
-        {
-          enableV4 = parseYesNo(i, i->first, "tcp");
-        }
-      else if (i->first == "enable_v6")
-        {
-          enableV6 = parseYesNo(i, i->first, "tcp");
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
-                                                  "\"tcp\" section"));
-        }
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "port") {
+      port = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+        NFD_LOG_TRACE("TCP port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"tcp\" section"));
+      }
+    }
+    else if (i->first == "listen") {
+      needToListen = ConfigFile::parseYesNo(i, i->first, "tcp");
+    }
+    else if (i->first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, i->first, "tcp");
+    }
+    else if (i->first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, i->first, "tcp");
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"tcp\" section"));
+    }
+  }
+
+  if (!enableV4 && !enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                            " Remove \"tcp\" section to disable TCP channels or"
+                                            " re-enable at least one channel type."));
+  }
+
+  if (!isDryRun) {
+    if (m_factories.count("tcp") > 0) {
+      return;
     }
 
-  if (!enableV4 && !enableV6)
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
-                                              " Remove \"tcp\" section to disable TCP channels or"
-                                              " re-enable at least one channel type."));
+    shared_ptr<TcpFactory> factory = make_shared<TcpFactory>(port);
+    m_factories.insert(std::make_pair("tcp", factory));
+
+    if (enableV4) {
+      shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+      if (needToListen) {
+        // Should acceptFailed callback be used somehow?
+        ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                            TcpChannel::ConnectFailedCallback());
+      }
+
+      m_factories.insert(std::make_pair("tcp4", factory));
     }
 
-  if (!isDryRun)
-    {
-      if (m_factories.count("tcp") > 0)
-        {
-          return;
-        }
+    if (enableV6) {
+      shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
+      if (needToListen) {
+        // Should acceptFailed callback be used somehow?
+        ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                            TcpChannel::ConnectFailedCallback());
+      }
 
-      shared_ptr<TcpFactory> factory = make_shared<TcpFactory>(port);
-      m_factories.insert(std::make_pair("tcp", factory));
-
-      if (enableV4)
-        {
-          shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
-          if (needToListen)
-            {
-              // Should acceptFailed callback be used somehow?
-              ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                                  TcpChannel::ConnectFailedCallback());
-            }
-
-          m_factories.insert(std::make_pair("tcp4", factory));
-        }
-
-      if (enableV6)
-        {
-          shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
-          if (needToListen)
-            {
-              // Should acceptFailed callback be used somehow?
-              ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                                  TcpChannel::ConnectFailedCallback());
-            }
-
-          m_factories.insert(std::make_pair("tcp6", factory));
-        }
+      m_factories.insert(std::make_pair("tcp6", factory));
     }
+  }
 }
 
 void
@@ -401,221 +552,177 @@
   std::string mcastPort = "56363";
 
 
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "port")
-        {
-          port = i->second.get_value<std::string>();
-          try
-            {
-              uint16_t portNo = boost::lexical_cast<uint16_t>(port);
-              NFD_LOG_TRACE("UDP port set to " << portNo);
-            }
-          catch (const std::bad_cast& error)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                      i->first + "\" in \"udp\" section"));
-            }
-        }
-      else if (i->first == "enable_v4")
-        {
-          enableV4 = parseYesNo(i, i->first, "udp");
-        }
-      else if (i->first == "enable_v6")
-        {
-          enableV6 = parseYesNo(i, i->first, "udp");
-        }
-      else if (i->first == "idle_timeout")
-        {
-          try
-            {
-              timeout = i->second.get_value<size_t>();
-            }
-          catch (const std::exception& e)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                      i->first + "\" in \"udp\" section"));
-            }
-        }
-      else if (i->first == "keep_alive_interval")
-        {
-          try
-            {
-              keepAliveInterval = i->second.get_value<size_t>();
-
-              /// \todo Make use of keepAliveInterval
-              (void)(keepAliveInterval);
-            }
-          catch (const std::exception& e)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                      i->first + "\" in \"udp\" section"));
-            }
-        }
-      else if (i->first == "mcast")
-        {
-          useMcast = parseYesNo(i, i->first, "udp");
-        }
-      else if (i->first == "mcast_port")
-        {
-          mcastPort = i->second.get_value<std::string>();
-          try
-            {
-              uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
-              NFD_LOG_TRACE("UDP multicast port set to " << portNo);
-            }
-          catch (const std::bad_cast& error)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                      i->first + "\" in \"udp\" section"));
-            }
-        }
-      else if (i->first == "mcast_group")
-        {
-          using namespace boost::asio::ip;
-          mcastGroup = i->second.get_value<std::string>();
-          try
-            {
-              address mcastGroupTest = address::from_string(mcastGroup);
-              if (!mcastGroupTest.is_v4())
-                {
-                  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                          i->first + "\" in \"udp\" section"));
-                }
-            }
-          catch(const std::runtime_error& e)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                      i->first + "\" in \"udp\" section"));
-            }
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
-                                                  "\"udp\" section"));
-        }
-    }
-
-  if (!enableV4 && !enableV6)
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
-                                              " Remove \"udp\" section to disable UDP channels or"
-                                              " re-enable at least one channel type."));
-    }
-  else if (useMcast && !enableV4)
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
-                                              " have been disabled (conflicting configuration"
-                                              " options set)"));
-    }
-
-  /// \todo what is keep alive interval used for?
-
-  if (!isDryRun)
-    {
-      shared_ptr<UdpFactory> factory;
-      bool isReload = false;
-      if (m_factories.count("udp") > 0) {
-        isReload = true;
-        factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "port") {
+      port = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+        NFD_LOG_TRACE("UDP port set to " << portNo);
       }
-      else {
-        factory = make_shared<UdpFactory>(port);
-        m_factories.insert(std::make_pair("udp", factory));
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, i->first, "udp");
+    }
+    else if (i->first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, i->first, "udp");
+    }
+    else if (i->first == "idle_timeout") {
+      try {
+        timeout = i->second.get_value<size_t>();
+      }
+      catch (const std::exception& e) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "keep_alive_interval") {
+      try {
+        keepAliveInterval = i->second.get_value<size_t>();
+
+        /// \todo Make use of keepAliveInterval
+        /// \todo what is keep alive interval used for?
+        (void)(keepAliveInterval);
+      }
+      catch (const std::exception& e) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "mcast") {
+      useMcast = ConfigFile::parseYesNo(i, i->first, "udp");
+    }
+    else if (i->first == "mcast_port") {
+      mcastPort = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
+        NFD_LOG_TRACE("UDP multicast port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "mcast_group") {
+      using namespace boost::asio::ip;
+      mcastGroup = i->second.get_value<std::string>();
+      try {
+        address mcastGroupTest = address::from_string(mcastGroup);
+        if (!mcastGroupTest.is_v4()) {
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                  i->first + "\" in \"udp\" section"));
+        }
+      }
+      catch(const std::runtime_error& e) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"udp\" section"));
+    }
+  }
+
+  if (!enableV4 && !enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                            " Remove \"udp\" section to disable UDP channels or"
+                                            " re-enable at least one channel type."));
+  }
+  else if (useMcast && !enableV4) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
+                                            " have been disabled (conflicting configuration options set)"));
+  }
+
+  if (!isDryRun) {
+    shared_ptr<UdpFactory> factory;
+    bool isReload = false;
+    if (m_factories.count("udp") > 0) {
+      isReload = true;
+      factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
+    }
+    else {
+      factory = make_shared<UdpFactory>(port);
+      m_factories.insert(std::make_pair("udp", factory));
+    }
+
+    if (!isReload && enableV4) {
+      shared_ptr<UdpChannel> v4Channel =
+        factory->createChannel("0.0.0.0", port, time::seconds(timeout));
+
+      v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                        UdpChannel::ConnectFailedCallback());
+
+      m_factories.insert(std::make_pair("udp4", factory));
+    }
+
+    if (!isReload && enableV6) {
+      shared_ptr<UdpChannel> v6Channel =
+        factory->createChannel("::", port, time::seconds(timeout));
+
+      v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                        UdpChannel::ConnectFailedCallback());
+      m_factories.insert(std::make_pair("udp6", factory));
+    }
+
+    if (useMcast && enableV4) {
+      std::vector<NetworkInterfaceInfo> ipv4MulticastInterfaces;
+      for (const auto& nic : nicList) {
+        if (nic.isUp() && nic.isMulticastCapable() && !nic.ipv4Addresses.empty()) {
+          ipv4MulticastInterfaces.push_back(nic);
+        }
       }
 
-      if (!isReload && enableV4)
-        {
-          shared_ptr<UdpChannel> v4Channel =
-            factory->createChannel("0.0.0.0", port, time::seconds(timeout));
-
-          v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                            UdpChannel::ConnectFailedCallback());
-
-          m_factories.insert(std::make_pair("udp4", factory));
-        }
-
-      if (!isReload && enableV6)
-        {
-          shared_ptr<UdpChannel> v6Channel =
-            factory->createChannel("::", port, time::seconds(timeout));
-
-          v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                            UdpChannel::ConnectFailedCallback());
-          m_factories.insert(std::make_pair("udp6", factory));
-        }
-
-      if (useMcast && enableV4)
-        {
-          std::vector<NetworkInterfaceInfo> ipv4MulticastInterfaces;
-          for (const auto& nic : nicList)
-            {
-              if (nic.isUp() && nic.isMulticastCapable() && !nic.ipv4Addresses.empty())
-                {
-                  ipv4MulticastInterfaces.push_back(nic);
-                }
-            }
-
-          bool isNicNameNecessary = false;
+      bool isNicNameNecessary = false;
 #if defined(__linux__)
-          if (ipv4MulticastInterfaces.size() > 1)
-            {
-              // On Linux if we have more than one MulticastUdpFace
-              // we need to specify the name of the interface
-              isNicNameNecessary = true;
-            }
+      if (ipv4MulticastInterfaces.size() > 1) {
+        // On Linux if we have more than one MulticastUdpFace
+        // we need to specify the name of the interface
+        isNicNameNecessary = true;
+      }
 #endif
 
-          std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
-          for (UdpFactory::MulticastFaceMap::const_iterator i =
-                 factory->getMulticastFaces().begin();
-               i != factory->getMulticastFaces().end();
-               ++i)
-            {
-              multicastFacesToRemove.push_back(i->second);
-            }
+      std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
 
-          for (const auto& nic : ipv4MulticastInterfaces)
-            {
-              shared_ptr<MulticastUdpFace> newFace;
-              newFace = factory->createMulticastFace(nic.ipv4Addresses[0].to_string(),
-                                                     mcastGroup,
-                                                     mcastPort,
-                                                     isNicNameNecessary ? nic.name : "");
-              addCreatedFaceToForwarder(newFace);
-              multicastFacesToRemove.remove(newFace);
-            }
+      for (const auto& nic : ipv4MulticastInterfaces) {
+        shared_ptr<MulticastUdpFace> newFace;
+        newFace = factory->createMulticastFace(nic.ipv4Addresses[0].to_string(),
+                                               mcastGroup,
+                                               mcastPort,
+                                               isNicNameNecessary ? nic.name : "");
+        addCreatedFaceToForwarder(newFace);
+        multicastFacesToRemove.remove(newFace);
+      }
 
-          for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
-        }
-      else
-        {
-          std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
-          for (UdpFactory::MulticastFaceMap::const_iterator i =
-                 factory->getMulticastFaces().begin();
-               i != factory->getMulticastFaces().end();
-               ++i)
-            {
-              multicastFacesToRemove.push_back(i->second);
-            }
-
-          for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
-        }
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
     }
+    else {
+      std::list<shared_ptr<MulticastUdpFace>> multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
+
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
+    }
+  }
 }
 
 void
@@ -635,107 +742,82 @@
   bool useMcast = true;
   ethernet::Address mcastGroup(ethernet::getDefaultMulticastAddress());
 
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "mcast")
-        {
-          useMcast = parseYesNo(i, i->first, "ether");
-        }
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "mcast") {
+      useMcast = ConfigFile::parseYesNo(i, i->first, "ether");
+    }
+    else if (i->first == "mcast_group") {
+      mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
+      if (mcastGroup.isNull()) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"ether\" section"));
+      }
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"ether\" section"));
+    }
+  }
 
-      else if (i->first == "mcast_group")
-        {
-          mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
-          if (mcastGroup.isNull())
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                      i->first + "\" in \"ether\" section"));
-            }
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first +
-                                                  "\" in \"ether\" section"));
-        }
+  if (!isDryRun) {
+    shared_ptr<EthernetFactory> factory;
+    if (m_factories.count("ether") > 0) {
+      factory = static_pointer_cast<EthernetFactory>(m_factories["ether"]);
+    }
+    else {
+      factory = make_shared<EthernetFactory>();
+      m_factories.insert(std::make_pair("ether", factory));
     }
 
-  if (!isDryRun)
-    {
-      shared_ptr<EthernetFactory> factory;
-      if (m_factories.count("ether") > 0) {
-        factory = static_pointer_cast<EthernetFactory>(m_factories["ether"]);
-      }
-      else {
-        factory = make_shared<EthernetFactory>();
-        m_factories.insert(std::make_pair("ether", factory));
+    if (useMcast) {
+      std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
       }
 
-      if (useMcast)
-        {
-          std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
-          for (EthernetFactory::MulticastFaceMap::const_iterator i =
-                 factory->getMulticastFaces().begin();
-               i != factory->getMulticastFaces().end();
-               ++i)
-            {
-              multicastFacesToRemove.push_back(i->second);
-            }
+      for (const auto& nic : nicList) {
+        if (nic.isUp() && nic.isMulticastCapable()) {
+          try {
+            shared_ptr<EthernetFace> newFace =
+            factory->createMulticastFace(nic, mcastGroup);
 
-          for (const auto& nic : nicList)
-            {
-              if (nic.isUp() && nic.isMulticastCapable())
-                {
-                  try
-                    {
-                      shared_ptr<EthernetFace> newFace =
-                        factory->createMulticastFace(nic, mcastGroup);
-
-                      addCreatedFaceToForwarder(newFace);
-                      multicastFacesToRemove.remove(newFace);
-                    }
-                  catch (const EthernetFactory::Error& factoryError)
-                    {
-                      NFD_LOG_ERROR(factoryError.what() << ", continuing");
-                    }
-                  catch (const EthernetFace::Error& faceError)
-                    {
-                      NFD_LOG_ERROR(faceError.what() << ", continuing");
-                    }
-                }
-            }
-
-          for (std::list<shared_ptr<EthernetFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
+            addCreatedFaceToForwarder(newFace);
+            multicastFacesToRemove.remove(newFace);
+          }
+          catch (const EthernetFactory::Error& factoryError) {
+            NFD_LOG_ERROR(factoryError.what() << ", continuing");
+          }
+          catch (const EthernetFace::Error& faceError) {
+            NFD_LOG_ERROR(faceError.what() << ", continuing");
+          }
         }
-      else
-        {
-          std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
-          for (EthernetFactory::MulticastFaceMap::const_iterator i =
-                 factory->getMulticastFaces().begin();
-               i != factory->getMulticastFaces().end();
-               ++i)
-            {
-              multicastFacesToRemove.push_back(i->second);
-            }
+      }
 
-          for (std::list<shared_ptr<EthernetFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
-        }
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
     }
+    else {
+      std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
+
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
+    }
+  }
 #else
-  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without libpcap, cannot "
-                                          "process \"ether\" section"));
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section"));
 #endif // HAVE_LIBPCAP
 }
 
@@ -758,442 +840,78 @@
   bool enableV4 = true;
   bool enableV6 = true;
 
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "port")
-        {
-          port = i->second.get_value<std::string>();
-          try
-            {
-              uint16_t portNo = boost::lexical_cast<uint16_t>(port);
-              NFD_LOG_TRACE("WebSocket port set to " << portNo);
-            }
-          catch (const std::bad_cast& error)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                      i->first + "\" in \"websocket\" section"));
-            }
-        }
-      else if (i->first == "listen")
-        {
-          needToListen = parseYesNo(i, i->first, "websocket");
-        }
-      else if (i->first == "enable_v4")
-        {
-          enableV4 = parseYesNo(i, i->first, "websocket");
-        }
-      else if (i->first == "enable_v6")
-        {
-          enableV6 = parseYesNo(i, i->first, "websocket");
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
-                                                  i->first + "\" in \"websocket\" section"));
-        }
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "port") {
+      port = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+        NFD_LOG_TRACE("WebSocket port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"websocket\" section"));
+      }
+    }
+    else if (i->first == "listen") {
+      needToListen = ConfigFile::parseYesNo(i, i->first, "websocket");
+    }
+    else if (i->first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, i->first, "websocket");
+    }
+    else if (i->first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, i->first, "websocket");
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"websocket\" section"));
+    }
+  }
+
+  if (!enableV4 && !enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                            " Remove \"websocket\" section to disable WebSocket channels or"
+                                            " re-enable at least one channel type."));
+  }
+
+  if (!enableV4 && enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel."));
+  }
+
+  if (!isDryRun) {
+    if (m_factories.count("websocket") > 0) {
+      return;
     }
 
-  if (!enableV4 && !enableV6)
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
-                                              " Remove \"websocket\" section to disable WebSocket"
-                                              " channels or re-enable at least one channel type."));
+    shared_ptr<WebSocketFactory> factory = make_shared<WebSocketFactory>(port);
+    m_factories.insert(std::make_pair("websocket", factory));
+
+    if (enableV6 && enableV4) {
+      shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", port);
+      if (needToListen) {
+        ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
+      }
+
+      m_factories.insert(std::make_pair("websocket46", factory));
     }
+    else if (enableV4) {
+      shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+      if (needToListen) {
+        ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
+      }
 
-  if (!enableV4 && enableV6)
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel."));
+      m_factories.insert(std::make_pair("websocket4", factory));
     }
-
-  if (!isDryRun)
-    {
-      if (m_factories.count("websocket") > 0)
-        {
-          return;
-        }
-
-      shared_ptr<WebSocketFactory> factory = make_shared<WebSocketFactory>(port);
-      m_factories.insert(std::make_pair("websocket", factory));
-
-      if (enableV6 && enableV4)
-        {
-          shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", port);
-          if (needToListen)
-            {
-              ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
-            }
-
-          m_factories.insert(std::make_pair("websocket46", factory));
-        }
-      else if (enableV4)
-        {
-          shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
-          if (needToListen)
-            {
-              ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
-            }
-
-          m_factories.insert(std::make_pair("websocket4", factory));
-        }
-    }
+  }
 #else
   BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without WebSocket, "
                                           "cannot process \"websocket\" section"));
 #endif // HAVE_WEBSOCKET
 }
 
-
 void
-FaceManager::onFaceRequest(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps <= COMMAND_PREFIX.size())
-    {
-      // command is too short to have a verb
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
-
-  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
-  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
-    {
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      (unsignedVerbProcessor->second)(this, request);
-    }
-  else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
-           commandNComps < COMMAND_SIGNED_NCOMPS)
-    {
-      NFD_LOG_DEBUG("command result: unsigned verb: " << command);
-      sendResponse(command, 401, "Signature required");
-    }
-  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
-           !COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-    }
-  else
-    {
-      validate(request,
-               bind(&FaceManager::onValidatedFaceRequest, this, _1),
-               bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
-    }
-}
-
-void
-FaceManager::onValidatedFaceRequest(const shared_ptr<const Interest>& request)
-{
-  const Name& command = request->getName();
-  const Name::Component& verb = command[COMMAND_PREFIX.size()];
-  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
-  SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find(verb);
-  if (signedVerbProcessor != m_signedVerbDispatch.end())
-    {
-      ControlParameters parameters;
-      if (!extractParameters(parameterComponent, parameters))
-        {
-          sendResponse(command, 400, "Malformed command");
-          return;
-        }
-
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      (signedVerbProcessor->second)(this, *request, parameters);
-    }
-  else
-    {
-      NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
-      sendResponse(command, 501, "Unsupported command");
-    }
-
-}
-
-void
-FaceManager::addCreatedFaceToForwarder(const shared_ptr<Face>& newFace)
+FaceManager::addCreatedFaceToForwarder(shared_ptr<Face> newFace)
 {
   m_faceTable.add(newFace);
-
-  //NFD_LOG_DEBUG("Created face " << newFace->getRemoteUri() << " ID " << newFace->getId());
 }
 
-void
-FaceManager::onCreated(const Name& requestName,
-                       ControlParameters& parameters,
-                       const shared_ptr<Face>& newFace)
-{
-  addCreatedFaceToForwarder(newFace);
-  parameters.setFaceId(newFace->getId());
-  parameters.setUri(newFace->getRemoteUri().toString());
-  parameters.setFacePersistency(newFace->getPersistency());
-
-  sendResponse(requestName, 200, "Success", parameters.wireEncode());
-}
-
-void
-FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
-{
-  NFD_LOG_DEBUG("Failed to create face: " << reason);
-  sendResponse(requestName, 408, reason);
-}
-
-void
-FaceManager::createFace(const Interest& request,
-                        ControlParameters& parameters)
-{
-  const Name& requestName = request.getName();
-  ndn::nfd::FaceCreateCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      sendResponse(requestName, 400, "Malformed command");
-      NFD_LOG_TRACE("invalid control parameters URI");
-      return;
-    }
-
-  FaceUri uri;
-  if (!uri.parse(parameters.getUri()))
-    {
-      sendResponse(requestName, 400, "Malformed command");
-      NFD_LOG_TRACE("failed to parse URI");
-      return;
-    }
-
-  if (!uri.isCanonical())
-    {
-      sendResponse(requestName, 400, "Non-canonical URI");
-      NFD_LOG_TRACE("received non-canonical URI");
-      return;
-    }
-
-  FactoryMap::iterator factory = m_factories.find(uri.getScheme());
-  if (factory == m_factories.end())
-    {
-      sendResponse(requestName, 501, "Unsupported protocol");
-      return;
-    }
-
-  try
-    {
-      factory->second->createFace(uri,
-                                  parameters.getFacePersistency(),
-                                  bind(&FaceManager::onCreated,
-                                       this, requestName, parameters, _1),
-                                  bind(&FaceManager::onConnectFailed,
-                                       this, requestName, _1));
-    }
-  catch (const std::runtime_error& error)
-    {
-      std::string errorMessage = "NFD error: ";
-      errorMessage += error.what();
-
-      NFD_LOG_ERROR(errorMessage);
-      sendResponse(requestName, 500, errorMessage);
-    }
-  catch (const std::logic_error& error)
-    {
-      std::string errorMessage = "NFD error: ";
-      errorMessage += error.what();
-
-      NFD_LOG_ERROR(errorMessage);
-      sendResponse(requestName, 500, errorMessage);
-    }
-}
-
-
-void
-FaceManager::destroyFace(const Interest& request,
-                         ControlParameters& parameters)
-{
-  const Name& requestName = request.getName();
-  ndn::nfd::FaceDestroyCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      sendResponse(requestName, 400, "Malformed command");
-      return;
-    }
-
-  shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
-  if (static_cast<bool>(target))
-    {
-      target->close();
-    }
-
-  sendResponse(requestName, 200, "Success", parameters.wireEncode());
-
-}
-
-void
-FaceManager::onAddFace(shared_ptr<Face> face)
-{
-  ndn::nfd::FaceEventNotification notification;
-  notification.setKind(ndn::nfd::FACE_EVENT_CREATED);
-  face->copyStatusTo(notification);
-
-  m_notificationStream.postNotification(notification);
-}
-
-void
-FaceManager::onRemoveFace(shared_ptr<Face> face)
-{
-  ndn::nfd::FaceEventNotification notification;
-  notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED);
-  face->copyStatusTo(notification);
-
-  m_notificationStream.postNotification(notification);
-}
-
-bool
-FaceManager::extractLocalControlParameters(const Interest& request,
-                                           ControlParameters& parameters,
-                                           ControlCommand& command,
-                                           shared_ptr<LocalFace>& outFace,
-                                           LocalControlFeature& outFeature)
-{
-  if (!validateParameters(command, parameters))
-    {
-      sendResponse(request.getName(), 400, "Malformed command");
-      return false;
-    }
-
-  shared_ptr<Face> face = m_faceTable.get(request.getIncomingFaceId());
-
-  if (!static_cast<bool>(face))
-    {
-      NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
-      sendResponse(request.getName(), 410, "Face not found");
-      return false;
-    }
-  else if (!face->isLocal())
-    {
-      NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
-                    face->getId());
-      sendResponse(request.getName(), 412, "Face is non-local");
-      return false;
-    }
-
-  outFace = dynamic_pointer_cast<LocalFace>(face);
-  outFeature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
-
-  return true;
-}
-
-void
-FaceManager::enableLocalControl(const Interest& request,
-                                ControlParameters& parameters)
-{
-  ndn::nfd::FaceEnableLocalControlCommand command;
-
-
-  shared_ptr<LocalFace> face;
-  LocalControlFeature feature;
-
-  if (extractLocalControlParameters(request, parameters, command, face, feature))
-    {
-      face->setLocalControlHeaderFeature(feature, true);
-      sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
-    }
-}
-
-void
-FaceManager::disableLocalControl(const Interest& request,
-                                 ControlParameters& parameters)
-{
-  ndn::nfd::FaceDisableLocalControlCommand command;
-  shared_ptr<LocalFace> face;
-  LocalControlFeature feature;
-
-  if (extractLocalControlParameters(request, parameters, command, face, feature))
-    {
-      face->setLocalControlHeaderFeature(feature, false);
-      sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
-    }
-}
-
-void
-FaceManager::listFaces(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps < FACES_LIST_DATASET_NCOMPS ||
-      !FACES_LIST_DATASET_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  m_faceStatusPublisher.publish();
-}
-
-void
-FaceManager::listChannels(const Interest& request)
-{
-  NFD_LOG_DEBUG("in listChannels");
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps < CHANNELS_LIST_DATASET_NCOMPS ||
-      !CHANNELS_LIST_DATASET_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  NFD_LOG_DEBUG("publishing");
-  m_channelStatusPublisher.publish();
-}
-
-void
-FaceManager::listQueriedFaces(const Interest& request)
-{
-  NFD_LOG_DEBUG("in listQueriedFaces");
-  const Name& query = request.getName();
-  const size_t queryNComps = query.size();
-
-  if (queryNComps < FACES_QUERY_DATASET_NCOMPS ||
-      !FACES_QUERY_DATASET_PREFIX.isPrefixOf(query))
-    {
-      NFD_LOG_DEBUG("query result: malformed");
-      sendNack(query);
-      return;
-    }
-
-  ndn::nfd::FaceQueryFilter faceFilter;
-  try
-    {
-      faceFilter.wireDecode(query[-1].blockFromValue());
-    }
-  catch (tlv::Error&)
-    {
-      NFD_LOG_DEBUG("query result: malformed filter");
-      sendNack(query);
-      return;
-    }
-
-  FaceQueryStatusPublisher
-    faceQueryStatusPublisher(m_faceTable, *m_face, query, faceFilter, m_keyChain);
-
-  faceQueryStatusPublisher.publish();
-}
-
-shared_ptr<ProtocolFactory>
-FaceManager::findFactory(const std::string& protocol)
-{
-  FactoryMap::iterator factory = m_factories.find(protocol);
-  if (factory != m_factories.end())
-    return factory->second;
-  else
-    return shared_ptr<ProtocolFactory>();
-}
-
-} // namespace nfd
+} // namespace
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index 74dc0dd..f5283d6 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -26,118 +26,105 @@
 #ifndef NFD_DAEMON_MGMT_FACE_MANAGER_HPP
 #define NFD_DAEMON_MGMT_FACE_MANAGER_HPP
 
-#include "common.hpp"
-#include "core/notification-stream.hpp"
+#include "manager-base.hpp"
 #include "face/local-face.hpp"
-#include "mgmt/manager-base.hpp"
-#include "mgmt/face-status-publisher.hpp"
-#include "mgmt/channel-status-publisher.hpp"
-#include "mgmt/face-query-status-publisher.hpp"
-
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
-#include <ndn-cxx/management/nfd-control-response.hpp>
+#include <ndn-cxx/management/nfd-face-query-filter.hpp>
 
 namespace nfd {
 
-const std::string FACE_MANAGER_PRIVILEGE = "faces";
-
-class ConfigFile;
-class Face;
 class FaceTable;
-class LocalFace;
 class NetworkInterfaceInfo;
 class ProtocolFactory;
 
+/**
+ * @brief implement the Face Management of NFD Management Protocol.
+ * @sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt
+ */
 class FaceManager : public ManagerBase
 {
 public:
-  class Error : public ManagerBase::Error
-  {
-  public:
-    Error(const std::string& what) : ManagerBase::Error(what) {}
-  };
+  FaceManager(FaceTable& faceTable,
+              Dispatcher& dispatcher,
+              CommandValidator& validator);
 
   /**
-   * \throws FaceManager::Error if localPort is an invalid port number
-   */
-  FaceManager(FaceTable& faceTable,
-              shared_ptr<InternalFace> face,
-              ndn::KeyChain& keyChain);
-
-  virtual
-  ~FaceManager();
-
-  /** \brief Subscribe to a face management section(s) for the config file
+   * @brief Subscribe to face_system section for the config file
    */
   void
   setConfigFile(ConfigFile& configFile);
 
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // ControlCommand
   void
-  onFaceRequest(const Interest& request);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  listFaces(const Interest& request);
+  createFace(const Name& topPrefix, const Interest& interest,
+             const ControlParameters& parameters,
+             const ndn::mgmt::CommandContinuation& done);
 
   void
-  listChannels(const Interest& request);
+  destroyFace(const Name& topPrefix, const Interest& interest,
+              const ControlParameters& parameters,
+              const ndn::mgmt::CommandContinuation& done);
 
   void
-  listQueriedFaces(const Interest& request);
+  enableLocalControl(const Name& topPrefix, const Interest& interest,
+                     const ControlParameters& parameters,
+                     const ndn::mgmt::CommandContinuation& done);
 
-  shared_ptr<ProtocolFactory>
-  findFactory(const std::string& protocol);
-
-PROTECTED_WITH_TESTS_ELSE_PRIVATE:
   void
-  onValidatedFaceRequest(const shared_ptr<const Interest>& request);
+  disableLocalControl(const Name& topPrefix, const Interest& interest,
+                      const ControlParameters& parameters,
+                      const ndn::mgmt::CommandContinuation& done);
 
-  VIRTUAL_WITH_TESTS void
-  createFace(const Interest& request,
-             ControlParameters& parameters);
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers for ControlCommand
+  void
+  afterCreateFaceSuccess(ControlParameters& parameters,
+                         const shared_ptr<Face>& newFace,
+                         const ndn::mgmt::CommandContinuation& done);
 
-  VIRTUAL_WITH_TESTS void
-  destroyFace(const Interest& request,
-              ControlParameters& parameters);
+  void
+  afterCreateFaceFailure(const std::string& reason,
+                         const ndn::mgmt::CommandContinuation& done);
 
-  VIRTUAL_WITH_TESTS bool
+  struct ExtractLocalControlParametersResult
+  {
+    bool isValid;
+    shared_ptr<LocalFace> face;
+    LocalControlFeature feature;
+  };
+
+  ExtractLocalControlParametersResult
   extractLocalControlParameters(const Interest& request,
-                                ControlParameters& parameters,
-                                ControlCommand& command,
-                                shared_ptr<LocalFace>& outFace,
-                                LocalControlFeature& outFeature);
+                                const ControlParameters& parameters,
+                                const ndn::mgmt::CommandContinuation& done);
 
-  VIRTUAL_WITH_TESTS void
-  enableLocalControl(const Interest& request,
-                     ControlParameters& parambeters);
-
-  VIRTUAL_WITH_TESTS void
-  disableLocalControl(const Interest& request,
-                      ControlParameters& parameters);
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // StatusDataset
+  void
+  listFaces(const Name& topPrefix, const Interest& interest,
+            ndn::mgmt::StatusDatasetContext& context);
 
   void
-  ignoreUnsignedVerb(const Interest& request);
+  listChannels(const Name& topPrefix, const Interest& interest,
+               ndn::mgmt::StatusDatasetContext& context);
 
   void
-  addCreatedFaceToForwarder(const shared_ptr<Face>& newFace);
+  queryFaces(const Name& topPrefix, const Interest& interest,
+             ndn::mgmt::StatusDatasetContext& context);
+
+private: // helpers for StatusDataset handler
+  bool
+  doesMatchFilter(const ndn::nfd::FaceQueryFilter& filter, shared_ptr<Face> face);
+
+private: // NotificationStream
+  void
+  afterFaceAdded(shared_ptr<Face> face,
+                 const ndn::mgmt::PostNotification& post);
 
   void
-  onCreated(const Name& requestName,
-            ControlParameters& parameters,
-            const shared_ptr<Face>& newFace);
+  afterFaceRemoved(shared_ptr<Face> face,
+                   const ndn::mgmt::PostNotification& post);
 
+private: // configuration
   void
-  onConnectFailed(const Name& requestName, const std::string& reason);
-
-  void
-  onAddFace(shared_ptr<Face> face);
-
-  void
-  onRemoveFace(shared_ptr<Face> face);
-
-private:
-  void
-  onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
+  processConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
 
   void
   processSectionUnix(const ConfigSection& configSection, bool isDryRun);
@@ -158,14 +145,9 @@
   void
   processSectionWebSocket(const ConfigSection& configSection, bool isDryRun);
 
-  /** \brief parse a config option that can be either "yes" or "no"
-   *  \throw ConfigFile::Error value is neither "yes" nor "no"
-   *  \return true if "yes", false if "no"
-   */
-  bool
-  parseYesNo(const ConfigSection::const_iterator& i,
-             const std::string& optionName,
-             const std::string& sectionName);
+private: // helpers for configuration
+  void
+  addCreatedFaceToForwarder(shared_ptr<Face> newFace);
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   typedef std::map<std::string/*protocol*/, shared_ptr<ProtocolFactory>> FactoryMap;
@@ -175,76 +157,8 @@
   FaceTable& m_faceTable;
   signal::ScopedConnection m_faceAddConn;
   signal::ScopedConnection m_faceRemoveConn;
-  FaceStatusPublisher m_faceStatusPublisher;
-  ChannelStatusPublisher m_channelStatusPublisher;
-  NotificationStream<AppFace> m_notificationStream;
-
-  typedef function<void(FaceManager*,
-                        const Interest&,
-                        ControlParameters&)> SignedVerbProcessor;
-
-  typedef std::map<Name::Component, SignedVerbProcessor> SignedVerbDispatchTable;
-  typedef std::pair<Name::Component, SignedVerbProcessor> SignedVerbAndProcessor;
-
-  typedef function<void(FaceManager*, const Interest&)> UnsignedVerbProcessor;
-
-  typedef std::map<Name::Component, UnsignedVerbProcessor> UnsignedVerbDispatchTable;
-  typedef std::pair<Name::Component, UnsignedVerbProcessor> UnsignedVerbAndProcessor;
-
-  const SignedVerbDispatchTable m_signedVerbDispatch;
-  const UnsignedVerbDispatchTable m_unsignedVerbDispatch;
-
-  static const Name COMMAND_PREFIX; // /localhost/nfd/faces
-
-  // number of components in an invalid signed command (i.e. should be signed, but isn't)
-  // (/localhost/nfd/faces + verb + parameters) = 5
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed command.
-  // (see UNSIGNED_NCOMPS), 9 with signed Interest support.
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const SignedVerbAndProcessor SIGNED_COMMAND_VERBS[];
-  static const UnsignedVerbAndProcessor UNSIGNED_COMMAND_VERBS[];
-
-  static const Name FACES_LIST_DATASET_PREFIX;
-  static const size_t FACES_LIST_DATASET_NCOMPS;
-
-  static const Name CHANNELS_LIST_DATASET_PREFIX;
-  static const size_t CHANNELS_LIST_DATASET_NCOMPS;
-
-  static const Name FACES_QUERY_DATASET_PREFIX;
-  static const size_t FACES_QUERY_DATASET_NCOMPS;
-
-  static const Name FACE_EVENTS_PREFIX;
 };
 
-inline bool
-FaceManager::parseYesNo(const ConfigSection::const_iterator& i,
-                        const std::string& optionName,
-                        const std::string& sectionName)
-{
-  const std::string value = i->second.get_value<std::string>();
-  if (value == "yes")
-    {
-      return true;
-    }
-  else if (value == "no")
-    {
-      return false;
-    }
-
-   BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                           optionName + "\" in \"" +
-                                           sectionName + "\" section"));
-}
-
-inline void
-FaceManager::ignoreUnsignedVerb(const Interest& request)
-{
-  // do nothing
-}
-
 } // namespace nfd
 
 #endif // NFD_DAEMON_MGMT_FACE_MANAGER_HPP
diff --git a/daemon/mgmt/face-query-status-publisher.cpp b/daemon/mgmt/face-query-status-publisher.cpp
deleted file mode 100644
index e60b949..0000000
--- a/daemon/mgmt/face-query-status-publisher.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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-query-status-publisher.hpp"
-
-#include <boost/range/adaptor/reversed.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
-namespace nfd {
-
-FaceQueryStatusPublisher::FaceQueryStatusPublisher(const FaceTable& faceTable,
-                                                   AppFace& face,
-                                                   const Name& prefix,
-                                                   const ndn::nfd::FaceQueryFilter& filter,
-                                                   ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_faceTable(faceTable)
-  , m_faceFilter(filter)
-{
-}
-
-FaceQueryStatusPublisher::~FaceQueryStatusPublisher()
-{
-}
-
-bool
-FaceQueryStatusPublisher::doesMatchFilter(const shared_ptr<Face>& face)
-{
-  if (m_faceFilter.hasFaceId() &&
-      m_faceFilter.getFaceId() != static_cast<uint64_t>(face->getId())) {
-    return false;
-  }
-
-  if (m_faceFilter.hasUriScheme() &&
-      (m_faceFilter.getUriScheme() != face->getRemoteUri().getScheme() ||
-       m_faceFilter.getUriScheme() != face->getLocalUri().getScheme())) {
-    return false;
-  }
-
-  if (m_faceFilter.hasRemoteUri() &&
-      m_faceFilter.getRemoteUri() != face->getRemoteUri().toString()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasLocalUri() && m_faceFilter.getLocalUri() != face->getLocalUri().toString()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasFaceScope() &&
-      (m_faceFilter.getFaceScope() == ndn::nfd::FACE_SCOPE_LOCAL) != face->isLocal()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasFacePersistency() &&
-      m_faceFilter.getFacePersistency() != face->getPersistency()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasLinkType() &&
-      (m_faceFilter.getLinkType() == ndn::nfd::LINK_TYPE_MULTI_ACCESS) != face->isMultiAccess()) {
-    return false;
-  }
-
-  return true;
-}
-
-size_t
-FaceQueryStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  for (const shared_ptr<Face>& face : m_faceTable | boost::adaptors::reversed) {
-    if (doesMatchFilter(face)) {
-      ndn::nfd::FaceStatus status = face->getFaceStatus();
-      totalLength += status.wireEncode(outBuffer);
-    }
-  }
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/face-query-status-publisher.hpp b/daemon/mgmt/face-query-status-publisher.hpp
deleted file mode 100644
index 237cecb..0000000
--- a/daemon/mgmt/face-query-status-publisher.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_DAEMON_MGMT_QUERIED_FACE_STATUS_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_QUERIED_FACE_STATUS_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-#include "fw/face-table.hpp"
-
-#include <ndn-cxx/management/nfd-face-query-filter.hpp>
-
-namespace nfd {
-
-class FaceQueryStatusPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  FaceQueryStatusPublisher(const FaceTable& faceTable,
-                           AppFace& face,
-                           const Name& prefix,
-                           const ndn::nfd::FaceQueryFilter& filter,
-                           ndn::KeyChain& keyChain);
-
-  virtual
-  ~FaceQueryStatusPublisher();
-
-  bool
-  doesMatchFilter(const shared_ptr<Face>& face);
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const FaceTable& m_faceTable;
-  const ndn::nfd::FaceQueryFilter& m_faceFilter;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_QUERIED_FACE_STATUS_PUBLISHER_HPP
diff --git a/daemon/mgmt/face-status-publisher.cpp b/daemon/mgmt/face-status-publisher.cpp
deleted file mode 100644
index ff061fa..0000000
--- a/daemon/mgmt/face-status-publisher.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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.hpp"
-#include "fw/face-table.hpp"
-
-#include <boost/range/adaptor/reversed.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
-namespace nfd {
-
-FaceStatusPublisher::FaceStatusPublisher(const FaceTable& faceTable,
-                                         AppFace& face,
-                                         const Name& prefix,
-                                         ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_faceTable(faceTable)
-{
-}
-
-FaceStatusPublisher::~FaceStatusPublisher()
-{
-}
-
-size_t
-FaceStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  for (const shared_ptr<Face>& face : m_faceTable | boost::adaptors::reversed) {
-    ndn::nfd::FaceStatus status = face->getFaceStatus();
-    totalLength += status.wireEncode(outBuffer);
-  }
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/face-status-publisher.hpp b/daemon/mgmt/face-status-publisher.hpp
deleted file mode 100644
index 5091165..0000000
--- a/daemon/mgmt/face-status-publisher.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_DAEMON_MGMT_FACE_STATUS_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_FACE_STATUS_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class FaceTable;
-
-class FaceStatusPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  FaceStatusPublisher(const FaceTable& faceTable,
-                      AppFace& face,
-                      const Name& prefix,
-                      ndn::KeyChain& keyChain);
-
-  virtual
-  ~FaceStatusPublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const FaceTable& m_faceTable;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_FACE_STATUS_PUBLISHER_HPP
diff --git a/daemon/mgmt/fib-enumeration-publisher.cpp b/daemon/mgmt/fib-enumeration-publisher.cpp
deleted file mode 100644
index 5123a58..0000000
--- a/daemon/mgmt/fib-enumeration-publisher.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- 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 "fib-enumeration-publisher.hpp"
-#include "core/logger.hpp"
-#include "table/fib.hpp"
-
-#include <ndn-cxx/management/nfd-fib-entry.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("FibEnumerationPublisher");
-
-FibEnumerationPublisher::FibEnumerationPublisher(const Fib& fib,
-                                                 AppFace& face,
-                                                 const Name& prefix,
-                                                 ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_fib(fib)
-{
-}
-
-FibEnumerationPublisher::~FibEnumerationPublisher()
-{
-}
-
-size_t
-FibEnumerationPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  /// \todo Enable use of Fib::const_reverse_iterator (when it is available)
-  for (Fib::const_iterator i = m_fib.begin(); i != m_fib.end(); ++i)
-    {
-      const fib::Entry& entry = *i;
-      const Name& prefix = entry.getPrefix();
-      size_t fibEntryLength = 0;
-
-      ndn::nfd::FibEntry tlvEntry;
-      const fib::NextHopList& nextHops = entry.getNextHops();
-
-      for (fib::NextHopList::const_iterator j = nextHops.begin();
-           j != nextHops.end();
-           ++j)
-        {
-          const fib::NextHop& next = *j;
-          ndn::nfd::NextHopRecord nextHopRecord;
-          nextHopRecord.setFaceId(next.getFace()->getId());
-          nextHopRecord.setCost(next.getCost());
-
-          tlvEntry.addNextHopRecord(nextHopRecord);
-        }
-
-      tlvEntry.setPrefix(prefix);
-      fibEntryLength += tlvEntry.wireEncode(outBuffer);
-
-      NFD_LOG_DEBUG("generate: fib entry length = " << fibEntryLength);
-
-      totalLength += fibEntryLength;
-    }
-
-  NFD_LOG_DEBUG("generate: Total length = " << totalLength);
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/fib-enumeration-publisher.hpp b/daemon/mgmt/fib-enumeration-publisher.hpp
deleted file mode 100644
index 2ff5c31..0000000
--- a/daemon/mgmt/fib-enumeration-publisher.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_DAEMON_MGMT_FIB_ENUMERATION_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_FIB_ENUMERATION_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class Fib;
-
-class FibEnumerationPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  FibEnumerationPublisher(const Fib& fib,
-                          AppFace& face,
-                          const Name& prefix,
-                          ndn::KeyChain& keyChain);
-
-  virtual
-  ~FibEnumerationPublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const Fib& m_fib;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_FIB_ENUMERATION_PUBLISHER_HPP
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index 3db26e7..12374f1 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,171 +24,34 @@
  */
 
 #include "fib-manager.hpp"
-
-#include "core/logger.hpp"
-#include "table/fib.hpp"
-#include "fw/forwarder.hpp"
-#include "mgmt/internal-face.hpp"
-#include "mgmt/app-face.hpp"
-
-#include <ndn-cxx/encoding/tlv.hpp>
+#include <ndn-cxx/management/nfd-fib-entry.hpp>
 
 namespace nfd {
 
 NFD_LOG_INIT("FibManager");
 
-const Name FibManager::COMMAND_PREFIX = "/localhost/nfd/fib";
-
-const size_t FibManager::COMMAND_UNSIGNED_NCOMPS =
-  FibManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb parameters
-
-const size_t FibManager::COMMAND_SIGNED_NCOMPS =
-  FibManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const FibManager::SignedVerbAndProcessor FibManager::SIGNED_COMMAND_VERBS[] =
-  {
-
-    SignedVerbAndProcessor(
-                           Name::Component("add-nexthop"),
-                           &FibManager::addNextHop
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("remove-nexthop"),
-                           &FibManager::removeNextHop
-                           ),
-
-  };
-
-const FibManager::UnsignedVerbAndProcessor FibManager::UNSIGNED_COMMAND_VERBS[] =
-  {
-    UnsignedVerbAndProcessor(
-                             Name::Component("list"),
-                             &FibManager::listEntries
-                             ),
-  };
-
-const Name FibManager::LIST_COMMAND_PREFIX("/localhost/nfd/fib/list");
-const size_t FibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
-
-
 FibManager::FibManager(Fib& fib,
                        function<shared_ptr<Face>(FaceId)> getFace,
-                       shared_ptr<InternalFace> face,
-                       ndn::KeyChain& keyChain)
-  : ManagerBase(face, FIB_PRIVILEGE, keyChain)
-  , m_managedFib(fib)
+                       Dispatcher& dispatcher,
+                       CommandValidator& validator)
+  : ManagerBase(dispatcher, validator, "fib")
+  , m_fib(fib)
   , m_getFace(getFace)
-  , m_fibEnumerationPublisher(fib, *face, LIST_COMMAND_PREFIX, keyChain)
-  , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
-                         SIGNED_COMMAND_VERBS +
-                         (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
-  , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
-                           UNSIGNED_COMMAND_VERBS +
-                           (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
 {
-  face->setInterestFilter("/localhost/nfd/fib",
-                          bind(&FibManager::onFibRequest, this, _2));
-}
+  registerCommandHandler<ndn::nfd::FibAddNextHopCommand>("add-nexthop",
+    bind(&FibManager::addNextHop, this, _2, _3, _4, _5));
+  registerCommandHandler<ndn::nfd::FibRemoveNextHopCommand>("remove-nexthop",
+    bind(&FibManager::removeNextHop, this, _2, _3, _4, _5));
 
-FibManager::~FibManager()
-{
-
+  registerStatusDatasetHandler("list", bind(&FibManager::listEntries, this, _1, _2, _3));
 }
 
 void
-FibManager::onFibRequest(const Interest& request)
+FibManager::addNextHop(const Name& topPrefix, const Interest& interest,
+                       ControlParameters parameters,
+                       const ndn::mgmt::CommandContinuation& done)
 {
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps <= COMMAND_PREFIX.size())
-    {
-      // command is too short to have a verb
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
-
-  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
-  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
-    {
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      (unsignedVerbProcessor->second)(this, request);
-    }
-  else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
-           commandNComps < COMMAND_SIGNED_NCOMPS)
-    {
-      NFD_LOG_DEBUG("command result: unsigned verb: " << command);
-      sendResponse(command, 401, "Signature required");
-    }
-  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
-           !COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-    }
-  else
-    {
-      validate(request,
-               bind(&FibManager::onValidatedFibRequest, this, _1),
-               bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
-    }
-}
-
-void
-FibManager::onValidatedFibRequest(const shared_ptr<const Interest>& request)
-{
-  const Name& command = request->getName();
-  const Name::Component& verb = command[COMMAND_PREFIX.size()];
-  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
-  SignedVerbDispatchTable::const_iterator verbProcessor = m_signedVerbDispatch.find(verb);
-  if (verbProcessor != m_signedVerbDispatch.end())
-    {
-      ControlParameters parameters;
-      if (!extractParameters(parameterComponent, parameters))
-        {
-          NFD_LOG_DEBUG("command result: malformed verb: " << verb);
-          sendResponse(command, 400, "Malformed command");
-          return;
-        }
-
-      bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
-      if (isSelfRegistration)
-        {
-          parameters.setFaceId(request->getIncomingFaceId());
-        }
-
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      ControlResponse response;
-      (verbProcessor->second)(this, parameters, response);
-      sendResponse(command, response);
-    }
-  else
-    {
-      NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
-      sendResponse(command, 501, "Unsupported command");
-    }
-}
-
-void
-FibManager::addNextHop(ControlParameters& parameters,
-                       ControlResponse& response)
-{
-  ndn::nfd::FibAddNextHopCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("add-nexthop result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
+  setFaceForSelfRegistration(interest, parameters);
 
   const Name& prefix = parameters.getName();
   FaceId faceId = parameters.getFaceId();
@@ -198,87 +61,89 @@
                 << " faceid: " << faceId
                 << " cost: " << cost);
 
-  shared_ptr<Face> nextHopFace = m_getFace(faceId);
-  if (static_cast<bool>(nextHopFace))
-    {
-      shared_ptr<fib::Entry> entry = m_managedFib.insert(prefix).first;
+  auto face = m_getFace(faceId);
+  if (static_cast<bool>(face)) {
+    auto entry = m_fib.insert(prefix).first;
 
-      entry->addNextHop(nextHopFace, cost);
+    entry->addNextHop(face, cost);
 
-      NFD_LOG_DEBUG("add-nexthop result: OK"
-                    << " prefix:" << prefix
-                    << " faceid: " << faceId
-                    << " cost: " << cost);
+    NFD_LOG_DEBUG("add-nexthop result: OK"
+                  << " prefix:" << prefix
+                  << " faceid: " << faceId
+                  << " cost: " << cost);
 
-      setResponse(response, 200, "Success", parameters.wireEncode());
-    }
-  else
-    {
-      NFD_LOG_DEBUG("add-nexthop result: FAIL reason: unknown-faceid: " << faceId);
-      setResponse(response, 410, "Face not found");
-    }
+    return done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
+  }
+  else {
+    NFD_LOG_INFO("add-nexthop result: FAIL reason: unknown-faceid: " << faceId);
+    return done(ControlResponse(410, "Face not found"));
+  }
 }
 
 void
-FibManager::removeNextHop(ControlParameters& parameters,
-                          ControlResponse& response)
+FibManager::removeNextHop(const Name& topPrefix, const Interest& interest,
+                          ControlParameters parameters,
+                          const ndn::mgmt::CommandContinuation& done)
 {
-  ndn::nfd::FibRemoveNextHopCommand command;
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("remove-nexthop result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
+  setFaceForSelfRegistration(interest, parameters);
 
   NFD_LOG_TRACE("remove-nexthop prefix: " << parameters.getName()
                 << " faceid: " << parameters.getFaceId());
 
-  shared_ptr<Face> faceToRemove = m_getFace(parameters.getFaceId());
-  if (static_cast<bool>(faceToRemove))
-    {
-      shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(parameters.getName());
-      if (static_cast<bool>(entry))
-        {
-          entry->removeNextHop(faceToRemove);
-          NFD_LOG_DEBUG("remove-nexthop result: OK prefix: " << parameters.getName()
-                        << " faceid: " << parameters.getFaceId());
+  auto face = m_getFace(parameters.getFaceId());
+  if (static_cast<bool>(face)) {
+    auto entry = m_fib.findExactMatch(parameters.getName());
+    if (static_cast<bool>(entry)) {
+      entry->removeNextHop(face);
+      NFD_LOG_DEBUG("remove-nexthop result: OK prefix: " << parameters.getName()
+                    << " faceid: " << parameters.getFaceId());
 
-          if (!entry->hasNextHops())
-            {
-              m_managedFib.erase(*entry);
-            }
-        }
-      else
-        {
-          NFD_LOG_DEBUG("remove-nexthop result: OK, but entry for face id "
-                        << parameters.getFaceId() << " not found");
-        }
+      if (!entry->hasNextHops()) {
+        m_fib.erase(*entry);
+      }
     }
-  else
-    {
-      NFD_LOG_DEBUG("remove-nexthop result: OK, but face id "
-                    << parameters.getFaceId() << " not found");
+    else {
+      NFD_LOG_DEBUG("remove-nexthop result: OK");
     }
+  }
+  else {
+    NFD_LOG_DEBUG("remove-nexthop result: OK");
+  }
 
-  setResponse(response, 200, "Success", parameters.wireEncode());
+  done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
 }
 
 void
-FibManager::listEntries(const Interest& request)
+FibManager::listEntries(const Name& topPrefix, const Interest& interest,
+                        ndn::mgmt::StatusDatasetContext& context)
 {
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
+  for (auto&& entry : m_fib) {
+    auto prefix = entry.getPrefix();
+    ndn::nfd::FibEntry record;
+    const auto& nextHops = entry.getNextHops();
 
-  if (commandNComps < LIST_COMMAND_NCOMPS ||
-      !LIST_COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
+    for (auto&& next : nextHops) {
+      ndn::nfd::NextHopRecord nextHopRecord;
+      nextHopRecord.setFaceId(next.getFace()->getId());
+      nextHopRecord.setCost(next.getCost());
+
+      record.addNextHopRecord(nextHopRecord);
     }
 
-  m_fibEnumerationPublisher.publish();
+    record.setPrefix(prefix);
+    context.append(record.wireEncode());
+  }
+
+  context.end();
 }
 
-} // namespace nfd
+void
+FibManager::setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters)
+{
+  bool isSelfRegistration = (parameters.getFaceId() == 0);
+  if (isSelfRegistration) {
+    parameters.setFaceId(request.getIncomingFaceId());
+  }
+}
+
+} // namespace
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
index c8c21ea..7c66138 100644
--- a/daemon/mgmt/fib-manager.hpp
+++ b/daemon/mgmt/fib-manager.hpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -26,87 +26,55 @@
 #ifndef NFD_DAEMON_MGMT_FIB_MANAGER_HPP
 #define NFD_DAEMON_MGMT_FIB_MANAGER_HPP
 
-#include "common.hpp"
-#include "mgmt/manager-base.hpp"
-#include "mgmt/fib-enumeration-publisher.hpp"
+#include "manager-base.hpp"
+#include "core/logger.hpp"
+#include "table/fib.hpp"
+#include "fw/forwarder.hpp"
 
 namespace nfd {
 
-class Face;
-class Forwarder;
-class Fib;
-
-const std::string FIB_PRIVILEGE = "fib"; // config file privilege name
-
+/**
+ * @brief implement the FIB Management of NFD Management Protocol.
+ * @sa http://redmine.named-data.net/projects/nfd/wiki/FibMgmt
+ */
 class FibManager : public ManagerBase
 {
 public:
-
+  /**
+   * @brief construct a FibManger
+   *
+   * @param fib the managed FIB
+   * @param getFace a function used to retrive a face by FaceId from the face table
+   * @param dispatcher the management dispatcher
+   * @param validator the command validator
+   */
   FibManager(Fib& fib,
              function<shared_ptr<Face>(FaceId)> getFace,
-             shared_ptr<InternalFace> face,
-             ndn::KeyChain& keyChain);
-
-  virtual
-  ~FibManager();
-
-  void
-  onFibRequest(const Interest& request);
+             Dispatcher& dispatcher,
+             CommandValidator& validator);
 
 private:
+  void
+  addNextHop(const Name& topPrefix, const Interest& interest,
+             ControlParameters parameters,
+             const ndn::mgmt::CommandContinuation& done);
 
   void
-  onValidatedFibRequest(const shared_ptr<const Interest>& request);
+  removeNextHop(const Name& topPrefix, const Interest& interest,
+                ControlParameters parameters,
+                const ndn::mgmt::CommandContinuation& done);
 
   void
-  addNextHop(ControlParameters& parameters,
-             ControlResponse& response);
-
-  void
-  removeNextHop(ControlParameters& parameters,
-                ControlResponse& response);
-
-  void
-  listEntries(const Interest& request);
+  listEntries(const Name& topPrefix, const Interest& interest,
+              ndn::mgmt::StatusDatasetContext& context);
 
 private:
+  void
+  setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
 
-  Fib& m_managedFib;
+private:
+  Fib& m_fib;
   function<shared_ptr<Face>(FaceId)> m_getFace;
-  FibEnumerationPublisher m_fibEnumerationPublisher;
-
-  typedef function<void(FibManager*,
-                        ControlParameters&,
-                        ControlResponse&)> SignedVerbProcessor;
-
-  typedef std::map<Name::Component, SignedVerbProcessor> SignedVerbDispatchTable;
-
-  typedef std::pair<Name::Component, SignedVerbProcessor> SignedVerbAndProcessor;
-
-  typedef function<void(FibManager*, const Interest&)> UnsignedVerbProcessor;
-
-  typedef std::map<Name::Component, UnsignedVerbProcessor> UnsignedVerbDispatchTable;
-  typedef std::pair<Name::Component, UnsignedVerbProcessor> UnsignedVerbAndProcessor;
-
-
-  const SignedVerbDispatchTable m_signedVerbDispatch;
-  const UnsignedVerbDispatchTable m_unsignedVerbDispatch;
-
-  static const Name COMMAND_PREFIX; // /localhost/nfd/fib
-
-  // number of components in an invalid, but not malformed, unsigned command.
-  // (/localhost/nfd/fib + verb + parameters) = 5
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed Interest.
-  // UNSIGNED_NCOMPS + 4 command Interest components = 9
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const SignedVerbAndProcessor SIGNED_COMMAND_VERBS[];
-  static const UnsignedVerbAndProcessor UNSIGNED_COMMAND_VERBS[];
-
-  static const Name LIST_COMMAND_PREFIX;
-  static const size_t LIST_COMMAND_NCOMPS;
 };
 
 } // namespace nfd
diff --git a/daemon/mgmt/forwarder-status-manager.cpp b/daemon/mgmt/forwarder-status-manager.cpp
new file mode 100644
index 0000000..bf2372b
--- /dev/null
+++ b/daemon/mgmt/forwarder-status-manager.cpp
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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 "forwarder-status-manager.hpp"
+#include "fw/forwarder.hpp"
+#include "version.hpp"
+
+namespace nfd {
+
+const time::milliseconds STATUS_SERVER_DEFAULT_FRESHNESS = time::milliseconds(5000);
+
+ForwarderStatusManager::ForwarderStatusManager(Forwarder& forwarder, Dispatcher& dispatcher)
+  : m_forwarder(forwarder)
+  , m_dispatcher(dispatcher)
+  , m_startTimestamp(time::system_clock::now())
+{
+  m_dispatcher.addStatusDataset("status", ndn::mgmt::makeAcceptAllAuthorization(),
+                                bind(&ForwarderStatusManager::listStatus, this, _1, _2, _3));
+}
+
+void
+ForwarderStatusManager::listStatus(const Name& topPrefix, const Interest& interest,
+                                   ndn::mgmt::StatusDatasetContext& context)
+{
+  ndn::nfd::ForwarderStatus status;
+
+  status.setNfdVersion(NFD_VERSION_BUILD_STRING);
+  status.setStartTimestamp(m_startTimestamp);
+  status.setCurrentTimestamp(time::system_clock::now());
+
+  status.setNNameTreeEntries(m_forwarder.getNameTree().size());
+  status.setNFibEntries(m_forwarder.getFib().size());
+  status.setNPitEntries(m_forwarder.getPit().size());
+  status.setNMeasurementsEntries(m_forwarder.getMeasurements().size());
+  status.setNCsEntries(m_forwarder.getCs().size());
+
+  m_forwarder.getCounters().copyTo(status);
+
+  context.setExpiry(STATUS_SERVER_DEFAULT_FRESHNESS);
+
+  status.wireEncode().parse();
+  for (const auto& subblock : status.wireEncode().elements()) {
+    context.append(subblock);
+  }
+  context.end();
+}
+
+} // namespace nfd
diff --git a/daemon/mgmt/forwarder-status-manager.hpp b/daemon/mgmt/forwarder-status-manager.hpp
new file mode 100644
index 0000000..57d89c8
--- /dev/null
+++ b/daemon/mgmt/forwarder-status-manager.hpp
@@ -0,0 +1,58 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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_DAEMON_MGMT_FORWARDER_STATUS_MANAGER_HPP
+#define NFD_DAEMON_MGMT_FORWARDER_STATUS_MANAGER_HPP
+
+#include "manager-base.hpp"
+#include <ndn-cxx/management/nfd-forwarder-status.hpp>
+
+namespace nfd {
+
+class Forwarder;
+
+/**
+ * @brief implement the Forwarder Status of NFD Management Protocol.
+ * @sa http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus
+ */
+class ForwarderStatusManager : noncopyable
+{
+public:
+  ForwarderStatusManager(Forwarder& forwarder, Dispatcher& dispatcher);
+
+private:
+  void
+  listStatus(const Name& topPrefix, const Interest& interest,
+             ndn::mgmt::StatusDatasetContext& context);
+
+private:
+  Forwarder&  m_forwarder;
+  Dispatcher& m_dispatcher;
+  time::system_clock::TimePoint m_startTimestamp;
+};
+
+} // namespace nfd
+
+#endif // NFD_DAEMON_MGMT_FORWARDER_STATUS_MANAGER_HPP
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
deleted file mode 100644
index 7569fb9..0000000
--- a/daemon/mgmt/internal-face.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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 "internal-face.hpp"
-#include "core/logger.hpp"
-#include "core/global-io.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("InternalFace");
-
-InternalFace::InternalFace()
-  : Face(FaceUri("internal://"), FaceUri("internal://"), true)
-{
-}
-
-void
-InternalFace::sendInterest(const Interest& interest)
-{
-  this->emitSignal(onSendInterest, interest);
-
-  // Invoke .processInterest a bit later,
-  // to avoid potential problems in forwarding pipelines.
-  getGlobalIoService().post(bind(&InternalFace::processInterest,
-                                 this, interest.shared_from_this()));
-}
-
-void
-InternalFace::processInterest(const shared_ptr<const Interest>& interest)
-{
-  if (m_interestFilters.size() == 0)
-    {
-      NFD_LOG_DEBUG("no Interest filters to match against");
-      return;
-    }
-
-  const Name& interestName(interest->getName());
-  NFD_LOG_DEBUG("received Interest: " << interestName);
-
-  std::map<Name, OnInterest>::const_iterator filter =
-    m_interestFilters.lower_bound(interestName);
-
-  // lower_bound gives us the first Name that is
-  // an exact match OR ordered after interestName.
-  //
-  // If we reach the end of the map, then we need
-  // only check if the before-end element is a match.
-  //
-  // If we match an element, then the current
-  // position or the previous element are potential
-  // matches.
-  //
-  // If we hit begin, the element is either an exact
-  // match or there is no matching prefix in the map.
-
-
-  if (filter == m_interestFilters.end() && filter != m_interestFilters.begin())
-    {
-      // We hit the end, check if the previous element
-      // is a match
-      --filter;
-      if (filter->first.isPrefixOf(interestName))
-        {
-          NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (before end match)");
-          filter->second(interestName, *interest);
-        }
-      else
-        {
-          NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (before end)");
-        }
-    }
-  else if (filter->first == interestName)
-    {
-      NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (exact match)");
-      filter->second(interestName, *interest);
-    }
-  else if (filter != m_interestFilters.begin())
-    {
-      // the element we found is canonically
-      // ordered after interestName.
-      // Check the previous element.
-      --filter;
-      if (filter->first.isPrefixOf(interestName))
-        {
-          NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (previous match)");
-          filter->second(interestName, *interest);
-        }
-      else
-        {
-          NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (previous)");
-        }
-    }
-  else
-    {
-      NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (begin)");
-    }
-  //Drop Interest
-}
-
-void
-InternalFace::sendData(const Data& data)
-{
-  this->emitSignal(onSendData, data);
-}
-
-void
-InternalFace::close()
-{
-  BOOST_THROW_EXCEPTION(Error("Internal face cannot be closed"));
-}
-
-void
-InternalFace::setInterestFilter(const Name& filter,
-                                OnInterest onInterest)
-{
-  NFD_LOG_INFO("registering callback for " << filter);
-  m_interestFilters[filter] = onInterest;
-}
-
-void
-InternalFace::put(const Data& data)
-{
-  this->emitSignal(onReceiveData, data);
-}
-
-InternalFace::~InternalFace()
-{
-
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/internal-face.hpp b/daemon/mgmt/internal-face.hpp
deleted file mode 100644
index c35676f..0000000
--- a/daemon/mgmt/internal-face.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_DAEMON_MGMT_INTERNAL_FACE_HPP
-#define NFD_DAEMON_MGMT_INTERNAL_FACE_HPP
-
-#include "face/face.hpp"
-#include "app-face.hpp"
-
-#include "command-validator.hpp"
-
-namespace nfd {
-
-class InternalFace : public Face, public AppFace
-{
-public:
-  /**
-   * \brief InternalFace-related error
-   */
-  class Error : public Face::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : Face::Error(what)
-    {
-    }
-  };
-
-  InternalFace();
-
-  CommandValidator&
-  getValidator();
-
-  virtual
-  ~InternalFace();
-
-  // Overridden Face methods for forwarder
-
-  virtual void
-  sendInterest(const Interest& interest);
-
-  virtual void
-  sendData(const Data& data);
-
-  virtual void
-  close();
-
-  // Methods implementing AppFace interface. Do not invoke from forwarder.
-
-  virtual void
-  setInterestFilter(const Name& filter,
-                    OnInterest onInterest);
-
-  virtual void
-  put(const Data& data);
-
-private:
-  void
-  processInterest(const shared_ptr<const Interest>& interest);
-
-private:
-  std::map<Name, OnInterest> m_interestFilters;
-  CommandValidator m_validator;
-};
-
-inline CommandValidator&
-InternalFace::getValidator()
-{
-  return m_validator;
-}
-
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_INTERNAL_FACE_HPP
diff --git a/daemon/mgmt/manager-base.cpp b/daemon/mgmt/manager-base.cpp
index cf75d04..418c3d6 100644
--- a/daemon/mgmt/manager-base.cpp
+++ b/daemon/mgmt/manager-base.cpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,120 +24,96 @@
  */
 
 #include "manager-base.hpp"
-#include "core/logger.hpp"
 
 namespace nfd {
 
-NFD_LOG_INIT("ManagerBase");
+using ndn::mgmt::ValidateParameters;
+using ndn::mgmt::Authorization;
 
-ManagerBase::ManagerBase(shared_ptr<InternalFace> face, const std::string& privilege,
-                         ndn::KeyChain& keyChain)
-  : m_face(face)
-  , m_keyChain(keyChain)
+ManagerBase::ManagerBase(Dispatcher& dispatcher,
+                         CommandValidator& validator,
+                         const std::string& module)
+  : m_dispatcher(dispatcher)
+  , m_validator(validator)
+  , m_mgmtModuleName(module)
 {
-  face->getValidator().addSupportedPrivilege(privilege);
+  m_validator.addSupportedPrivilege(module);
 }
 
-ManagerBase::~ManagerBase()
+void
+ManagerBase::registerStatusDatasetHandler(const std::string& verb,
+                                          const ndn::mgmt::StatusDatasetHandler& handler)
 {
+  m_dispatcher.addStatusDataset(makeRelPrefix(verb),
+                                ndn::mgmt::makeAcceptAllAuthorization(),
+                                handler);
+}
 
+ndn::mgmt::PostNotification
+ManagerBase::registerNotificationStream(const std::string& verb)
+{
+  return m_dispatcher.addNotificationStream(makeRelPrefix(verb));
+}
+
+void
+ManagerBase::authorize(const Name& prefix, const Interest& interest,
+                       const ndn::mgmt::ControlParameters* params,
+                       ndn::mgmt::AcceptContinuation accept,
+                       ndn::mgmt::RejectContinuation reject)
+{
+  BOOST_ASSERT(params != nullptr);
+  BOOST_ASSERT(typeid(*params) == typeid(ndn::nfd::ControlParameters));
+
+  m_validator.validate(interest,
+                       bind(&ManagerBase::extractRequester, this, interest, accept),
+                       bind([&] { reject(ndn::mgmt::RejectReply::STATUS403); }));
+}
+
+void
+ManagerBase::extractRequester(const Interest& interest,
+                              ndn::mgmt::AcceptContinuation accept)
+{
+  const Name& interestName = interest.getName();
+
+  try {
+    ndn::SignatureInfo sigInfo(interestName.at(ndn::signed_interest::POS_SIG_INFO).blockFromValue());
+    if (!sigInfo.hasKeyLocator() ||
+        sigInfo.getKeyLocator().getType() != ndn::KeyLocator::KeyLocator_Name) {
+      return accept("");
+    }
+
+    accept(sigInfo.getKeyLocator().getName().toUri());
+  }
+  catch (const tlv::Error&) {
+    accept("");
+  }
 }
 
 bool
-ManagerBase::extractParameters(const Name::Component& parameterComponent,
-                               ControlParameters& extractedParameters)
+ManagerBase::validateParameters(const nfd::ControlCommand& command, const ndn::mgmt::ControlParameters& parameters)
 {
-  try
-    {
-      Block rawParameters = parameterComponent.blockFromValue();
-      extractedParameters.wireDecode(rawParameters);
-    }
-  catch (const tlv::Error&)
-    {
-      return false;
-    }
+  BOOST_ASSERT(dynamic_cast<const ControlParameters*>(&parameters) != nullptr);
 
-  NFD_LOG_DEBUG("Parameters parsed OK");
+  try {
+    command.validateRequest(static_cast<const ControlParameters&>(parameters));
+  }
+  catch (const ControlCommand::ArgumentError&) {
+    return false;
+  }
   return true;
 }
 
 void
-ManagerBase::sendResponse(const Name& name,
-                          uint32_t code,
-                          const std::string& text)
+ManagerBase::handleCommand(shared_ptr<nfd::ControlCommand> command,
+                           const ControlCommandHandler& handler,
+                           const Name& prefix, const Interest& interest,
+                           const ndn::mgmt::ControlParameters& params,
+                           ndn::mgmt::CommandContinuation done)
 {
-  ControlResponse response(code, text);
-  sendResponse(name, response);
-}
-
-void
-ManagerBase::sendResponse(const Name& name,
-                          uint32_t code,
-                          const std::string& text,
-                          const Block& body)
-{
-  ControlResponse response(code, text);
-  response.setBody(body);
-  sendResponse(name, response);
-}
-
-void
-ManagerBase::sendResponse(const Name& name,
-                          const ControlResponse& response)
-{
-  NFD_LOG_DEBUG("responding"
-                << " name: " << name
-                << " code: " << response.getCode()
-                << " text: " << response.getText());
-
-  const Block& encodedControl = response.wireEncode();
-
-  shared_ptr<Data> responseData(make_shared<Data>(name));
-  responseData->setContent(encodedControl);
-
-  m_keyChain.sign(*responseData);
-  m_face->put(*responseData);
-}
-
-void
-ManagerBase::sendNack(const Name& name)
-{
-  NFD_LOG_DEBUG("responding NACK to " << name);
-
-  ndn::MetaInfo meta;
-  meta.setType(tlv::ContentType_Nack);
-
-  shared_ptr<Data> responseData(make_shared<Data>(name));
-  responseData->setMetaInfo(meta);
-
-  m_keyChain.sign(*responseData);
-  m_face->put(*responseData);
-}
-
-bool
-ManagerBase::validateParameters(const ControlCommand& command,
-                                ControlParameters& parameters)
-{
-  try
-    {
-      command.validateRequest(parameters);
-    }
-  catch (const ControlCommand::ArgumentError& error)
-    {
-      return false;
-    }
-
-  command.applyDefaultsToRequest(parameters);
-
-  return true;
-}
-
-void
-ManagerBase::onCommandValidationFailed(const shared_ptr<const Interest>& command,
-                                       const std::string& error)
-{
-  NFD_LOG_DEBUG("command result: unauthorized command: " << *command << " (" << error << ")");
-  sendResponse(command->getName(), 403, "Unauthorized command");
+  BOOST_ASSERT(dynamic_cast<const ControlParameters*>(&params) != nullptr);
+  ControlParameters parameters = static_cast<const ControlParameters&>(params);
+  command->applyDefaultsToRequest(parameters);
+  handler(*command, prefix, interest, parameters, done);
 }
 
 
diff --git a/daemon/mgmt/manager-base.hpp b/daemon/mgmt/manager-base.hpp
index 1611615..988fff1 100644
--- a/daemon/mgmt/manager-base.hpp
+++ b/daemon/mgmt/manager-base.hpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -27,143 +27,154 @@
 #define NFD_DAEMON_MGMT_MANAGER_BASE_HPP
 
 #include "common.hpp"
-
 #include "mgmt/command-validator.hpp"
-#include "mgmt/internal-face.hpp"
 
+#include <ndn-cxx/mgmt/dispatcher.hpp>
 #include <ndn-cxx/management/nfd-control-command.hpp>
 #include <ndn-cxx/management/nfd-control-response.hpp>
 #include <ndn-cxx/management/nfd-control-parameters.hpp>
 
 namespace nfd {
 
+using ndn::mgmt::Dispatcher;
+
 using ndn::nfd::ControlCommand;
 using ndn::nfd::ControlResponse;
 using ndn::nfd::ControlParameters;
 
-class InternalFace;
-
-class ManagerBase
+/**
+ * @brief a collection of common functions shared by all NFD managers,
+ *        such as communicating with the dispatcher and command validator.
+ */
+class ManagerBase : public noncopyable
 {
 public:
-
-  struct Error : public std::runtime_error
+  class Error : public std::runtime_error
   {
-    Error(const std::string& what) : std::runtime_error(what) {}
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
   };
 
-  ManagerBase(shared_ptr<InternalFace> face,
-              const std::string& privilege,
-              ndn::KeyChain& keyChain);
+public:
+  ManagerBase(Dispatcher& dispatcher,
+              CommandValidator& validator,
+              const std::string& module);
 
-  virtual
-  ~ManagerBase();
+PUBLIC_WITH_TESTS_ELSE_PROTECTED: // registrations to the dispatcher
+
+  // difference from mgmt::ControlCommand: accepts nfd::ControlParameters
+  typedef function<void(const ControlCommand& command,
+                        const Name& prefix, const Interest& interest,
+                        const ControlParameters& parameters,
+                        const ndn::mgmt::CommandContinuation done)> ControlCommandHandler;
+
+  template<typename Command>
+  void
+  registerCommandHandler(const std::string& verb,
+                         const ControlCommandHandler& handler);
 
   void
-  onCommandValidationFailed(const shared_ptr<const Interest>& command,
-                            const std::string& error);
+  registerStatusDatasetHandler(const std::string& verb,
+                               const ndn::mgmt::StatusDatasetHandler& handler);
 
-protected:
+  ndn::mgmt::PostNotification
+  registerNotificationStream(const std::string& verb);
 
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // command validation
+  /**
+   * @brief validate a request for ControlCommand.
+   *
+   * This is called by the dispatcher.
+   *
+   * @pre params != null
+   * @pre typeid(*params) == typeid(ndn::nfd::ControlParameters)
+   *
+   * @param prefix the top prefix
+   * @param interest a request for ControlCommand
+   * @param params the parameters for ControlCommand
+   * @param accept callback of successful validation, take the requester string as a argument
+   * @param reject callback of failure in validation, take the action code as a argument
+   */
+  void
+  authorize(const Name& prefix, const Interest& interest,
+            const ndn::mgmt::ControlParameters* params,
+            ndn::mgmt::AcceptContinuation accept,
+            ndn::mgmt::RejectContinuation reject);
+
+  /**
+   * @brief extract a requester from a ControlCommand request
+   *
+   * This is called after the signature is validated.
+   *
+   * @param interest a request for ControlCommand
+   * @param accept callback of successful validation, take the requester string as a argument
+   */
+  void
+  extractRequester(const Interest& interest,
+                   ndn::mgmt::AcceptContinuation accept);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers
+  /**
+   * @brief validate the @p parameters for a given @p command
+   *
+   * @param parameters the original ControlParameters
+   *
+   * @return whether the original ControlParameters can be validated
+   */
   static bool
-  extractParameters(const Name::Component& parameterComponent,
-                    ControlParameters& extractedParameters);
+  validateParameters(const nfd::ControlCommand& command,
+                     const ndn::mgmt::ControlParameters& parameters);
 
-  void
-  setResponse(ControlResponse& response,
-              uint32_t code,
-              const std::string& text);
-  void
-  setResponse(ControlResponse& response,
-              uint32_t code,
-              const std::string& text,
-              const Block& body);
+  /** @brief Handle control command
+   */
+  static void
+  handleCommand(shared_ptr<nfd::ControlCommand> command,
+                const ControlCommandHandler& handler,
+                const Name& prefix, const Interest& interest,
+                const ndn::mgmt::ControlParameters& params,
+                ndn::mgmt::CommandContinuation done);
 
-  void
-  sendResponse(const Name& name,
-               const ControlResponse& response);
+  /**
+   * @brief generate the relative prefix for a handler,
+   *        by appending the verb name to the module name.
+   *
+   * @param verb the verb name
+   *
+   * @return the generated relative prefix
+   */
+  PartialName
+  makeRelPrefix(const std::string& verb);
 
-  void
-  sendResponse(const Name& name,
-               uint32_t code,
-               const std::string& text);
-
-  void
-  sendResponse(const Name& name,
-               uint32_t code,
-               const std::string& text,
-               const Block& body);
-
-  void
-  sendNack(const Name& name);
-
-  virtual bool
-  validateParameters(const ControlCommand& command,
-                     ControlParameters& parameters);
-
-PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  void
-  addInterestRule(const std::string& regex,
-                  const ndn::IdentityCertificate& certificate);
-
-  void
-  addInterestRule(const std::string& regex,
-                  const Name& keyName,
-                  const ndn::PublicKey& publicKey);
-
-  void
-  validate(const Interest& interest,
-           const ndn::OnInterestValidated& onValidated,
-           const ndn::OnInterestValidationFailed& onValidationFailed);
-
-protected:
-  shared_ptr<InternalFace> m_face;
-  ndn::KeyChain& m_keyChain;
+private:
+  Dispatcher&       m_dispatcher;
+  CommandValidator& m_validator;
+  std::string       m_mgmtModuleName;
 };
 
-inline void
-ManagerBase::setResponse(ControlResponse& response,
-                         uint32_t code,
-                         const std::string& text)
+inline PartialName
+ManagerBase::makeRelPrefix(const std::string& verb)
 {
-  response.setCode(code);
-  response.setText(text);
+  return PartialName(m_mgmtModuleName).append(verb);
 }
 
+template<typename Command>
 inline void
-ManagerBase::setResponse(ControlResponse& response,
-                         uint32_t code,
-                         const std::string& text,
-                         const Block& body)
+ManagerBase::registerCommandHandler(const std::string& verb,
+                                    const ControlCommandHandler& handler)
 {
-  setResponse(response, code, text);
-  response.setBody(body);
-}
+  auto command = make_shared<Command>();
 
-inline void
-ManagerBase::addInterestRule(const std::string& regex,
-                             const ndn::IdentityCertificate& certificate)
-{
-  m_face->getValidator().addInterestRule(regex, certificate);
+  m_dispatcher.addControlCommand<ControlParameters>(
+    makeRelPrefix(verb),
+    bind(&ManagerBase::authorize, this, _1, _2, _3, _4, _5),
+    bind(&ManagerBase::validateParameters, cref(*command), _1),
+    bind(&ManagerBase::handleCommand, command, handler, _1, _2, _3, _4));
 }
 
-inline void
-ManagerBase::addInterestRule(const std::string& regex,
-                             const Name& keyName,
-                             const ndn::PublicKey& publicKey)
-{
-  m_face->getValidator().addInterestRule(regex, keyName, publicKey);
-}
-
-inline void
-ManagerBase::validate(const Interest& interest,
-                      const ndn::OnInterestValidated& onValidated,
-                      const ndn::OnInterestValidationFailed& onValidationFailed)
-{
-  m_face->getValidator().validate(interest, onValidated, onValidationFailed);
-}
-
-
 } // namespace nfd
 
 #endif // NFD_DAEMON_MGMT_MANAGER_BASE_HPP
diff --git a/daemon/mgmt/status-server.cpp b/daemon/mgmt/status-server.cpp
deleted file mode 100644
index c8ce5b4..0000000
--- a/daemon/mgmt/status-server.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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 "status-server.hpp"
-#include "fw/forwarder.hpp"
-#include "version.hpp"
-
-namespace nfd {
-
-const Name StatusServer::DATASET_PREFIX = "ndn:/localhost/nfd/status";
-const time::milliseconds StatusServer::RESPONSE_FRESHNESS = time::milliseconds(5000);
-
-StatusServer::StatusServer(shared_ptr<AppFace> face, Forwarder& forwarder, ndn::KeyChain& keyChain)
-  : m_face(face)
-  , m_forwarder(forwarder)
-  , m_startTimestamp(time::system_clock::now())
-  , m_keyChain(keyChain)
-{
-  m_face->setInterestFilter(DATASET_PREFIX, bind(&StatusServer::onInterest, this, _2));
-}
-
-void
-StatusServer::onInterest(const Interest& interest) const
-{
-  Name name(DATASET_PREFIX);
-  name.appendVersion();
-  name.appendSegment(0);
-
-  shared_ptr<Data> data = make_shared<Data>(name);
-  data->setFreshnessPeriod(RESPONSE_FRESHNESS);
-
-  shared_ptr<ndn::nfd::ForwarderStatus> status = this->collectStatus();
-  data->setContent(status->wireEncode());
-
-  m_keyChain.sign(*data);
-  m_face->put(*data);
-}
-
-shared_ptr<ndn::nfd::ForwarderStatus>
-StatusServer::collectStatus() const
-{
-  shared_ptr<ndn::nfd::ForwarderStatus> status = make_shared<ndn::nfd::ForwarderStatus>();
-
-  status->setNfdVersion(NFD_VERSION_BUILD_STRING);
-  status->setStartTimestamp(m_startTimestamp);
-  status->setCurrentTimestamp(time::system_clock::now());
-
-  status->setNNameTreeEntries(m_forwarder.getNameTree().size());
-  status->setNFibEntries(m_forwarder.getFib().size());
-  status->setNPitEntries(m_forwarder.getPit().size());
-  status->setNMeasurementsEntries(m_forwarder.getMeasurements().size());
-  status->setNCsEntries(m_forwarder.getCs().size());
-
-  m_forwarder.getCounters().copyTo(*status);
-
-  return status;
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/status-server.hpp b/daemon/mgmt/status-server.hpp
deleted file mode 100644
index 16dbf8e..0000000
--- a/daemon/mgmt/status-server.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_DAEMON_MGMT_STATUS_SERVER_HPP
-#define NFD_DAEMON_MGMT_STATUS_SERVER_HPP
-
-#include "mgmt/app-face.hpp"
-#include <ndn-cxx/management/nfd-forwarder-status.hpp>
-
-namespace nfd {
-
-class Forwarder;
-
-class StatusServer : noncopyable
-{
-public:
-  StatusServer(shared_ptr<AppFace> face, Forwarder& forwarder, ndn::KeyChain& keyChain);
-
-private:
-  void
-  onInterest(const Interest& interest) const;
-
-  shared_ptr<ndn::nfd::ForwarderStatus>
-  collectStatus() const;
-
-private:
-  static const Name DATASET_PREFIX;
-  static const time::milliseconds RESPONSE_FRESHNESS;
-
-  shared_ptr<AppFace> m_face;
-  Forwarder& m_forwarder;
-  time::system_clock::TimePoint m_startTimestamp;
-  ndn::KeyChain& m_keyChain;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_STATUS_SERVER_HPP
diff --git a/daemon/mgmt/strategy-choice-manager.cpp b/daemon/mgmt/strategy-choice-manager.cpp
index 4f2728c..fba7f4c 100644
--- a/daemon/mgmt/strategy-choice-manager.cpp
+++ b/daemon/mgmt/strategy-choice-manager.cpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -25,190 +25,75 @@
 
 #include "strategy-choice-manager.hpp"
 #include "table/strategy-choice.hpp"
-#include "core/logger.hpp"
-#include "mgmt/app-face.hpp"
+#include <ndn-cxx/management/nfd-strategy-choice.hpp>
 
 namespace nfd {
 
 NFD_LOG_INIT("StrategyChoiceManager");
 
-const Name StrategyChoiceManager::COMMAND_PREFIX = "/localhost/nfd/strategy-choice";
-
-const size_t StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS =
-  StrategyChoiceManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb parameters
-
-const size_t StrategyChoiceManager::COMMAND_SIGNED_NCOMPS =
-  StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const Name StrategyChoiceManager::LIST_DATASET_PREFIX("/localhost/nfd/strategy-choice/list");
-
 StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
-                                             shared_ptr<InternalFace> face,
-                                             ndn::KeyChain& keyChain)
-  : ManagerBase(face, STRATEGY_CHOICE_PRIVILEGE, keyChain)
+                                             Dispatcher& dispatcher,
+                                             CommandValidator& validator)
+  : ManagerBase(dispatcher, validator, "strategy-choice")
   , m_strategyChoice(strategyChoice)
-  , m_listPublisher(strategyChoice, *m_face, LIST_DATASET_PREFIX, keyChain)
 {
-  face->setInterestFilter("/localhost/nfd/strategy-choice",
-                          bind(&StrategyChoiceManager::onStrategyChoiceRequest, this, _2));
-}
+  registerCommandHandler<ndn::nfd::StrategyChoiceSetCommand>("set",
+    bind(&StrategyChoiceManager::setStrategy, this, _2, _3, _4, _5));
+  registerCommandHandler<ndn::nfd::StrategyChoiceUnsetCommand>("unset",
+    bind(&StrategyChoiceManager::unsetStrategy, this, _2, _3, _4, _5));
 
-StrategyChoiceManager::~StrategyChoiceManager()
-{
-
+  registerStatusDatasetHandler("list",
+    bind(&StrategyChoiceManager::listChoices, this, _1, _2, _3));
 }
 
 void
-StrategyChoiceManager::onStrategyChoiceRequest(const Interest& request)
+StrategyChoiceManager::setStrategy(const Name& topPrefix, const Interest& interest,
+                                   ControlParameters parameters,
+                                   const ndn::mgmt::CommandContinuation& done)
 {
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (command == LIST_DATASET_PREFIX)
-    {
-      listStrategies(request);
-      return;
-    }
-  else if (commandNComps <= COMMAND_PREFIX.size())
-    {
-      // command is too short to have a verb
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
-      commandNComps < COMMAND_SIGNED_NCOMPS)
-    {
-      NFD_LOG_DEBUG("command result: unsigned verb: " << command);
-      sendResponse(command, 401, "Signature required");
-
-      return;
-    }
-  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
-           !COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  validate(request,
-           bind(&StrategyChoiceManager::onValidatedStrategyChoiceRequest, this, _1),
-           bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
-}
-
-void
-StrategyChoiceManager::listStrategies(const Interest& request)
-{
-  m_listPublisher.publish();
-}
-
-void
-StrategyChoiceManager::onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request)
-{
-  static const Name::Component VERB_SET("set");
-  static const Name::Component VERB_UNSET("unset");
-
-  const Name& command = request->getName();
-  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
-  ControlParameters parameters;
-  if (!extractParameters(parameterComponent, parameters))
-    {
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
-  ControlResponse response;
-  if (verb == VERB_SET)
-    {
-      setStrategy(parameters, response);
-    }
-  else if (verb == VERB_UNSET)
-    {
-      unsetStrategy(parameters, response);
-    }
-  else
-    {
-      NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
-      setResponse(response, 501, "Unsupported command");
-    }
-
-  sendResponse(command, response);
-}
-
-void
-StrategyChoiceManager::setStrategy(ControlParameters& parameters,
-                                   ControlResponse& response)
-{
-  ndn::nfd::StrategyChoiceSetCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("strategy-choice result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
-
   const Name& prefix = parameters.getName();
   const Name& selectedStrategy = parameters.getStrategy();
 
-  if (!m_strategyChoice.hasStrategy(selectedStrategy))
-    {
-      NFD_LOG_DEBUG("strategy-choice result: FAIL reason: unknown-strategy: "
-                    << parameters.getStrategy());
-      setResponse(response, 504, "Unsupported strategy");
-      return;
-    }
+  if (!m_strategyChoice.hasStrategy(selectedStrategy)) {
+    NFD_LOG_DEBUG("strategy-choice result: FAIL reason: unknown-strategy: "
+                  << parameters.getStrategy());
+    return done(ControlResponse(504, "Unsupported strategy"));
+  }
 
-  if (m_strategyChoice.insert(prefix, selectedStrategy))
-    {
-      NFD_LOG_DEBUG("strategy-choice result: SUCCESS");
-      auto currentStrategyChoice = m_strategyChoice.get(prefix);
-      BOOST_ASSERT(currentStrategyChoice.first);
-      parameters.setStrategy(currentStrategyChoice.second);
-      setResponse(response, 200, "Success", parameters.wireEncode());
-    }
-  else
-    {
-      NFD_LOG_DEBUG("strategy-choice result: FAIL reason: not-installed");
-      setResponse(response, 405, "Strategy not installed");
-    }
+  if (m_strategyChoice.insert(prefix, selectedStrategy)) {
+    NFD_LOG_DEBUG("strategy-choice result: SUCCESS");
+    auto currentStrategyChoice = m_strategyChoice.get(prefix);
+    BOOST_ASSERT(currentStrategyChoice.first);
+    parameters.setStrategy(currentStrategyChoice.second);
+    return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+  }
+  else {
+    NFD_LOG_DEBUG("strategy-choice result: FAIL reason: not-installed");
+    return done(ControlResponse(405, "Strategy not installed"));
+  }
 }
 
 void
-StrategyChoiceManager::unsetStrategy(ControlParameters& parameters,
-                                     ControlResponse& response)
+StrategyChoiceManager::unsetStrategy(const Name& topPrefix, const Interest& interest,
+                                     ControlParameters parameters,
+                                     const ndn::mgmt::CommandContinuation& done)
 {
-  ndn::nfd::StrategyChoiceUnsetCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      static const Name ROOT_PREFIX;
-      if (parameters.hasName() && parameters.getName() == ROOT_PREFIX)
-        {
-          NFD_LOG_DEBUG("strategy-choice result: FAIL reason: unset-root");
-          setResponse(response, 403, "Cannot unset root prefix strategy");
-        }
-      else
-        {
-          NFD_LOG_DEBUG("strategy-choice result: FAIL reason: malformed");
-          setResponse(response, 400, "Malformed command");
-        }
-      return;
-    }
-
   m_strategyChoice.erase(parameters.getName());
 
   NFD_LOG_DEBUG("strategy-choice result: SUCCESS");
-  setResponse(response, 200, "Success", parameters.wireEncode());
+  done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
 }
 
+void
+StrategyChoiceManager::listChoices(const Name& topPrefix, const Interest& interest,
+                                   ndn::mgmt::StatusDatasetContext& context)
+{
+  for (auto&& i : m_strategyChoice) {
+    ndn::nfd::StrategyChoice entry;
+    entry.setName(i.getPrefix()).setStrategy(i.getStrategyName());
+    context.append(entry.wireEncode());
+  }
+  context.end();
+}
 
-
-} // namespace nfd
+} // namespace
diff --git a/daemon/mgmt/strategy-choice-manager.hpp b/daemon/mgmt/strategy-choice-manager.hpp
index c2ccd53..74c54db 100644
--- a/daemon/mgmt/strategy-choice-manager.hpp
+++ b/daemon/mgmt/strategy-choice-manager.hpp
@@ -1,12 +1,12 @@
 /* -*- 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,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -26,64 +26,40 @@
 #ifndef NFD_DAEMON_MGMT_STRATEGY_CHOICE_MANAGER_HPP
 #define NFD_DAEMON_MGMT_STRATEGY_CHOICE_MANAGER_HPP
 
-#include "mgmt/manager-base.hpp"
-#include "mgmt/strategy-choice-publisher.hpp"
-
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
+#include "manager-base.hpp"
 
 namespace nfd {
 
-const std::string STRATEGY_CHOICE_PRIVILEGE = "strategy-choice";
-
 class StrategyChoice;
 
+/**
+ * @brief implement the Strategy Choice Management of NFD Management Protocol.
+ * @sa http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice
+ */
 class StrategyChoiceManager : public ManagerBase
 {
 public:
   StrategyChoiceManager(StrategyChoice& strategyChoice,
-                        shared_ptr<InternalFace> face,
-                        ndn::KeyChain& keyChain);
-
-  virtual
-  ~StrategyChoiceManager();
-
-  void
-  onStrategyChoiceRequest(const Interest& request);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
-  void
-  listStrategies(const Interest& request);
-
-  void
-  onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request);
-
-  void
-  setStrategy(ControlParameters& parameters,
-              ControlResponse& response);
-
-  void
-  unsetStrategy(ControlParameters& parameters,
-                ControlResponse& response);
+                        Dispatcher& dispatcher,
+                        CommandValidator& validator);
 
 private:
+  void
+  setStrategy(const Name& topPrefix, const Interest& interest,
+              ControlParameters parameters,
+              const ndn::mgmt::CommandContinuation& done);
 
+  void
+  unsetStrategy(const Name& topPrefix, const Interest& interest,
+                ControlParameters parameters,
+                const ndn::mgmt::CommandContinuation& done);
+
+  void
+  listChoices(const Name& topPrefix, const Interest& interest,
+              ndn::mgmt::StatusDatasetContext& context);
+
+private:
   StrategyChoice& m_strategyChoice;
-
-  StrategyChoicePublisher m_listPublisher;
-
-  static const Name COMMAND_PREFIX; // /localhost/nfd/strategy-choice
-
-  // number of components in an invalid, but not malformed, unsigned command.
-  // (/localhost/nfd/strategy-choice + verb + parameters) = 5
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed Interest.
-  // (see UNSIGNED_NCOMPS), 9 with signed Interest support.
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const Name LIST_DATASET_PREFIX; // /localhost/nfd/strategy-choice/list
-
 };
 
 } // namespace nfd
diff --git a/daemon/mgmt/strategy-choice-publisher.cpp b/daemon/mgmt/strategy-choice-publisher.cpp
deleted file mode 100644
index 8db7124..0000000
--- a/daemon/mgmt/strategy-choice-publisher.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- 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,
- *                     The University of Memphis
- *
- * 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 "strategy-choice-publisher.hpp"
-#include "table/strategy-choice.hpp"
-
-#include <ndn-cxx/management/nfd-strategy-choice.hpp>
-
-namespace nfd {
-
-StrategyChoicePublisher::StrategyChoicePublisher(const StrategyChoice& strategyChoice,
-                                                 AppFace& face,
-                                                 const Name& prefix,
-                                                 ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_strategyChoice(strategyChoice)
-{
-}
-
-StrategyChoicePublisher::~StrategyChoicePublisher()
-{
-}
-
-size_t
-StrategyChoicePublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  for (StrategyChoice::const_iterator i = m_strategyChoice.begin();
-       i != m_strategyChoice.end();
-       ++i)
-    {
-      ndn::nfd::StrategyChoice entry;
-
-      entry.setName(i->getPrefix())
-           .setStrategy(i->getStrategyName());
-
-      totalLength += entry.wireEncode(outBuffer);
-    }
-
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/strategy-choice-publisher.hpp b/daemon/mgmt/strategy-choice-publisher.hpp
deleted file mode 100644
index 8322b63..0000000
--- a/daemon/mgmt/strategy-choice-publisher.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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,
- *                     The University of Memphis
- *
- * 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_DAEMON_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class StrategyChoice;
-
-class StrategyChoicePublisher : public SegmentPublisher<AppFace>
-{
-public:
-  StrategyChoicePublisher(const StrategyChoice& strategyChoice,
-                          AppFace& face,
-                          const Name& prefix,
-                          ndn::KeyChain& keyChain);
-
-  virtual
-  ~StrategyChoicePublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-
-  const StrategyChoice& m_strategyChoice;
-
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
diff --git a/daemon/nfd.cpp b/daemon/nfd.cpp
index 262bbf5..7d68de3 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -31,13 +31,17 @@
 #include "core/config-file.hpp"
 #include "fw/forwarder.hpp"
 #include "face/null-face.hpp"
-#include "mgmt/internal-face.hpp"
+#include "face/internal-face.hpp"
+#include "face/internal-client-face.hpp"
 #include "mgmt/fib-manager.hpp"
 #include "mgmt/face-manager.hpp"
 #include "mgmt/strategy-choice-manager.hpp"
-#include "mgmt/status-server.hpp"
+#include "mgmt/forwarder-status-manager.hpp"
 #include "mgmt/general-config-section.hpp"
 #include "mgmt/tables-config-section.hpp"
+#include "mgmt/command-validator.hpp"
+
+#include <ndn-cxx/mgmt/dispatcher.hpp>
 
 namespace nfd {
 
@@ -128,17 +132,26 @@
 Nfd::initializeManagement()
 {
   m_internalFace = make_shared<InternalFace>();
+  m_forwarder->getFaceTable().addReserved(m_internalFace, FACEID_INTERNAL_FACE);
+  m_internalClientFace = makeInternalClientFace(m_internalFace, m_keyChain);
+  m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_internalClientFace, m_keyChain));
+
+  m_validator.reset(new CommandValidator());
 
   m_fibManager.reset(new FibManager(m_forwarder->getFib(),
                                     bind(&Forwarder::getFace, m_forwarder.get(), _1),
-                                    m_internalFace, m_keyChain));
+                                    *m_dispatcher,
+                                    *m_validator));
 
-  m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(), m_internalFace, m_keyChain));
+  m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(),
+                                      *m_dispatcher,
+                                      *m_validator));
 
   m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
-                                                          m_internalFace, m_keyChain));
+                                                          *m_dispatcher,
+                                                          *m_validator));
 
-  m_statusServer.reset(new StatusServer(m_internalFace, *m_forwarder, m_keyChain));
+  m_forwarderStatusManager.reset(new ForwarderStatusManager(*m_forwarder, *m_dispatcher));
 
   ConfigFile config(&ignoreRibAndLogSections);
   general::setConfigFile(config);
@@ -151,9 +164,7 @@
                                    m_forwarder->getNetworkRegionTable());
   tablesConfig.setConfigFile(config);
 
-  m_internalFace->getValidator().setConfigFile(config);
-
-  m_forwarder->getFaceTable().addReserved(m_internalFace, FACEID_INTERNAL_FACE);
+  m_validator->setConfigFile(config);
 
   m_faceManager->setConfigFile(config);
 
@@ -170,8 +181,10 @@
   tablesConfig.ensureTablesAreConfigured();
 
   // add FIB entry for NFD Management Protocol
-  shared_ptr<fib::Entry> entry = m_forwarder->getFib().insert("/localhost/nfd").first;
+  Name topPrefix("/localhost/nfd");
+  auto entry = m_forwarder->getFib().insert(topPrefix).first;
   entry->addNextHop(m_internalFace, 0);
+  m_dispatcher->addTopPrefix(topPrefix, false);
 }
 
 void
@@ -195,7 +208,7 @@
 
   tablesConfig.setConfigFile(config);
 
-  m_internalFace->getValidator().setConfigFile(config);
+  m_validator->setConfigFile(config);
   m_faceManager->setConfigFile(config);
 
   if (!m_configFile.empty()) {
diff --git a/daemon/nfd.hpp b/daemon/nfd.hpp
index 4710554..34111b3 100644
--- a/daemon/nfd.hpp
+++ b/daemon/nfd.hpp
@@ -33,6 +33,14 @@
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/util/network-monitor.hpp>
 
+namespace ndn {
+namespace mgmt {
+
+class Dispatcher;
+
+}
+}
+
 namespace nfd {
 
 class Forwarder;
@@ -40,7 +48,9 @@
 class FibManager;
 class FaceManager;
 class StrategyChoiceManager;
-class StatusServer;
+class ForwarderStatusManager;
+class InternalClientFace;
+class CommandValidator;
 
 /**
  * \brief Class representing NFD instance
@@ -97,16 +107,19 @@
 
   unique_ptr<Forwarder> m_forwarder;
 
-  shared_ptr<InternalFace>          m_internalFace;
-  unique_ptr<FibManager>            m_fibManager;
-  unique_ptr<FaceManager>           m_faceManager;
-  unique_ptr<StrategyChoiceManager> m_strategyChoiceManager;
-  unique_ptr<StatusServer>          m_statusServer;
+  ndn::KeyChain&                     m_keyChain;
+  shared_ptr<InternalFace>           m_internalFace;
+  shared_ptr<InternalClientFace>     m_internalClientFace;
+  unique_ptr<CommandValidator>       m_validator;
 
-  ndn::KeyChain&                    m_keyChain;
+  unique_ptr<ndn::mgmt::Dispatcher>  m_dispatcher;
+  unique_ptr<FibManager>             m_fibManager;
+  unique_ptr<FaceManager>            m_faceManager;
+  unique_ptr<StrategyChoiceManager>  m_strategyChoiceManager;
+  unique_ptr<ForwarderStatusManager> m_forwarderStatusManager;
 
-  ndn::util::NetworkMonitor         m_networkMonitor;
-  scheduler::ScopedEventId          m_reloadConfigEvent;
+  ndn::util::NetworkMonitor          m_networkMonitor;
+  scheduler::ScopedEventId           m_reloadConfigEvent;
 };
 
 } // namespace nfd
diff --git a/tests/daemon/face/internal-client-face.t.cpp b/tests/daemon/face/internal-client-face.t.cpp
new file mode 100644
index 0000000..0b2295c
--- /dev/null
+++ b/tests/daemon/face/internal-client-face.t.cpp
@@ -0,0 +1,134 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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/internal-client-face.hpp"
+#include "face/internal-face.hpp"
+#include "tests/test-common.hpp"
+#include "tests/identity-management-fixture.hpp"
+
+namespace nfd {
+namespace tests {
+
+class InternalClientFaceFixture : public UnitTestTimeFixture
+                                , public IdentityManagementFixture
+{
+public:
+  InternalClientFaceFixture()
+    : m_internalFace(make_shared<InternalFace>())
+    , m_face(makeInternalClientFace(m_internalFace, m_keyChain))
+  {
+  }
+
+protected:
+  shared_ptr<InternalFace> m_internalFace;
+  shared_ptr<InternalClientFace> m_face;
+};
+
+BOOST_FIXTURE_TEST_SUITE(FaceInternalClientFace, InternalClientFaceFixture)
+
+BOOST_AUTO_TEST_CASE(ExpressInterest)
+{
+  bool didReceiveDataBack = false;
+  bool didTimeoutCallbackFire = false;
+  Data receivedData;
+
+  auto expressInterest = [&] (shared_ptr<Interest> interest) {
+    didReceiveDataBack = false;
+    didTimeoutCallbackFire = false;
+    m_face->expressInterest(interest->setInterestLifetime(time::milliseconds(100)),
+                            [&] (const Interest& interest, Data& data) {
+                              didReceiveDataBack = true;
+                              receivedData = data;
+                            },
+                            bind([&] { didTimeoutCallbackFire = true; }));
+    advanceClocks(time::milliseconds(1));
+  };
+
+  expressInterest(makeInterest("/test/timeout"));
+  advanceClocks(time::milliseconds(1), 200); // wait for time out
+  BOOST_CHECK(didTimeoutCallbackFire);
+
+  auto dataToSend = makeData("/test/data")->setContent(Block("\x81\x01\0x01", 3));
+  expressInterest(makeInterest("/test/data"));
+  m_internalFace->sendData(dataToSend); // send data to satisfy the expressed interest
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK(didReceiveDataBack);
+  BOOST_CHECK(receivedData.wireEncode() == dataToSend.wireEncode());
+}
+
+BOOST_AUTO_TEST_CASE(InterestFilter)
+{
+  bool didOnInterestCallbackFire = false;
+  Block receivedBlock, expectedBlock;
+
+  auto testSendInterest = [&] (shared_ptr<Interest> interest) {
+    didOnInterestCallbackFire = false;
+    expectedBlock = interest->wireEncode();
+    m_internalFace->sendInterest(*interest);
+  };
+
+  testSendInterest(makeInterest("/test/filter")); // no filter is set now
+  BOOST_CHECK(!didOnInterestCallbackFire);
+
+  // set filter
+  auto filter = m_face->setInterestFilter("/test/filter",
+                                          bind([&](const Interest& interset) {
+                                              didOnInterestCallbackFire = true;
+                                              receivedBlock = interset.wireEncode();
+                                            }, _2));
+  advanceClocks(time::milliseconds(1));
+
+  testSendInterest(makeInterest("/test/filter"));
+  BOOST_CHECK(didOnInterestCallbackFire);
+  BOOST_CHECK(receivedBlock == expectedBlock);
+
+  // unset filter
+  didOnInterestCallbackFire = false;
+  m_face->unsetInterestFilter(filter);
+  advanceClocks(time::milliseconds(1));
+  testSendInterest(makeInterest("/test/filter"));
+  BOOST_CHECK(!didOnInterestCallbackFire);
+}
+
+BOOST_AUTO_TEST_CASE(PutData)
+{
+  bool didInternalFaceReceiveData = false;
+  Data receivedData;
+  m_internalFace->onReceiveData.connect([&] (const Data& data) {
+      didInternalFaceReceiveData = true;
+      receivedData = data;
+    });
+
+  auto dataToPut = makeData("/test/put/data");
+  m_face->put(*dataToPut);
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK(didInternalFaceReceiveData);
+  BOOST_CHECK(receivedData.wireEncode() == dataToPut->wireEncode());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/face/internal-face.t.cpp b/tests/daemon/face/internal-face.t.cpp
new file mode 100644
index 0000000..44f5e7b
--- /dev/null
+++ b/tests/daemon/face/internal-face.t.cpp
@@ -0,0 +1,143 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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/internal-face.hpp"
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+class InternalFaceFixture : protected BaseFixture
+{
+public:
+  InternalFaceFixture()
+  {
+    m_face.onReceiveInterest.connect([this] (const Interest& interest) {
+        inInterests.push_back(interest);
+      });
+    m_face.onSendInterest.connect([this] (const Interest& interest) {
+        outInterests.push_back(interest);
+      });
+    m_face.onReceiveData.connect([this] (const Data& data) {
+        inData.push_back(data);
+      });
+    m_face.onSendData.connect([this] (const Data& data) {
+        outData.push_back(data);
+      });
+  }
+
+protected:
+  InternalFace m_face;
+  std::vector<Interest> inInterests;
+  std::vector<Interest> outInterests;
+  std::vector<Data> inData;
+  std::vector<Data> outData;
+};
+
+BOOST_FIXTURE_TEST_SUITE(FaceInternalFace, InternalFaceFixture)
+
+BOOST_AUTO_TEST_CASE(SendInterest)
+{
+  BOOST_CHECK(outInterests.empty());
+
+  auto interest = makeInterest("/test/send/interest");
+  Block expectedBlock = interest->wireEncode(); // assign a value to nonce
+  m_face.sendInterest(*interest);
+
+  BOOST_CHECK_EQUAL(outInterests.size(), 1);
+  BOOST_CHECK(outInterests[0].wireEncode() == expectedBlock);
+}
+
+BOOST_AUTO_TEST_CASE(SendData)
+{
+  BOOST_CHECK(outData.empty());
+
+  auto data = makeData("/test/send/data");
+  m_face.sendData(*data);
+
+  BOOST_CHECK_EQUAL(outData.size(), 1);
+  BOOST_CHECK(outData[0].wireEncode() == data->wireEncode());
+}
+
+BOOST_AUTO_TEST_CASE(ReceiveInterest)
+{
+  BOOST_CHECK(inInterests.empty());
+
+  auto interest = makeInterest("/test/receive/interest");
+  Block expectedBlock = interest->wireEncode(); // assign a value to nonce
+  m_face.receiveInterest(*interest);
+
+  BOOST_CHECK_EQUAL(inInterests.size(), 1);
+  BOOST_CHECK(inInterests[0].wireEncode() == expectedBlock);
+}
+
+BOOST_AUTO_TEST_CASE(ReceiveData)
+{
+  BOOST_CHECK(inData.empty());
+
+  auto data = makeData("/test/send/data");
+  m_face.receiveData(*data);
+
+  BOOST_CHECK_EQUAL(inData.size(), 1);
+  BOOST_CHECK(inData[0].wireEncode() == data->wireEncode());
+}
+
+BOOST_AUTO_TEST_CASE(ReceiveBlock)
+{
+  BOOST_CHECK(inInterests.empty());
+  BOOST_CHECK(inData.empty());
+
+  Block interestBlock = makeInterest("test/receive/interest")->wireEncode();
+  m_face.receive(interestBlock);
+  BOOST_CHECK_EQUAL(inInterests.size(), 1);
+  BOOST_CHECK(inInterests[0].wireEncode() == interestBlock);
+
+  Block dataBlock = makeData("test/receive/data")->wireEncode();
+  m_face.receive(dataBlock);
+  BOOST_CHECK_EQUAL(inData.size(), 1);
+  BOOST_CHECK(inData[0].wireEncode() == dataBlock);
+}
+
+BOOST_AUTO_TEST_CASE(ExtractPacketFromBlock)
+{
+  {
+    Block block = makeInterest("/test/interest")->wireEncode();
+    const Block& payload = ndn::nfd::LocalControlHeader::getPayload(block);
+    auto interest = m_face.extractPacketFromBlock<Interest>(block, payload);
+    BOOST_CHECK(interest->wireEncode() == block);
+  }
+
+  {
+    Block block = makeData("/test/data")->wireEncode();
+    const Block& payload = ndn::nfd::LocalControlHeader::getPayload(block);
+    auto data = m_face.extractPacketFromBlock<Data>(block, payload);
+    BOOST_CHECK(data->wireEncode() == block);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/channel-status-common.hpp b/tests/daemon/mgmt/channel-status-common.hpp
deleted file mode 100644
index e04c0be..0000000
--- a/tests/daemon/mgmt/channel-status-common.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_CHANNEL_STATUS_COMMON_HPP
-#define NFD_TESTS_NFD_MGMT_CHANNEL_STATUS_COMMON_HPP
-
-#include "face/protocol-factory.hpp"
-#include "face/channel.hpp"
-
-#include "tests/test-common.hpp"
-
-#include <ndn-cxx/management/nfd-channel-status.hpp>
-
-
-
-namespace nfd {
-namespace tests {
-
-class DummyChannel : public Channel
-{
-public:
-
-  DummyChannel(const std::string& uri)
-  {
-    setUri(FaceUri(uri));
-  }
-
-  virtual
-  ~DummyChannel()
-  {
-  }
-};
-
-class DummyProtocolFactory : public ProtocolFactory
-{
-public:
-
-  DummyProtocolFactory()
-  {
-
-  }
-
-  virtual void
-  createFace(const FaceUri& uri,
-             ndn::nfd::FacePersistency persistency,
-             const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed)
-  {
-  }
-
-  virtual void
-  addChannel(const std::string& channelUri)
-  {
-    m_channels.push_back(make_shared<DummyChannel>(channelUri));
-  }
-
-  virtual std::list<shared_ptr<const Channel> >
-  getChannels() const
-  {
-    return m_channels;
-  }
-
-  virtual size_t
-  getNChannels() const
-  {
-    return m_channels.size();
-  }
-
-private:
-  std::list<shared_ptr<const Channel> > m_channels;
-};
-
-} // namespace tests
-} // namespace nfd
-
-#endif // NFD_TESTS_NFD_MGMT_CHANNEL_STATUS_COMMON_HPP
diff --git a/tests/daemon/mgmt/channel-status-publisher.t.cpp b/tests/daemon/mgmt/channel-status-publisher.t.cpp
deleted file mode 100644
index 6027137..0000000
--- a/tests/daemon/mgmt/channel-status-publisher.t.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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/channel-status-publisher.hpp"
-#include "mgmt/internal-face.hpp"
-
-#include "channel-status-common.hpp"
-
-namespace nfd {
-namespace tests {
-
-class ChannelStatusPublisherFixture : BaseFixture
-{
-public:
-  ChannelStatusPublisherFixture()
-    : m_face(make_shared<InternalFace>())
-    , m_publisher(m_factories, *m_face, "/localhost/nfd/faces/channels", m_keyChain)
-    , m_finished(false)
-  {
-  }
-
-  virtual
-  ~ChannelStatusPublisherFixture()
-  {
-  }
-
-  // virtual shared_ptr<DummyProtocolFactory>
-  // addProtocolFactory(const std::string& protocol)
-  // {
-  //   shared_ptr<DummyProtocolFactory> factory(make_shared<DummyProtocolFactory>());
-  //   m_factories[protocol] = factory;
-
-  //   return factory;
-  // }
-
-  void
-  validatePublish(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 Channel Status entries in a single Content TLV for easy parsing
-    m_buffer.prependVarNumber(m_buffer.size());
-    m_buffer.prependVarNumber(tlv::Content);
-
-    ndn::Block parser(m_buffer.buf(), m_buffer.size());
-    parser.parse();
-
-    BOOST_REQUIRE_EQUAL(parser.elements_size(), m_expectedEntries.size());
-
-    for (Block::element_const_iterator i = parser.elements_begin();
-         i != parser.elements_end();
-         ++i)
-      {
-        if (i->type() != ndn::tlv::nfd::ChannelStatus)
-          {
-            BOOST_FAIL("expected ChannelStatus, got type #" << i->type());
-          }
-
-        ndn::nfd::ChannelStatus entry(*i);
-
-        std::map<std::string, ndn::nfd::ChannelStatus>::const_iterator expectedEntryPos =
-          m_expectedEntries.find(entry.getLocalUri());
-
-        BOOST_REQUIRE(expectedEntryPos != m_expectedEntries.end());
-        const ndn::nfd::ChannelStatus& expectedEntry = expectedEntryPos->second;
-
-        BOOST_CHECK_EQUAL(entry.getLocalUri(), expectedEntry.getLocalUri());
-
-        m_matchedEntries.insert(entry.getLocalUri());
-      }
-
-    BOOST_CHECK_EQUAL(m_matchedEntries.size(), m_expectedEntries.size());
-
-    m_finished = true;
-  }
-
-protected:
-  ChannelStatusPublisher::FactoryMap m_factories;
-  shared_ptr<InternalFace> m_face;
-  ChannelStatusPublisher m_publisher;
-
-  ndn::EncodingBuffer m_buffer;
-
-  std::map<std::string, ndn::nfd::ChannelStatus> m_expectedEntries;
-  std::set<std::string> m_matchedEntries;
-
-  bool m_finished;
-
-  ndn::KeyChain m_keyChain;
-};
-
-BOOST_FIXTURE_TEST_SUITE(MgmtChannelStatusPublisher, ChannelStatusPublisherFixture)
-
-BOOST_AUTO_TEST_CASE(Publish)
-{
-  const std::string protocol = "dummy";
-
-  shared_ptr<DummyProtocolFactory> factory(make_shared<DummyProtocolFactory>());
-  m_factories[protocol] = factory;
-
-  for (int i = 0; i < 10; ++i)
-    {
-      const std::string uri = protocol + "://path" + boost::lexical_cast<std::string>(i);
-      factory->addChannel(uri);
-
-      ndn::nfd::ChannelStatus expectedEntry;
-      expectedEntry.setLocalUri(DummyChannel(uri).getUri().toString());
-
-      m_expectedEntries[expectedEntry.getLocalUri()] = expectedEntry;
-    }
-
-  m_face->onReceiveData.connect(bind(&ChannelStatusPublisherFixture::validatePublish, this, _1));
-
-  m_publisher.publish();
-  BOOST_REQUIRE(m_finished);
-}
-
-BOOST_AUTO_TEST_CASE(DuplicateFactories)
-{
-  const std::string protocol1 = "dummy1";
-  const std::string protocol2 = "dummy2";
-
-  shared_ptr<DummyProtocolFactory> factory(make_shared<DummyProtocolFactory>());
-  m_factories[protocol1] = factory;
-  m_factories[protocol2] = factory;
-
-  for (int i = 0; i < 10; ++i)
-    {
-      ndn::nfd::ChannelStatus expectedEntry;
-      const std::string uri = protocol1 + "://path" + boost::lexical_cast<std::string>(i);
-
-      factory->addChannel(uri);
-
-      expectedEntry.setLocalUri(DummyChannel(uri).getUri().toString());
-      m_expectedEntries[expectedEntry.getLocalUri()] = expectedEntry;
-    }
-
-  m_face->onReceiveData.connect(bind(&ChannelStatusPublisherFixture::validatePublish, this, _1));
-
-  m_publisher.publish();
-  BOOST_REQUIRE(m_finished);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-
-
-
-} // namespace nfd
diff --git a/tests/daemon/mgmt/face-manager/create-face.t.cpp b/tests/daemon/mgmt/face-manager-create-face.t.cpp
similarity index 85%
rename from tests/daemon/mgmt/face-manager/create-face.t.cpp
rename to tests/daemon/mgmt/face-manager-create-face.t.cpp
index 3a70619..ffee5aa 100644
--- a/tests/daemon/mgmt/face-manager/create-face.t.cpp
+++ b/tests/daemon/mgmt/face-manager-create-face.t.cpp
@@ -24,27 +24,34 @@
  */
 
 #include "mgmt/face-manager.hpp"
-#include "mgmt/internal-face.hpp"
 #include "fw/forwarder.hpp"
 
 #include "tests/test-common.hpp"
 
+#include <ndn-cxx/mgmt/dispatcher.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
 #include <boost/property_tree/info_parser.hpp>
 
 namespace nfd {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, BaseFixture)
 
-BOOST_AUTO_TEST_SUITE(CreateFace)
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+BOOST_FIXTURE_TEST_SUITE(CreateFace, BaseFixture)
 
 class FaceManagerNode
 {
 public:
   FaceManagerNode(ndn::KeyChain& keyChain, const std::string& port = "6363")
-    : face(make_shared<InternalFace>())
-    , manager(forwarder.getFaceTable(), face, keyChain)
+    : face(ndn::util::makeDummyClientFace(getGlobalIoService(), {true, true}))
+    , dispatcher(*face, keyChain, ndn::security::SigningInfo())
+    , manager(forwarder.getFaceTable(), dispatcher, validator)
   {
+    dispatcher.addTopPrefix("/localhost/nfd");
+
     std::string basicConfig =
       "face_system\n"
       "{\n"
@@ -75,7 +82,7 @@
 
     ConfigFile config;
     manager.setConfigFile(config);
-    face->getValidator().setConfigFile(config);
+    validator.setConfigFile(config);
     config.parse(configSection, false, "dummy-config");
   }
 
@@ -92,7 +99,9 @@
 
 public:
   Forwarder forwarder;
-  shared_ptr<InternalFace> face;
+  shared_ptr<ndn::util::DummyClientFace> face;
+  ndn::mgmt::Dispatcher dispatcher;
+  CommandValidator validator;
   FaceManager manager;
 };
 
@@ -103,6 +112,7 @@
     : node1(keyChain, "16363")
     , node2(keyChain, "26363")
   {
+    advanceClocks(time::milliseconds(1), 100);
   }
 
   ~FaceManagerFixture()
@@ -166,6 +176,18 @@
   }
 };
 
+class UdpFaceCannotConnect // face that will cause afterCreateFaceFailure to be invoked
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://0.0.0.0:16363"); // cannot connect to self
+  }
+};
+
+
 class UdpFacePersistent
 {
 public:
@@ -198,7 +220,7 @@
   {
     return ControlResponse()
       .setCode(200)
-      .setText("Success");
+      .setText("OK");
   }
 };
 
@@ -223,7 +245,8 @@
                     mpl::pair<TcpFacePermanent, Failure<500>>,
                     mpl::pair<UdpFaceOnDemand, Failure<500>>,
                     mpl::pair<UdpFacePersistent, Success>,
-                    mpl::pair<UdpFacePermanent, Success>> Faces;
+                    mpl::pair<UdpFacePermanent, Success>,
+                    mpl::pair<UdpFaceCannotConnect, Failure<408>>> Faces;
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerFixture)
 {
@@ -238,7 +261,8 @@
   this->keyChain.sign(*command);
 
   bool hasCallbackFired = false;
-  this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+  this->node1.face->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
+      // std::cout << response << std::endl;
       if (!command->getName().isPrefixOf(response.getName())) {
         return;
       }
@@ -258,8 +282,8 @@
       hasCallbackFired = true;
     });
 
-  this->node1.face->sendInterest(*command);
-  this->advanceClocks(time::milliseconds(1), 10);
+  this->node1.face->receive(*command);
+  this->advanceClocks(time::milliseconds(1), 100);
 
   BOOST_CHECK(hasCallbackFired);
 }
@@ -287,7 +311,7 @@
     shared_ptr<Interest> command(make_shared<Interest>(commandName));
     this->keyChain.sign(*command);
 
-    this->node1.face->sendInterest(*command);
+    this->node1.face->receive(*command);
     this->advanceClocks(time::milliseconds(1), 10);
   }
 
@@ -303,7 +327,7 @@
     this->keyChain.sign(*command);
 
     bool hasCallbackFired = false;
-    this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+    this->node1.face->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
         if (!command->getName().isPrefixOf(response.getName())) {
           return;
         }
@@ -318,7 +342,7 @@
         hasCallbackFired = true;
       });
 
-    this->node1.face->sendInterest(*command);
+    this->node1.face->receive(*command);
     this->advanceClocks(time::milliseconds(1), 10);
 
     BOOST_CHECK(hasCallbackFired);
@@ -326,18 +350,6 @@
 }
 
 
-// class TcpFace
-// {
-// public:
-//   ControlParameters
-//   getParameters()
-//   {
-//     return ControlParameters()
-//       .setUri("tcp4://127.0.0.1:16363")
-//       .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-//   }
-// };
-
 class UdpFace
 {
 public:
@@ -376,13 +388,13 @@
     this->keyChain.sign(*command);
 
     ndn::util::signal::ScopedConnection connection =
-      this->node2.face->onReceiveData.connect([this, command] (const Data& response) {
+      this->node2.face->onSendData.connect([this, command] (const Data& response) {
           if (!command->getName().isPrefixOf(response.getName())) {
             return;
           }
 
           ControlResponse controlResponse(response.getContent().blockFromValue());
-          BOOST_REQUIRE_EQUAL(controlResponse.getText(), "Success");
+          BOOST_REQUIRE_EQUAL(controlResponse.getText(), "OK");
           BOOST_REQUIRE_EQUAL(controlResponse.getCode(), 200);
           uint64_t faceId = ControlParameters(controlResponse.getBody()).getFaceId();
           auto face = this->node2.forwarder.getFace(static_cast<FaceId>(faceId));
@@ -392,7 +404,7 @@
           face->sendInterest(*dummyInterest);
         });
 
-    this->node2.face->sendInterest(*command);
+    this->node2.face->receive(*command);
     this->advanceClocks(time::milliseconds(1), 10);
   }
 
@@ -419,7 +431,7 @@
     this->keyChain.sign(*command);
 
     bool hasCallbackFired = false;
-    this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+    this->node1.face->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
         if (!command->getName().isPrefixOf(response.getName())) {
           return;
         }
@@ -434,7 +446,7 @@
         hasCallbackFired = true;
       });
 
-    this->node1.face->sendInterest(*command);
+    this->node1.face->receive(*command);
     this->advanceClocks(time::milliseconds(1), 10);
 
     BOOST_CHECK(hasCallbackFired);
@@ -442,8 +454,8 @@
 }
 
 BOOST_AUTO_TEST_SUITE_END() // CreateFace
-
-BOOST_AUTO_TEST_SUITE_END() // MgmtFaceManager
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
 
 } // tests
 } // nfd
diff --git a/tests/daemon/mgmt/face-manager-process-config.t.cpp b/tests/daemon/mgmt/face-manager-process-config.t.cpp
new file mode 100644
index 0000000..9463ac4
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager-process-config.t.cpp
@@ -0,0 +1,438 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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 "face/udp-factory.hpp"
+
+#ifdef HAVE_LIBPCAP
+#include "face/ethernet-factory.hpp"
+#endif // HAVE_LIBPCAP
+
+#include "manager-common-fixture.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+class FaceManagerProcessConfigFixture : public ManagerCommonFixture
+{
+public:
+  FaceManagerProcessConfigFixture()
+    : m_manager(m_forwarder.getFaceTable(), m_dispatcher, m_validator)
+  {
+    m_manager.setConfigFile(m_config);
+  }
+
+public:
+  void
+  parseConfig(const std::string& type, bool isDryRun)
+  {
+    m_config.parse(type, isDryRun, "test-config");
+  }
+
+protected:
+  FaceManager m_manager;
+  ConfigFile m_config;
+};
+
+
+BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceManagerProcessConfigFixture)
+
+#ifdef HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUnix)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    path /tmp/nfd.sock\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUnixUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+#endif // HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 16363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpChannelsDisabled)
+{
+  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_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdp)
+{
+  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, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadIdleTimeout)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    idle_timeout hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcastGroup)
+{
+  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_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcastGroupV6)
+{
+  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_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpChannelsDisabled)
+{
+  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_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpConflictingMcast)
+{
+  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_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpMulticastReinit)
+{
+  const std::string CONFIG_WITH_MCAST =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
+
+  BOOST_REQUIRE(m_manager.m_factories.find("udp") != m_manager.m_factories.end());
+  auto factory = dynamic_pointer_cast<UdpFactory>(m_manager.m_factories.find("udp")->second);
+  BOOST_REQUIRE(factory != nullptr);
+
+  if (factory->getMulticastFaces().size() == 0) {
+    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
+                       "no UDP multicast faces are available");
+    return;
+  }
+  BOOST_CHECK_GT(factory->getMulticastFaces().size(), 0);
+
+  const std::string CONFIG_WITHOUT_MCAST =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
+  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+}
+
+#ifdef HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEther)
+{
+
+  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_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherMulticastReinit)
+{
+  const std::string CONFIG_WITH_MCAST =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
+
+  BOOST_REQUIRE(m_manager.m_factories.find("ether") != m_manager.m_factories.end());
+  auto factory = dynamic_pointer_cast<EthernetFactory>(m_manager.m_factories.find("ether")->second);
+  BOOST_REQUIRE(factory != nullptr);
+
+  if (factory->getMulticastFaces().size() == 0) {
+    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
+                       "no Ethernet multicast faces are available");
+    return;
+  }
+  BOOST_CHECK_GT(factory->getMulticastFaces().size(), 0);
+
+  const std::string CONFIG_WITHOUT_MCAST =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
+  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+}
+
+#endif // HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index 36e9e8a..db24029 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -24,1853 +24,426 @@
  */
 
 #include "mgmt/face-manager.hpp"
-#include "mgmt/internal-face.hpp"
-#include "mgmt/face-status-publisher.hpp"
-
-#include "face/face.hpp"
+#include "manager-common-fixture.hpp"
 #include "../face/dummy-face.hpp"
-#include "fw/face-table.hpp"
-#include "fw/forwarder.hpp"
+#include "face/tcp-factory.hpp"
 #include "face/udp-factory.hpp"
 
-#ifdef HAVE_LIBPCAP
-#include "face/ethernet-factory.hpp"
-#endif // HAVE_LIBPCAP
-
-#include "common.hpp"
-#include "tests/test-common.hpp"
-#include "validation-common.hpp"
-#include "face-status-publisher-common.hpp"
-#include "face-query-status-publisher-common.hpp"
-#include "channel-status-common.hpp"
-
+#include <ndn-cxx/util/random.hpp>
 #include <ndn-cxx/encoding/tlv.hpp>
+#include <ndn-cxx/management/nfd-channel-status.hpp>
 #include <ndn-cxx/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;
-  bool m_callbackFired;
-  ndn::KeyChain m_testKeyChain;
-};
-
-class FaceManagerFixture : public TestFaceTableFixture, public TestFaceManagerCommon
+class FaceManagerFixture : public ManagerCommonFixture
 {
 public:
   FaceManagerFixture()
-    : m_manager(m_faceTable, m_face, m_testKeyChain)
+    : m_faceTable(m_forwarder.getFaceTable())
+    , m_manager(m_faceTable, m_dispatcher, m_validator)
   {
-    m_manager.setConfigFile(m_config);
+    setTopPrefixAndPrivilege("/localhost/nfd", "faces");
   }
 
-  virtual
-  ~FaceManagerFixture()
+public:
+  template<typename Face>
+  shared_ptr<Face>
+  addFace(bool wantRemoveLastNotification = false)
   {
-
-  }
-
-  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();
+    auto face = make_shared<Face>();
+    m_faceTable.add(face);
+    advanceClocks(time::milliseconds(1), 10); // wait for notification posted
+    if (wantRemoveLastNotification) {
+      m_responses.pop_back();
+    }
+    return face;
   }
 
 protected:
+  FaceTable& m_faceTable;
   FaceManager m_manager;
-  ConfigFile m_config;
 };
 
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, FaceManagerFixture)
+BOOST_FIXTURE_TEST_SUITE(Mgmt, FaceManagerFixture)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+BOOST_AUTO_TEST_SUITE(DestroyFace)
+
+BOOST_AUTO_TEST_CASE(Existing)
+{
+  auto addedFace = addFace<DummyFace>(true); // clear notification for creation
+
+  auto parameters = ControlParameters().setFaceId(addedFace->getId());
+  auto command = makeControlCommandRequest("/localhost/nfd/faces/destroy", parameters);
+
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2); // one response and one notification
+  // notification is already tested, so ignore it
+
+  BOOST_CHECK_EQUAL(checkResponse(1, command->getName(), makeResponse(200, "OK", parameters)),
+                    CheckResponseResult::OK);
+
+  BOOST_CHECK_EQUAL(addedFace->getId(), -1);
+}
+
+BOOST_AUTO_TEST_CASE(NonExisting)
+{
+  auto parameters = ControlParameters().setFaceId(65535);
+  auto command = makeControlCommandRequest("/localhost/nfd/faces/destroy", parameters);
+
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "OK", parameters)),
+                    CheckResponseResult::OK);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // DestroyFace
+
+BOOST_AUTO_TEST_CASE(FaceEvents)
+{
+  auto addedFace = addFace<DummyFace>(); // trigger FACE_EVENT_CREATED notification
+  BOOST_CHECK_NE(addedFace->getId(), -1);
+  int64_t faceId = addedFace->getId();
+
+  // check notification
+  {
+    Block payload;
+    ndn::nfd::FaceEventNotification notification;
+    BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+    BOOST_CHECK_NO_THROW(payload = m_responses[0].getContent().blockFromValue());
+    BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+    BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+    BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_CREATED);
+    BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+    BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+    BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+  }
+
+  addedFace->close(); // trigger FaceDestroy FACE_EVENT_DESTROYED
+  advanceClocks(time::milliseconds(1), 10);
+
+  // check notification
+  {
+    Block payload;
+    ndn::nfd::FaceEventNotification notification;
+    BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+    BOOST_CHECK_NO_THROW(payload = m_responses[1].getContent().blockFromValue());
+    BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+    BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+    BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DESTROYED);
+    BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+    BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+    BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+  }
+  BOOST_CHECK_EQUAL(addedFace->getId(), -1);
+}
+
+BOOST_AUTO_TEST_CASE(EnableDisableLocalControl)
+{
+  auto nonLocalFace = addFace<DummyFace>(true); // clear notification
+  auto localFace = addFace<DummyLocalFace>(true); // clear notification
+  BOOST_CHECK(localFace->isLocal());
+  BOOST_CHECK(!nonLocalFace->isLocal());
+
+  std::vector<Name> commandNames;
+  auto testLocalControl = [&] (const Name& name, const ControlParameters& params, uint64_t faceId) {
+    auto command = makeControlCommandRequest(name, params,
+                                             [faceId] (shared_ptr<Interest> interest) {
+                                               interest->setIncomingFaceId(faceId);
+                                             });
+    receiveInterest(command);
+    commandNames.push_back(command->getName());
+  };
+
+  auto paramsF = ControlParameters().setLocalControlFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+  auto paramsN = ControlParameters().setLocalControlFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  // non-existing face: 0~3
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, FACEID_NULL);
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, FACEID_NULL);
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, FACEID_NULL);
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, FACEID_NULL);
+
+  // non-local face: 4~7
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, nonLocalFace->getId());
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, nonLocalFace->getId());
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, nonLocalFace->getId());
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, nonLocalFace->getId());
+
+  // enableLocalControl for Incoming FaceId on existing local face:
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, localFace->getId()); // 8
+  BOOST_CHECK(localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // disableLocalControl for Incoming FaceId on existing local face
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, localFace->getId()); // 9
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // enableLocalControl for NextHop ID on existing local face
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, localFace->getId()); // 10
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // disableLocalControl for NextHop ID on existing local face
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, localFace->getId()); // 11
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // check responses
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 12);
+  BOOST_CHECK_EQUAL(checkResponse(0,  commandNames[0],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(1,  commandNames[1],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(2,  commandNames[2],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(3,  commandNames[3],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(4,  commandNames[4],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(5,  commandNames[5],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(6,  commandNames[6],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(7,  commandNames[7],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(8,  commandNames[8],  makeResponse(200, "OK", paramsF)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(9,  commandNames[9],  makeResponse(200, "OK", paramsF)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(10, commandNames[10], makeResponse(200, "OK", paramsN)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(11, commandNames[11], makeResponse(200, "OK", paramsN)),
+                    CheckResponseResult::OK);
+}
+
+class TestFace : public DummyFace
+{
+public:
+  explicit
+  TestFace(const std::string& uri = "test://")
+    : DummyFace(uri, uri)
+  {
+    getMutableCounters().getNInInterests().set(ndn::random::generateWord64());
+    getMutableCounters().getNInDatas().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutInterests().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutDatas().set(ndn::random::generateWord64());
+    getMutableCounters().getNInBytes().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutBytes().set(ndn::random::generateWord64());
+  }
+};
+
+// @todo Refactor when ndn::nfd::FaceStatus implementes operator!= and operator<<
+class FaceStatus : public ndn::nfd::FaceStatus
+{
+public:
+  FaceStatus(const ndn::nfd::FaceStatus& s)
+    : ndn::nfd::FaceStatus(s)
+  {
+  }
+};
 
 bool
-isExpectedException(const ConfigFile::Error& error, const std::string& expectedMessage)
+operator!=(const FaceStatus& left, const FaceStatus& right)
 {
-  if (error.what() != expectedMessage)
-    {
-      NFD_LOG_ERROR("expected: " << expectedMessage << "\tgot: " << error.what());
-    }
-  return error.what() == expectedMessage;
+  return left.getRemoteUri() != right.getRemoteUri() ||
+    left.getLocalUri() != right.getLocalUri() ||
+    left.getFaceScope() != right.getFaceScope() ||
+    left.getFacePersistency() != right.getFacePersistency() ||
+    left.getLinkType() != right.getLinkType() ||
+    left.getNInInterests() != right.getNInInterests() ||
+    left.getNInDatas() != right.getNInDatas() ||
+    left.getNOutInterests() != right.getNOutInterests() ||
+    left.getNOutDatas() != right.getNOutDatas() ||
+    left.getNInBytes() != right.getNInBytes() ||
+    left.getNOutBytes() != right.getNOutBytes();
 }
 
-#ifdef HAVE_UNIX_SOCKETS
-
-BOOST_AUTO_TEST_CASE(TestProcessSectionUnix)
+std::ostream&
+operator<<(std::ostream &os, const FaceStatus& status)
 {
-  const std::string CONFIG =
-    "face_system\n"
-    "{\n"
-    "  unix\n"
-    "  {\n"
-    "    path /tmp/nfd.sock\n"
-    "  }\n"
-    "}\n";
-  BOOST_TEST_CHECKPOINT("Calling parse");
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+  os << "[" << status.getRemoteUri() << ", "
+     << status.getLocalUri() << ", "
+     << status.getFacePersistency() << ", "
+     << status.getLinkType() << ", "
+     << status.getNInInterests() << ", "
+     << status.getNInDatas() << ", "
+     << status.getNOutInterests() << ", "
+     << status.getNOutDatas() << ", "
+     << status.getNInBytes() << ", "
+     << status.getNOutBytes() << "]";
+  return os;
 }
 
-BOOST_AUTO_TEST_CASE(TestProcessSectionUnixDryRun)
+BOOST_AUTO_TEST_CASE(FaceDataset)
 {
-  const std::string CONFIG =
-    "face_system\n"
-    "{\n"
-    "  unix\n"
-    "  {\n"
-    "    path /var/run/nfd.sock\n"
-    "  }\n"
-    "}\n";
-
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
-}
-
-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"));
-}
-
-
-BOOST_AUTO_TEST_CASE(TestProcessSectionUdpMulticastReinit)
-{
-  const std::string CONFIG_WITH_MCAST =
-    "face_system\n"
-    "{\n"
-    "  udp\n"
-    "  {\n"
-    "    mcast yes\n"
-    "  }\n"
-    "}\n";
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
-
-  shared_ptr<UdpFactory> factory = static_pointer_cast<UdpFactory>(getManager().findFactory("udp"));
-  BOOST_REQUIRE(static_cast<bool>(factory));
-
-  if (factory->getMulticastFaces().size() == 0) {
-    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
-                       "no UDP multicast faces are available");
+  size_t nEntries = 303;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    addFace<TestFace>(true);
   }
 
-  const std::string CONFIG_WITHOUT_MCAST =
-    "face_system\n"
-    "{\n"
-    "  udp\n"
-    "  {\n"
-    "    mcast no\n"
-    "  }\n"
-    "}\n";
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
-  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
-}
+  receiveInterest(makeInterest("/localhost/nfd/faces/list"));
 
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
 
-#ifdef HAVE_LIBPCAP
+  std::vector<FaceStatus> expectedStatuses, receivedStatuses;
+  std::set<FaceId> faceIds;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
 
-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"));
-}
-
-BOOST_AUTO_TEST_CASE(TestProcessSectionEtherMulticastReinit)
-{
-  const std::string CONFIG_WITH_MCAST =
-    "face_system\n"
-    "{\n"
-    "  ether\n"
-    "  {\n"
-    "    mcast yes\n"
-    "  }\n"
-    "}\n";
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
-
-  shared_ptr<EthernetFactory> factory =
-    static_pointer_cast<EthernetFactory>(getManager().findFactory("ether"));
-  BOOST_REQUIRE(static_cast<bool>(factory));
-
-  if (factory->getMulticastFaces().size() == 0) {
-    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
-                       "no Ethernet multicast faces are available");
+    ndn::nfd::FaceStatus decodedStatus;
+    BOOST_REQUIRE_NO_THROW(decodedStatus.wireDecode(content.elements()[idx]));
+    BOOST_REQUIRE(m_faceTable.get(decodedStatus.getFaceId()) != nullptr);
+    faceIds.insert(decodedStatus.getFaceId());
+    receivedStatuses.push_back(decodedStatus);
+    expectedStatuses.push_back(m_faceTable.get(decodedStatus.getFaceId())->getFaceStatus());
   }
 
-  const std::string CONFIG_WITHOUT_MCAST =
-    "face_system\n"
-    "{\n"
-    "  ether\n"
-    "  {\n"
-    "    mcast no\n"
-    "  }\n"
-    "}\n";
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
-  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+  BOOST_CHECK_EQUAL(faceIds.size(), nEntries);
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedStatuses.begin(), receivedStatuses.end(),
+                                expectedStatuses.begin(), expectedStatuses.end());
 }
 
-#endif // HAVE_LIBPCAP
-
-BOOST_AUTO_TEST_CASE(ShortName)
+BOOST_AUTO_TEST_CASE(FaceQuery)
 {
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
+  auto face1 = addFace<DummyFace>(true); // dummy://
+  auto face2 = addFace<DummyLocalFace>(true); // dummy://, local
+  auto face3 = addFace<TestFace>(true); // test://
 
-  getFace()->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
+  auto generateQueryName = [] (const ndn::nfd::FaceQueryFilter& filter) {
+    return Name("/localhost/nfd/faces/query").append(filter.wireEncode());
+  };
 
-  getFace()->sendInterest(*command);
-  g_io.run_one();
+  auto querySchemeName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setUriScheme("dummy"));
+  auto queryIdName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setFaceId(face1->getId()));
+  auto queryScopeName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL));
+  auto invalidQueryName =
+    Name("/localhost/nfd/faces/query").append(ndn::makeStringBlock(tlv::Content, "invalid"));
 
-  BOOST_REQUIRE(didCallbackFire());
+  receiveInterest(makeInterest(querySchemeName)); // face1 and face2 expected
+  receiveInterest(makeInterest(queryIdName)); // face1 expected
+  receiveInterest(makeInterest(queryScopeName)); // face1 and face3 expected
+  receiveInterest(makeInterest(invalidQueryName)); // nack expected
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 4);
+
+  Block content;
+  ndn::nfd::FaceStatus status;
+
+  content = m_responses[0].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 2); // face1 and face2
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
+  BOOST_CHECK_EQUAL(face2->getId(), status.getFaceId());
+
+  content = m_responses[1].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 1); // face1
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+
+  content = m_responses[2].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 2); // face1 and face3
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
+  BOOST_CHECK_EQUAL(face3->getId(), status.getFaceId());
+
+  ControlResponse expectedResponse(400, "malformed filter"); // nack, 400, malformed filter
+  BOOST_CHECK_EQUAL(checkResponse(3, invalidQueryName, expectedResponse, tlv::ContentType_Nack),
+                    CheckResponseResult::OK);
 }
 
-BOOST_AUTO_TEST_CASE(MalformedCommmand)
-{
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
-
-  getFace()->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
-
-  getManager().onFaceRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_AUTO_TEST_CASE(UnsignedCommand)
-{
-  ControlParameters parameters;
-  parameters.setUri("tcp4://127.0.0.1:6363");
-
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 401, "Signature required");
-  });
-
-  getManager().onFaceRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedCommandFixture<FaceManagerFixture>)
-{
-  ControlParameters parameters;
-  parameters.setUri("tcp4://127.0.0.1:6363");
-
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 403, "Unauthorized command");
-  });
-
-  getManager().onFaceRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-template <typename T> class AuthorizedCommandFixture : public CommandFixture<T>
+class TestChannel : public Channel
 {
 public:
-  AuthorizedCommandFixture()
+  TestChannel(const std::string& uri)
   {
-    const std::string regex = "^<localhost><nfd><faces>";
-    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
-  }
-
-  virtual
-  ~AuthorizedCommandFixture()
-  {
-
+    setUri(FaceUri(uri));
   }
 };
 
-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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 501, "Unsupported command");
-  });
-
-  getManager().onFaceRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-class ValidatedFaceRequestFixture : public TestFaceTableFixture,
-                                    public TestFaceManagerCommon,
-                                    public FaceManager
+class TestProtocolFactory : public ProtocolFactory
 {
 public:
-
-  ValidatedFaceRequestFixture()
-    : FaceManager(TestFaceTableFixture::m_faceTable, getFace(), m_testKeyChain),
-      m_createFaceFired(false),
-      m_destroyFaceFired(false)
-  {
-
-  }
-
   virtual void
-  createFace(const Interest& request,
-             ControlParameters& parameters)
+  createFace(const FaceUri& uri,
+             ndn::nfd::FacePersistency persistency,
+             const FaceCreatedCallback& onCreated,
+             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE
   {
-    m_createFaceFired = true;
   }
 
-  virtual void
-  destroyFace(const Interest& request,
-              ControlParameters& parameters)
+  virtual std::list<shared_ptr<const Channel>>
+  getChannels() const DECL_OVERRIDE
   {
-    m_destroyFaceFired = true;
+    return m_channels;
   }
 
-  virtual
-  ~ValidatedFaceRequestFixture()
+public:
+  shared_ptr<TestChannel>
+  addChannel(const std::string& channelUri)
   {
-
-  }
-
-  bool
-  didCreateFaceFire() const
-  {
-    return m_createFaceFired;
-  }
-
-  bool
-  didDestroyFaceFire() const
-  {
-    return m_destroyFaceFired;
+    auto channel = make_shared<TestChannel>(channelUri);
+    m_channels.push_back(channel);
+    return channel;
   }
 
 private:
-  bool m_createFaceFired;
-  bool m_destroyFaceFired;
+  std::list<shared_ptr<const Channel> > m_channels;
 };
 
-BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestBadOptionParse,
-                        AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
+BOOST_AUTO_TEST_CASE(ChannelDataset)
 {
-  Name commandName("/localhost/nfd/faces");
-  commandName.append("create");
-  commandName.append("NotReallyParameters");
+  auto factory = make_shared<TestProtocolFactory>();
+  m_manager.m_factories["test"] = factory;
 
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  getFace()->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
-
-  onValidatedFaceRequest(command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestCreateFace,
-                        AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
-{
-  ControlParameters parameters;
-  parameters.setUri("tcp4://127.0.0.1:6363");
-
-  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("tcp4://127.0.0.1:6363");
-
-  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)
-  {
+  std::map<std::string, shared_ptr<TestChannel>> addedChannels;
+  size_t nEntries = 404;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    auto channel = factory->addChannel("test" + boost::lexical_cast<std::string>(i) + "://");
+    addedChannels[channel->getUri().toString()] = channel;
   }
 
-  virtual
-  ~FaceTableFixture()
-  {
+  receiveInterest(makeInterest("/localhost/nfd/faces/channels"));
+
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    ndn::nfd::ChannelStatus decodedStatus;
+    BOOST_CHECK_NO_THROW(decodedStatus.wireDecode(content.elements()[idx]));
+    BOOST_CHECK(addedChannels.find(decodedStatus.getLocalUri()) != addedChannels.end());
   }
-
-protected:
-  Forwarder m_forwarder;
-  FaceTable m_faceTable;
-};
-
-class LocalControlFixture : public FaceTableFixture,
-                            public TestFaceManagerCommon,
-                            public FaceManager
-{
-public:
-  LocalControlFixture()
-    : FaceManager(FaceTableFixture::m_faceTable, getFace(), m_testKeyChain)
-  {
-  }
-};
-
-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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand, encodedParameters] (const Data& response) {
-        this->validateControlResponse(response, 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));
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand, encodedParameters] (const Data& response) {
-        this->validateControlResponse(response, 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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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));
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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));
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand] (const Data& response) {
-        this->validateControlResponse(response, enableCommand->getName(),
-                                      412, "Face is non-local");
-      });
-
-  onValidatedFaceRequest(enableCommand);
-
-  BOOST_REQUIRE(didCallbackFire());
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand, encodedParameters] (const Data& response) {
-        this->validateControlResponse(response, 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));
-
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand, encodedParameters] (const Data& response) {
-        this->validateControlResponse(response, 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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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));
-
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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);
-
-  signal::Connection conn = getFace()->onReceiveData.connect(
-      [this, enableCommand] (const Data& response) {
-        this->validateControlResponse(response, enableCommand->getName(),
-                                      412, "Face is non-local");
-      });
-
-  onValidatedFaceRequest(enableCommand);
-
-  BOOST_REQUIRE(didCallbackFire());
-
-  conn.disconnect();
-  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);
-
-  getFace()->onReceiveData.connect(
-      [this, disableCommand] (const Data& response) {
-        this->validateControlResponse(response, 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,
-                  getFace(),
-                  m_testKeyChain)
-    , 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());
-    BOOST_CHECK_EQUAL(notification.getFaceScope(), expectedFaceEvent.getFaceScope());
-    BOOST_CHECK_EQUAL(notification.getFacePersistency(), expectedFaceEvent.getFacePersistency());
-    BOOST_CHECK_EQUAL(notification.getLinkType(), expectedFaceEvent.getLinkType());
-  }
-
-  bool
-  didReceiveNotication() const
-  {
-    return m_receivedNotification;
-  }
-
-protected:
-  bool m_receivedNotification;
-};
-
-BOOST_FIXTURE_TEST_CASE(CreateFaceBadUri, AuthorizedCommandFixture<FaceFixture>)
-{
-  ControlParameters parameters;
-  parameters.setUri("tcp4:/127.0.0.1:6363");
-
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
-
-  createFace(*command, parameters);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-BOOST_FIXTURE_TEST_CASE(CreateFaceNoncanonicalUri, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Non-canonical URI");
-  });
-
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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("tcp4://127.0.0.1:6363");
-
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 501, "Unsupported protocol");
-  });
-
-  createFace(*command, parameters);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_FIXTURE_TEST_CASE(OnCreated, AuthorizedCommandFixture<FaceFixture>)
-{
-  ControlParameters parameters;
-  parameters.setUri("tcp4://127.0.0.1:6363");
-
-  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("dummy://");
-  resultParameters.setFaceId(FACEID_RESERVED_MAX + 1);
-  resultParameters.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-
-  shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
-
-  ndn::nfd::FaceEventNotification expectedFaceEvent;
-  expectedFaceEvent.setKind(ndn::nfd::FACE_EVENT_CREATED)
-                   .setFaceId(FACEID_RESERVED_MAX + 1)
-                   .setRemoteUri(dummy->getRemoteUri().toString())
-                   .setLocalUri(dummy->getLocalUri().toString())
-                   .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
-                   .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-
-  Block encodedResultParameters(resultParameters.wireEncode());
-
-  getFace()->onReceiveData.connect(
-      [this, command, encodedResultParameters, expectedFaceEvent] (const Data& response) {
-        this->callbackDispatch(response,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("tcp4://127.0.0.1:6363");
-
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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())
-                   .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
-                   .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-
-  getFace()->onReceiveData.connect(
-      [this, command, encodedParameters, expectedFaceEvent] (const Data& response) {
-        this->callbackDispatch(response,command->getName(), 200, "Success",
-                               encodedParameters, expectedFaceEvent);
-      });
-
-  destroyFace(*command, parameters);
-
-  BOOST_REQUIRE(didCallbackFire());
-  BOOST_REQUIRE(didReceiveNotication());
-}
-
-class FaceListFixture : public FaceStatusPublisherFixture
-{
-public:
-  FaceListFixture()
-    : m_manager(m_table, m_face, m_testKeyChain)
-  {
-
-  }
-
-  virtual
-  ~FaceListFixture()
-  {
-
-  }
-
-protected:
-  FaceManager m_manager;
-  ndn::KeyChain m_testKeyChain;
-};
-
-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 75
-  // use 59 FaceStatuses to force a FaceStatus to span Data packets
-  for (int i = 0; i < 59; i++)
-    {
-      shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
-
-      uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
-      dummy->setCounters(filler, filler, filler, filler, filler, filler);
-
-      m_referenceFaces.push_back(dummy);
-
-      add(dummy);
-    }
-
-  ndn::EncodingBuffer buffer;
-
-  m_face->onReceiveData.connect(bind(&FaceStatusPublisherFixture::decodeFaceStatusBlock,
-                                     this, _1));
-
-  m_manager.listFaces(*command);
-  BOOST_REQUIRE(m_finished);
-}
-
-class ChannelStatusFixture : public FaceManagerFixture
-{
-public:
-  void
-  validatePublish(const Data& data, const ndn::nfd::ChannelStatus& expectedEntry)
-  {
-    m_callbackFired = true;
-    Block b = data.getContent().blockFromValue();
-    ndn::nfd::ChannelStatus entry(b);
-    BOOST_CHECK_EQUAL(entry.getLocalUri(), expectedEntry.getLocalUri());
-  }
-
-  virtual shared_ptr<DummyProtocolFactory>
-  addProtocolFactory(const std::string& protocol)
-  {
-    shared_ptr<DummyProtocolFactory> factory(make_shared<DummyProtocolFactory>());
-    m_manager.m_factories[protocol] = factory;
-
-    return factory;
-  }
-};
-
-BOOST_FIXTURE_TEST_CASE(TestChannelStatus, ChannelStatusFixture)
-{
-  shared_ptr<DummyProtocolFactory> factory(addProtocolFactory("dummy"));
-  factory->addChannel("dummy://");
-
-  Name requestName("/localhost/nfd/faces/channels");
-  shared_ptr<Interest> request(make_shared<Interest>(requestName));
-
-  ndn::nfd::ChannelStatus expectedEntry;
-  expectedEntry.setLocalUri(DummyChannel("dummy://").getUri().toString());
-
-  m_face->onReceiveData.connect(bind(&ChannelStatusFixture::validatePublish,
-                                     this, _1, expectedEntry));
-
-  m_manager.listChannels(*request);
-  BOOST_REQUIRE(m_callbackFired);
-}
-
-class FaceQueryListFixture : public FaceQueryStatusPublisherFixture
-{
-public:
-  FaceQueryListFixture()
-    : m_manager(m_table, m_face, m_testKeyChain)
-  {
-
-  }
-
-  virtual
-  ~FaceQueryListFixture()
-  {
-
-  }
-
-protected:
-  FaceManager m_manager;
-  ndn::KeyChain m_testKeyChain;
-};
-
-BOOST_FIXTURE_TEST_CASE(TestValidQueryFilter, FaceQueryListFixture)
-{
-  Name queryName("/localhost/nfd/faces/query");
-  ndn::nfd::FaceQueryFilter queryFilter;
-  queryFilter.setUriScheme("dummy");
-  queryName.append(queryFilter.wireEncode());
-
-  shared_ptr<Interest> query(make_shared<Interest>(queryName));
-
-  // add expected faces
-  shared_ptr<DummyLocalFace> expectedFace1(make_shared<DummyLocalFace>());
-  m_referenceFaces.push_back(expectedFace1);
-  add(expectedFace1);
-
-  shared_ptr<DummyFace> expectedFace2(make_shared<DummyFace>());
-  m_referenceFaces.push_back(expectedFace2);
-  add(expectedFace2);
-
-  // add other faces
-  shared_ptr<DummyFace> face1(make_shared<DummyFace>("udp://", "udp://"));
-  add(face1);
-  shared_ptr<DummyLocalFace> face2(make_shared<DummyLocalFace>("tcp://", "tcp://"));
-  add(face2);
-
-  m_face->onReceiveData.connect(bind(&FaceQueryStatusPublisherFixture::decodeFaceStatusBlock,
-                                     this, _1));
-
-  m_manager.listQueriedFaces(*query);
-  BOOST_REQUIRE(m_finished);
-}
-
-BOOST_FIXTURE_TEST_CASE(TestInvalidQueryFilter, FaceQueryListFixture)
-{
-  Name queryName("/localhost/nfd/faces/query");
-  ndn::nfd::FaceStatus queryFilter;
-  queryName.append(queryFilter.wireEncode());
-
-  shared_ptr<Interest> query(make_shared<Interest>(queryName));
-
-  shared_ptr<DummyLocalFace> face(make_shared<DummyLocalFace>());
-  add(face);
-
-  m_face->onReceiveData.connect(bind(&FaceQueryStatusPublisherFixture::decodeNackBlock, this, _1));
-
-  m_manager.listQueriedFaces(*query);
-  BOOST_REQUIRE(m_finished);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
 
 } // namespace tests
 } // namespace nfd
diff --git a/tests/daemon/mgmt/face-query-status-publisher-common.hpp b/tests/daemon/mgmt/face-query-status-publisher-common.hpp
deleted file mode 100644
index 09582c9..0000000
--- a/tests/daemon/mgmt/face-query-status-publisher-common.hpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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_QUERY_STATUS_PUBLISHER_COMMON_HPP
-#define NFD_TESTS_NFD_MGMT_FACE_QUERY_STATUS_PUBLISHER_COMMON_HPP
-
-#include "mgmt/face-query-status-publisher.hpp"
-#include "mgmt/app-face.hpp"
-#include "mgmt/internal-face.hpp"
-#include "fw/forwarder.hpp"
-#include "face/udp-factory.hpp"
-
-#include "tests/test-common.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
-
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
-namespace nfd {
-namespace tests {
-
-class FaceQueryStatusPublisherFixture : public BaseFixture
-{
-public:
-
-  FaceQueryStatusPublisherFixture()
-    : m_table(m_forwarder)
-    , m_face(make_shared<InternalFace>())
-    , m_dummyFace(make_shared<DummyFace>())
-    , m_dummyLocalFace(make_shared<DummyLocalFace>())
-    , m_dummyUri(make_shared<DummyFace>("dummy://remoteUri", "dummy://localUri"))
-    , m_factory(UdpFactory())
-    , m_finished(false)
-  {
-  }
-
-  virtual
-  ~FaceQueryStatusPublisherFixture()
-  {
-  }
-
-  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));
-
-    BOOST_CHECK_EQUAL(status.getFaceId(), reference->getId());
-    BOOST_CHECK_EQUAL(status.getRemoteUri(), reference->getRemoteUri().toString());
-    BOOST_CHECK_EQUAL(status.getLocalUri(), reference->getLocalUri().toString());
-
-    if (reference->isLocal()) {
-      BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_LOCAL);
-    }
-    else {
-      BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
-    }
-
-    BOOST_CHECK_EQUAL(status.getFacePersistency(), reference->getPersistency());
-
-    if (reference->isMultiAccess()) {
-      BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
-    }
-    else {
-      BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
-    }
-  }
-
-  void
-  decodeFaceStatusBlock(const Data& data)
-  {
-    BOOST_REQUIRE_EQUAL(data.getContentType(), tlv::ContentType_Blob);
-
-    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(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;
-  }
-
-  void
-  decodeNackBlock(const Data& data)
-  {
-    BOOST_REQUIRE_EQUAL(data.getContentType(), tlv::ContentType_Nack);
-
-    m_finished = true;
-  }
-
-protected:
-  Forwarder m_forwarder;
-  FaceTable m_table;
-  shared_ptr<InternalFace> m_face;
-  ndn::EncodingBuffer m_buffer;
-  std::list<shared_ptr<Face> > m_referenceFaces;
-  ndn::KeyChain m_keyChain;
-  shared_ptr<DummyFace> m_dummyFace;
-  shared_ptr<DummyLocalFace> m_dummyLocalFace;
-  shared_ptr<DummyFace> m_dummyUri;
-  UdpFactory m_factory;
-
-protected:
-  bool m_finished;
-};
-
-} // namespace tests
-} // namespace nfd
-
-#endif // NFD_TESTS_NFD_MGMT_FACE_QUERY_STATUS_PUBLISHER_COMMON_HPP
diff --git a/tests/daemon/mgmt/face-query-status-publisher.t.cpp b/tests/daemon/mgmt/face-query-status-publisher.t.cpp
deleted file mode 100644
index 09f6804..0000000
--- a/tests/daemon/mgmt/face-query-status-publisher.t.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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-query-status-publisher-common.hpp"
-
-namespace nfd {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceQueryStatusPublisher, FaceQueryStatusPublisherFixture)
-
-BOOST_AUTO_TEST_CASE(NoConditionFilter)
-{
-  // filter without conditions matches all faces
-  ndn::nfd::FaceQueryFilter filter;
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), true);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyLocalFace), true);
-}
-
-BOOST_AUTO_TEST_CASE(AllConditionFilter)
-{
-  ndn::nfd::FaceQueryFilter filter;
-  filter.setUriScheme("dummy")
-        .setRemoteUri("dummy://")
-        .setLocalUri("dummy://")
-        .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
-        .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
-        .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
-
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), true);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyLocalFace), false);
-}
-
-BOOST_AUTO_TEST_CASE(UriSchemeFilter)
-{
-  ndn::nfd::FaceQueryFilter filter;
-  filter.setUriScheme("dummyurischeme");
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), false);
-  auto dummyUriScheme = make_shared<DummyFace>("dummyurischeme://", "dummyurischeme://");
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(dummyUriScheme), true);
-}
-
-BOOST_AUTO_TEST_CASE(RemoteUriFilter)
-{
-  ndn::nfd::FaceQueryFilter filter;
-  filter.setRemoteUri("dummy://remoteUri");
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), false);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyUri), true);
-}
-
-BOOST_AUTO_TEST_CASE(LocalUriFilter)
-{
-  ndn::nfd::FaceQueryFilter filter;
-  filter.setLocalUri("dummy://localUri");
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), false);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyUri), true);
-}
-
-
-BOOST_AUTO_TEST_CASE(LinkTypeFilter)
-{
-  shared_ptr<MulticastUdpFace> multicastFace = m_factory.createMulticastFace("0.0.0.0",
-                                                                             "224.0.0.1",
-                                                                             "20070");
-  ndn::nfd::FaceQueryFilter filter;
-  filter.setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), false);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(multicastFace), true);
-}
-
-BOOST_AUTO_TEST_CASE(PersistencyFilter)
-{
-  shared_ptr<MulticastUdpFace> multicastFace = m_factory.createMulticastFace("0.0.0.0",
-                                                                             "224.0.0.1",
-                                                                             "20070");
-  ndn::nfd::FaceQueryFilter filter;
-  filter.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
-  FaceQueryStatusPublisher faceQueryStatusPublisher(m_table, *m_face,
-                                                    "/localhost/nfd/FaceStatusPublisherFixture",
-                                                    filter, m_keyChain);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), false);
-  multicastFace->setPersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
-  BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(multicastFace), true);
-}
-
-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
deleted file mode 100644
index 882c976..0000000
--- a/tests/daemon/mgmt/face-status-publisher-common.hpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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 "fw/forwarder.hpp"
-
-#include "tests/test-common.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
-
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
-namespace nfd {
-namespace tests {
-
-class TestCountersFace : public DummyFace
-{
-public:
-
-  TestCountersFace()
-  {
-  }
-
-  virtual
-  ~TestCountersFace()
-  {
-  }
-
-  void
-  setCounters(PacketCounter::rep nInInterests,
-              PacketCounter::rep nInDatas,
-              PacketCounter::rep nOutInterests,
-              PacketCounter::rep nOutDatas,
-              ByteCounter::rep nInBytes,
-              ByteCounter::rep nOutBytes)
-  {
-    FaceCounters& counters = getMutableCounters();
-    counters.getNInInterests().set(nInInterests);
-    counters.getNInDatas().set(nInDatas);
-    counters.getNOutInterests().set(nOutInterests);
-    counters.getNOutDatas().set(nOutDatas);
-    counters.getNInBytes().set(nInBytes);
-    counters.getNOutBytes().set(nOutBytes);
-  }
-
-
-};
-
-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();
-  BOOST_THROW_EXCEPTION(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);
-    }
-  BOOST_THROW_EXCEPTION(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_keyChain)
-    , 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());
-
-    if (reference->isLocal()) {
-      BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_LOCAL);
-    }
-    else {
-      BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
-    }
-
-    BOOST_CHECK_EQUAL(status.getFacePersistency(), reference->getPersistency());
-
-    if (reference->isMultiAccess()) {
-      BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
-    }
-    else {
-      BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
-    }
-
-    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());
-    BOOST_CHECK_EQUAL(status.getNInBytes(), counters.getNInBytes());
-    BOOST_CHECK_EQUAL(status.getNOutBytes(), counters.getNOutBytes());
-  }
-
-  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(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;
-  ndn::KeyChain m_keyChain;
-
-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.t.cpp b/tests/daemon/mgmt/face-status-publisher.t.cpp
deleted file mode 100644
index 383dba8..0000000
--- a/tests/daemon/mgmt/face-status-publisher.t.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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 {
-
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceStatusPublisher, 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 75
-  // use 59 FaceStatuses to force a FaceStatus to span Data packets
-  for (int i = 0; i < 59; i++)
-    {
-      shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
-
-      uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
-      dummy->setCounters(filler, filler, filler, filler, filler, filler);
-
-      m_referenceFaces.push_back(dummy);
-
-      add(dummy);
-    }
-
-  ndn::EncodingBuffer buffer;
-
-  m_face->onReceiveData.connect(
-      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
deleted file mode 100644
index 9f9150b..0000000
--- a/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/* -*- 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,
- *                      The University of Memphis
- *
- * 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-cxx/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();
-  BOOST_THROW_EXCEPTION(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;
-  BOOST_THROW_EXCEPTION(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_keyChain)
-    , 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() == tlv::Name);
-    Name prefix(*i);
-    ++i;
-
-    std::set<shared_ptr<fib::Entry> >::const_iterator referenceIter =
-      std::find_if(m_referenceEntries.begin(), m_referenceEntries.end(),
-                   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(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;
-  ndn::KeyChain m_keyChain;
-
-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.t.cpp b/tests/daemon/mgmt/fib-enumeration-publisher.t.cpp
deleted file mode 100644
index 34cb582..0000000
--- a/tests/daemon/mgmt/fib-enumeration-publisher.t.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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-cxx/encoding/tlv.hpp>
-
-namespace nfd {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(MgmtFibEnumerationPublisher, 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.connect(
-      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.t.cpp b/tests/daemon/mgmt/fib-manager.t.cpp
index 82e70b9..513536c 100644
--- a/tests/daemon/mgmt/fib-manager.t.cpp
+++ b/tests/daemon/mgmt/fib-manager.t.cpp
@@ -22,904 +22,470 @@
  * 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 "manager-common-fixture.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"
+#include "../face/dummy-face.hpp"
+#include <ndn-cxx/management/nfd-fib-entry.hpp>
 
 namespace nfd {
 namespace tests {
 
-NFD_LOG_INIT("FibManagerTest");
-
-class FibManagerFixture : public FibEnumerationPublisherFixture
+class FibManagerFixture : public ManagerCommonFixture
 {
 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(ref(m_fib), bind(&FibManagerFixture::getFace, this, _1), m_face, m_keyChain)
-    , m_callbackFired(false)
+    : m_fib(m_forwarder.getFib())
+    , m_faceTable(m_forwarder.getFaceTable())
+    , m_manager(m_fib, bind(&Forwarder::getFace, &m_forwarder, _1), m_dispatcher, m_validator)
   {
+    setTopPrefixAndPrivilege("/localhost/nfd", "fib");
+  }
+
+public: // for test
+  ControlParameters
+  makeParameters(const Name& name, const FaceId& id)
+  {
+    return ControlParameters().setName(name).setFaceId(id);
+  }
+
+  ControlParameters
+  makeParameters(const Name& name, const FaceId& id, const uint32_t& cost)
+  {
+    return ControlParameters().setName(name).setFaceId(id).setCost(cost);
+  }
+
+  FaceId
+  addFace()
+  {
+    auto face = make_shared<DummyFace>();
+    m_faceTable.add(face);
+    advanceClocks(time::milliseconds(1), 10);
+    m_responses.clear(); // clear all event notifications, if any
+    return face->getId();
+  }
+
+public: // for check
+  enum class CheckNextHopResult
+  {
+    OK,
+    NO_FIB_ENTRY,
+    WRONG_N_NEXTHOPS,
+    NO_NEXTHOP,
+    WRONG_COST
+   };
+
+  /**
+   * @brief check whether the nexthop record is added / removed properly
+   *
+   * @param expectedNNextHops use -1 to skip this check
+   * @param faceId use FACEID_NULL to skip NextHopRecord checks
+   * @param expectedCost use -1 to skip this check
+   *
+   * @retval OK FIB entry is found by exact match and has the expected number of nexthops;
+   *            NextHopRe record for faceId is found and has the expected cost
+   * @retval NO_FIB_ENTRY FIB entry is not found
+   * @retval WRONG_N_NEXTHOPS FIB entry is found but has wrong number of nexthops
+   * @retval NO_NEXTHOP NextHopRecord for faceId is not found
+   * @retval WRONG_COST NextHopRecord for faceId has wrong cost
+   */
+  CheckNextHopResult
+  checkNextHop(const Name& prefix, ssize_t expectedNNextHops = -1,
+               FaceId faceId = FACEID_NULL, int32_t expectedCost = -1)
+  {
+    auto entry = m_fib.findExactMatch(prefix);
+    if (!static_cast<bool>(entry)) {
+      return CheckNextHopResult::NO_FIB_ENTRY;
+    }
+
+    auto nextHops = entry->getNextHops();
+    if (expectedNNextHops != -1 && nextHops.size() != static_cast<size_t>(expectedNNextHops)) {
+      return CheckNextHopResult::WRONG_N_NEXTHOPS;
+    }
+
+    if (faceId != FACEID_NULL) {
+      for (auto&& record : nextHops) {
+        if (record.getFace()->getId() == faceId) {
+          return expectedCost != -1 && record.getCost() != static_cast<uint32_t>(expectedCost) ?
+            CheckNextHopResult::WRONG_COST : CheckNextHopResult::OK;
+        }
+      }
+
+      return CheckNextHopResult::NO_NEXTHOP;
+    }
+
+    return CheckNextHopResult::OK;
   }
 
 protected:
+  Fib&       m_fib;
+  FaceTable& m_faceTable;
   FibManager m_manager;
-
-  std::vector<shared_ptr<Face> > m_faces;
-  bool m_callbackFired;
-  ndn::KeyChain m_keyChain;
 };
 
-template <typename T>
-class AuthorizedCommandFixture : public CommandFixture<T>
+std::ostream&
+operator<<(std::ostream &os, const FibManagerFixture::CheckNextHopResult& result)
 {
-public:
-  AuthorizedCommandFixture()
-  {
-    const std::string regex = "^<localhost><nfd><fib>";
-    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
-  }
+  switch (result) {
+  case FibManagerFixture::CheckNextHopResult::OK:
+    os << "OK";
+    break;
+  case FibManagerFixture::CheckNextHopResult::NO_FIB_ENTRY:
+    os << "NO_FIB_ENTRY";
+    break;
+  case FibManagerFixture::CheckNextHopResult::WRONG_N_NEXTHOPS:
+    os << "WRONG_N_NEXTHOPS";
+    break;
+  case FibManagerFixture::CheckNextHopResult::NO_NEXTHOP:
+    os << "NO_NEXTHOP";
+    break;
+  case FibManagerFixture::CheckNextHopResult::WRONG_COST:
+    os << "WRONG_COST";
+    break;
+  default:
+    break;
+  };
 
-  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;
+  return os;
 }
 
-bool
-addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
-{
-  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
+BOOST_FIXTURE_TEST_SUITE(Mgmt, FibManagerFixture)
+BOOST_AUTO_TEST_SUITE(TestFibManager)
 
-  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(ShortName)
-{
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  shared_ptr<Interest> command = makeInterest("/localhost/nfd/fib");
-
-  face->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
-
-  getFibManager().onFibRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
+BOOST_AUTO_TEST_SUITE(AddNextHop)
 
 BOOST_AUTO_TEST_CASE(UnknownFaceId)
 {
-  addFace(make_shared<DummyFace>());
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop",
+                                           makeParameters("hello", FACEID_NULL, 101));
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
 
-  shared_ptr<InternalFace> face = getInternalFace();
+  // check response
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
 
-  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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 410, "Face not found");
-  });
-
-  getFibManager().onFibRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-  BOOST_REQUIRE(addedNextHopWithCost(getFib(), "/hello", 0, 101) == false);
+  // double check that the next hop was not added
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, FACEID_NULL, 101), CheckNextHopResult::NO_FIB_ENTRY);
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbImplicitFaceId)
+BOOST_AUTO_TEST_CASE(ImplicitFaceId)
 {
-  addFace(make_shared<DummyFace>());
+  auto face1 = addFace();
+  auto face2 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID);
 
-  shared_ptr<InternalFace> face = getInternalFace();
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testAddNextHop = [&] (ControlParameters parameters, const FaceId& faceId) {
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters,
+                                             [&faceId] (shared_ptr<Interest> interest) {
+                                               interest->setIncomingFaceId(faceId);
+                                             });
+    m_responses.clear();
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters.setFaceId(faceId));
+    receiveInterest(command);
+  };
 
-  std::vector<ControlParameters> testedParameters;
-  testedParameters.push_back(ControlParameters().setName("/hello").setCost(101).setFaceId(0));
-  testedParameters.push_back(ControlParameters().setName("/hello").setCost(101));
+  testAddNextHop(ControlParameters().setName("/hello").setCost(100).setFaceId(0), face1);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 100), CheckNextHopResult::OK);
 
-  for (std::vector<ControlParameters>::iterator parameters = testedParameters.begin();
-       parameters != testedParameters.end(); ++parameters) {
-
-    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);
-
-    signal::Connection conn = face->onReceiveData.connect(
-        [this, command, encodedExpectedParameters] (const Data& response) {
-          this->validateControlResponse(response, command->getName(),
-                                        200, "Success", encodedExpectedParameters);
-        });
-
-    getFibManager().onFibRequest(*command);
-
-    BOOST_REQUIRE(didCallbackFire());
-    BOOST_REQUIRE(addedNextHopWithFace(getFib(), "/hello", 0, 101, getFace(1)));
-
-    conn.disconnect();
-    getFib().erase("/hello");
-    BOOST_REQUIRE_EQUAL(getFib().size(), 0);
-  }
+  testAddNextHop(ControlParameters().setName("/hello").setCost(100), face2);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face2, 100), CheckNextHopResult::OK);
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
+BOOST_AUTO_TEST_CASE(InitialAdd)
 {
-  addFace(make_shared<DummyFace>());
+  FaceId addedFaceId = addFace();
+  BOOST_REQUIRE(addedFaceId != INVALID_FACEID);
 
-  shared_ptr<InternalFace> face = getInternalFace();
+  auto parameters = makeParameters("hello", addedFaceId, 101);
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
 
-  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.connect([this, command, encodedParameters] (const Data& response) {
-    this->validateControlResponse(response, command->getName(),
-                                  200, "Success", encodedParameters);
-  });
-
-  getFibManager().onFibRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-  BOOST_REQUIRE(addedNextHopWithCost(getFib(), "/hello", 0, 101));
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 101), CheckNextHopResult::OK);
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbImplicitCost)
+BOOST_AUTO_TEST_CASE(ImplicitCost)
 {
-  addFace(make_shared<DummyFace>());
+  FaceId addedFaceId = addFace();
+  BOOST_REQUIRE(addedFaceId != INVALID_FACEID);
 
-  shared_ptr<InternalFace> face = getInternalFace();
+  auto originalParameters = ControlParameters().setName("/hello").setFaceId(addedFaceId);
+  auto parameters = makeParameters("/hello", addedFaceId, 0);
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", originalParameters);
 
-  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.connect([this, command, resultParameters] (const Data& response) {
-    this->validateControlResponse(response, command->getName(),
-                                  200, "Success", resultParameters.wireEncode());
-  });
-
-  getFibManager().onFibRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-  BOOST_REQUIRE(addedNextHopWithCost(getFib(), "/hello", 0, 0));
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 0), CheckNextHopResult::OK);
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
+BOOST_AUTO_TEST_CASE(AddToExisting)
 {
-  addFace(make_shared<DummyFace>());
-  shared_ptr<InternalFace> face = getInternalFace();
+  FaceId face = addFace();
+  BOOST_CHECK(face != INVALID_FACEID);
 
-  for (int i = 1; i <= 2; i++)
-    {
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testAddNextHop = [&] (const ControlParameters& parameters) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters);
+    receiveInterest(command);
+  };
 
-      ControlParameters parameters;
-      parameters.setName("/hello");
-      parameters.setFaceId(1);
-      parameters.setCost(100 + i);
+  // add initial, succeeds
+  testAddNextHop(makeParameters("/hello", face, 101));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
 
-      Block encodedParameters(parameters.wireEncode());
+  // add to existing --> update cost, succeeds
+  testAddNextHop(makeParameters("/hello", face, 102));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
 
-      Name commandName("/localhost/nfd/fib");
-      commandName.append("add-nexthop");
-      commandName.append(encodedParameters);
-
-      shared_ptr<Interest> command(make_shared<Interest>(commandName));
-      generateCommand(*command);
-
-      signal::Connection conn = face->onReceiveData.connect(
-          [this, command, encodedParameters] (const Data& response) {
-            this->validateControlResponse(response, 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");
-        }
-
-      conn.disconnect();
-    }
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face, 102), CheckNextHopResult::WRONG_N_NEXTHOPS);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 101), CheckNextHopResult::WRONG_COST);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 102), CheckNextHopResult::OK);
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
+BOOST_AUTO_TEST_SUITE_END() // AddNextHop
+
+BOOST_AUTO_TEST_SUITE(RemoveNextHop)
+
+BOOST_AUTO_TEST_CASE(Basic)
 {
-  addFace(make_shared<DummyFace>());
-  shared_ptr<InternalFace> face = getInternalFace();
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testRemoveNextHop = [&] (const ControlParameters& parameters) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters);
+    receiveInterest(command);
+  };
 
-  ControlParameters parameters;
-  parameters.setName("/hello");
-  parameters.setFaceId(1);
+  FaceId face1 = addFace();
+  FaceId face2 = addFace();
+  FaceId face3 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID && face3 != INVALID_FACEID);
 
+  shared_ptr<fib::Entry> entry = m_fib.insert("/hello").first;
+  entry->addNextHop(m_faceTable.get(face1), 101);
+  entry->addNextHop(m_faceTable.get(face2), 202);
+  entry->addNextHop(m_faceTable.get(face3), 303);
+
+  testRemoveNextHop(makeParameters("/hello", face1));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face1, 101), CheckNextHopResult::NO_NEXTHOP);
+
+  testRemoveNextHop(makeParameters("/hello", face2));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face2, 202), CheckNextHopResult::NO_NEXTHOP);
+
+  testRemoveNextHop(makeParameters("/hello", face3));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face3, 303), CheckNextHopResult::NO_FIB_ENTRY);
+}
+
+BOOST_AUTO_TEST_CASE(PrefixNotFound)
+{
+  FaceId addedFaceId = addFace();
+  BOOST_CHECK(addedFaceId != INVALID_FACEID);
+
+  auto parameters = makeParameters("hello", addedFaceId);
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
+  auto response = makeResponse(200, "Success", parameters);
+
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), response), CheckResponseResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(ImplicitFaceId)
+{
+  auto face1 = addFace();
+  auto face2 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID);
+
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testWithImplicitFaceId = [&] (ControlParameters parameters, FaceId face) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters,
+                                             [face] (shared_ptr<Interest> interest) {
+                                               interest->setIncomingFaceId(face);
+                                             });
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters.setFaceId(face));
+    receiveInterest(command);
+  };
+
+  shared_ptr<fib::Entry> entry = m_fib.insert("/hello").first;
+  entry->addNextHop(m_faceTable.get(face1), 101);
+  entry->addNextHop(m_faceTable.get(face2), 202);
+
+  testWithImplicitFaceId(ControlParameters().setName("/hello").setFaceId(0), face1);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 101), CheckNextHopResult::NO_NEXTHOP);
+
+  testWithImplicitFaceId(ControlParameters().setName("/hello"), face2);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face2, 202), CheckNextHopResult::NO_FIB_ENTRY);
+}
+
+BOOST_AUTO_TEST_CASE(RecordNotExist)
+{
+  auto face1 = addFace();
+  auto face2 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID);
+
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testRemoveNextHop = [&] (ControlParameters parameters) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters);
+    receiveInterest(command);
+  };
+
+  m_fib.insert("/hello").first->addNextHop(m_faceTable.get(face1), 101);
+
+  testRemoveNextHop(makeParameters("/hello", face2 + 100));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // face does not exist
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2 + 100), CheckNextHopResult::NO_NEXTHOP);
+
+  testRemoveNextHop(makeParameters("/hello", face2));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // record does not exist
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2), CheckNextHopResult::NO_NEXTHOP);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // RemoveNextHop
+
+// @todo Remove when ndn::nfd::FibEntry implements operator!= and operator<<
+class FibEntry : public ndn::nfd::FibEntry
+{
+public:
+  FibEntry() = default;
+
+  FibEntry(const ndn::nfd::FibEntry& entry)
+    : ndn::nfd::FibEntry(entry)
   {
-    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);
-
-    signal::Connection conn = face->onReceiveData.connect(
-        [this, command, encodedParameters] (const Data& response) {
-          this->validateControlResponse(response, command->getName(),
-                                        200, "Success", encodedParameters);
-        });
-
-    getFibManager().onFibRequest(*command);
-
-    BOOST_REQUIRE(didCallbackFire());
-
-    resetCallbackFired();
-    conn.disconnect();
   }
-
-  {
-    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.connect([this, command, encodedParameters] (const Data& response) {
-      this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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)
+operator!=(const FibEntry& left, const FibEntry& right)
 {
-  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
+  if (left.getPrefix() != right.getPrefix()) {
+    return true;
+  }
 
-  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();
+  auto leftNextHops = left.getNextHopRecords();
+  auto rightNextHops = right.getNextHopRecords();
+  if (leftNextHops.size() != rightNextHops.size()) {
+    return true;
+  }
+
+  for (auto&& nexthop : leftNextHops) {
+    auto hitEntry =
+      std::find_if(rightNextHops.begin(), rightNextHops.end(), [&] (const ndn::nfd::NextHopRecord& record) {
+          return nexthop.getCost() == record.getCost() && nexthop.getFaceId() == record.getFaceId();
+        });
+
+    if (hitEntry == rightNextHops.end()) {
+      return true;
     }
+  }
+
   return false;
 }
 
-void
-testRemoveNextHop(CommandFixture<FibManagerFixture>* fixture,
-                  FibManager& manager,
-                  Fib& fib,
-                  shared_ptr<Face> face,
-                  const Name& targetName,
-                  FaceId targetFace)
+std::ostream&
+operator<<(std::ostream &os, const FibEntry& entry)
 {
-  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);
-
-  signal::Connection conn = face->onReceiveData.connect(
-      [fixture, command, encodedParameters] (const Data& response) {
-        fixture->validateControlResponse(response, command->getName(),
-                                         200, "Success", encodedParameters);
-      });
-
-  manager.onFibRequest(*command);
-
-  BOOST_REQUIRE(fixture->didCallbackFire());
-
-  fixture->resetCallbackFired();
-  conn.disconnect();
-}
-
-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.connect([this, command, encodedParameters] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command, encodedParameters] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
-
-  getFibManager().onFibRequest(*command);
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_AUTO_TEST_CASE(RemoveImplicitFaceId)
-{
-  addFace(make_shared<DummyFace>());
-
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  std::vector<ControlParameters> testedParameters;
-  testedParameters.push_back(ControlParameters().setName("/hello").setFaceId(0));
-  testedParameters.push_back(ControlParameters().setName("/hello"));
-
-  for (std::vector<ControlParameters>::iterator parameters = testedParameters.begin();
-       parameters != testedParameters.end(); ++parameters) {
-    Block encodedParameters(parameters->wireEncode());
-
-    Name commandName("/localhost/nfd/fib");
-    commandName.append("remove-nexthop");
-    commandName.append(encodedParameters);
-
-    shared_ptr<Interest> command(make_shared<Interest>(commandName));
-    command->setIncomingFaceId(1);
-    generateCommand(*command);
-
-    ControlParameters resultParameters;
-    resultParameters.setFaceId(1);
-    resultParameters.setName("/hello");
-
-    signal::Connection conn = face->onReceiveData.connect(
-        [this, command, resultParameters] (const Data& response) {
-          this->validateControlResponse(response, command->getName(),
-                                        200, "Success", resultParameters.wireEncode());
-        });
-
-    getFibManager().onFibRequest(*command);
-
-    BOOST_REQUIRE(didCallbackFire());
-
-    conn.disconnect();
+  const auto& nexthops = entry.getNextHopRecords();
+  os << "[" << entry.getPrefix() << ", " << nexthops.size() << ": ";
+  for (auto record : nexthops) {
+    os << "{" << record.getFaceId() << ", " << record.getCost() << "} ";
   }
+  os << "]";
+
+  return os;
 }
 
-BOOST_FIXTURE_TEST_CASE(TestFibEnumerationRequest, FibManagerFixture)
+BOOST_AUTO_TEST_CASE(FibDataset)
 {
-  for (int i = 0; i < 87; i++)
-    {
-      Name prefix("/test");
-      prefix.appendSegment(i);
+  const size_t nEntries = 108;
+  std::set<Name> actualPrefixes;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    Name prefix = Name("test").appendSegment(i);
+    actualPrefixes.insert(prefix);
+    auto fibEntry = m_fib.insert(prefix).first;
+    fibEntry->addNextHop(m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 1);
+    fibEntry->addNextHop(m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 2);
+  }
 
-      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
-      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
+  receiveInterest(makeInterest("/localhost/nfd/fib/list"));
 
-      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);
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
 
-      m_referenceEntries.insert(entry);
+  std::vector<FibEntry> receivedRecords, expectedRecords;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    FibEntry decodedEntry;
+    BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
+    receivedRecords.push_back(decodedEntry);
+
+    actualPrefixes.erase(decodedEntry.getPrefix());
+
+    auto matchedEntry = m_fib.findExactMatch(decodedEntry.getPrefix());
+    BOOST_REQUIRE(matchedEntry != nullptr);
+
+    FibEntry record;
+    record.setPrefix(matchedEntry->getPrefix());
+    const auto& nextHops = matchedEntry->getNextHops();
+    for (auto&& next : nextHops) {
+      ndn::nfd::NextHopRecord nextHopRecord;
+      nextHopRecord.setFaceId(next.getFace()->getId());
+      nextHopRecord.setCost(next.getCost());
+      record.addNextHopRecord(nextHopRecord);
     }
-  for (int i = 0; i < 2; i++)
-    {
-      Name prefix("/test2");
-      prefix.appendSegment(i);
+    expectedRecords.push_back(record);
+  }
 
-      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
-      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
+  BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
 
-      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.connect(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_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
+                                expectedRecords.begin(), expectedRecords.end());
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestFibManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
 
 } // namespace tests
 } // namespace nfd
diff --git a/tests/daemon/mgmt/status-server.t.cpp b/tests/daemon/mgmt/forwarder-status-manager.t.cpp
similarity index 78%
rename from tests/daemon/mgmt/status-server.t.cpp
rename to tests/daemon/mgmt/forwarder-status-manager.t.cpp
index 4cf7c13..104adaa 100644
--- a/tests/daemon/mgmt/status-server.t.cpp
+++ b/tests/daemon/mgmt/forwarder-status-manager.t.cpp
@@ -23,39 +23,35 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "mgmt/status-server.hpp"
+#include "mgmt/forwarder-status-manager.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"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/mgmt/dispatcher.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_FIXTURE_TEST_SUITE(Mgmt, UnitTestTimeFixture)
+BOOST_AUTO_TEST_SUITE(TestForwarderStatusManager)
 
 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.connect(&interceptResponse);
+  auto face = ndn::util::makeDummyClientFace(g_io, {true, true});
   ndn::KeyChain keyChain;
-  StatusServer statusServer(internalFace, ref(forwarder), keyChain);
-  time::system_clock::TimePoint t2 = time::system_clock::now();
+  ndn::mgmt::Dispatcher dispatcher(*face, ref(keyChain));
+  ForwarderStatusManager statusServer(ref(forwarder), ref(dispatcher));
+  dispatcher.addTopPrefix("/localhost/nfd");
+  advanceClocks(time::milliseconds(1));
 
   // populate tables
+  time::system_clock::TimePoint t2 = time::system_clock::now();
   forwarder.getFib().insert("ndn:/fib1");
   forwarder.getPit().insert(*makeInterest("ndn:/pit1"));
   forwarder.getPit().insert(*makeInterest("ndn:/pit2"));
@@ -69,20 +65,19 @@
   BOOST_CHECK_GE(forwarder.getMeasurements().size(), 3);
 
   // request
-  shared_ptr<Interest> request = makeInterest("ndn:/localhost/nfd/status");
+  time::system_clock::TimePoint t3 = time::system_clock::now();
+  auto 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));
+  face->receive<Interest>(*request);
+  advanceClocks(time::milliseconds(1));
 
   // verify
+  time::system_clock::TimePoint t4 = time::system_clock::now();
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
   ndn::nfd::ForwarderStatus status;
-  BOOST_REQUIRE_NO_THROW(status.wireDecode(g_response->getContent()));
+  BOOST_REQUIRE_NO_THROW(status.wireDecode(face->sentDatas[0].getContent()));
 
   BOOST_CHECK_EQUAL(status.getNfdVersion(), NFD_VERSION_BUILD_STRING);
   BOOST_CHECK_GE(time::toUnixTimestamp(status.getStartTimestamp()), time::toUnixTimestamp(t1));
@@ -90,7 +85,7 @@
   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,
+  // Interest/Data toward ForwarderStatusManager don't go through 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());
@@ -99,7 +94,8 @@
   BOOST_CHECK_EQUAL(status.getNCsEntries(), forwarder.getCs().size());
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestForwarderStatusManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
 
 } // namespace tests
 } // namespace nfd
diff --git a/tests/daemon/mgmt/internal-face.t.cpp b/tests/daemon/mgmt/internal-face.t.cpp
deleted file mode 100644
index 29b602c..0000000
--- a/tests/daemon/mgmt/internal-face.t.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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 {
-
-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;
-  }
-
-protected:
-  ndn::KeyChain m_keyChain;
-
-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.connect(bind(&validatePutData, ref(didPutData), dataName, _1));
-
-  Data testData(dataName);
-  m_keyChain.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/manager-base.t.cpp b/tests/daemon/mgmt/manager-base.t.cpp
index 1b78175..f3ea152 100644
--- a/tests/daemon/mgmt/manager-base.t.cpp
+++ b/tests/daemon/mgmt/manager-base.t.cpp
@@ -24,177 +24,164 @@
  */
 
 #include "mgmt/manager-base.hpp"
-#include "mgmt/internal-face.hpp"
+#include "manager-common-fixture.hpp"
 
-#include "tests/test-common.hpp"
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/management/nfd-control-command.hpp>
 
 namespace nfd {
 namespace tests {
 
 NFD_LOG_INIT("ManagerBaseTest");
 
-class ManagerBaseTest : public ManagerBase, protected BaseFixture
+class TestCommandVoidParameters : public ndn::nfd::ControlCommand
 {
-
 public:
-
-  ManagerBaseTest()
-    : ManagerBase(make_shared<InternalFace>(), "TEST-PRIVILEGE", m_keyChain),
-      m_callbackFired(false)
+  TestCommandVoidParameters()
+    : ndn::nfd::ControlCommand("test-module", "test-void-parameters")
   {
-
   }
-
-  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 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;
-  ndn::KeyChain m_keyChain;
-
 };
 
-BOOST_FIXTURE_TEST_SUITE(MgmtManagerBase, ManagerBaseTest)
-
-BOOST_AUTO_TEST_CASE(SetResponse)
+class TestCommandRequireName : public ndn::nfd::ControlCommand
 {
-  ControlResponse response(200, "OK");
+public:
+  TestCommandRequireName()
+    : ndn::nfd::ControlCommand("test-module", "test-require-name")
+  {
+    m_requestValidator.required(ndn::nfd::CONTROL_PARAMETER_NAME);
+  }
+};
 
-  BOOST_CHECK_EQUAL(response.getCode(), 200);
-  BOOST_CHECK_EQUAL(response.getText(), "OK");
+class ManagerBaseFixture : public ManagerCommonFixture
+{
+public:
+  ManagerBaseFixture()
+    : m_manager(m_dispatcher, m_validator, "test-module")
+  {
+  }
 
-  testSetResponse(response, 100, "test");
+protected:
+  ManagerBase m_manager;
+};
 
-  BOOST_CHECK_EQUAL(response.getCode(), 100);
-  BOOST_CHECK_EQUAL(response.getText(), "test");
+BOOST_FIXTURE_TEST_SUITE(MgmtManagerBase, ManagerBaseFixture)
+
+BOOST_AUTO_TEST_CASE(AddSupportedPrivilegeInConstructor)
+{
+  BOOST_CHECK_NO_THROW(m_validator.addSupportedPrivilege("other-module"));
+  // test-module has already been added by the constructor of ManagerBase
+  BOOST_CHECK_THROW(m_validator.addSupportedPrivilege("test-module"), CommandValidator::Error);
 }
 
-BOOST_AUTO_TEST_CASE(SendResponse4Arg)
+BOOST_AUTO_TEST_CASE(RegisterCommandHandler)
 {
-  ndn::nfd::ControlParameters parameters;
-  parameters.setName("/test/body");
+  bool wasCommandHandlerCalled = false;
+  auto handler = bind([&] { wasCommandHandlerCalled = true; });
 
-  getInternalFace()->onReceiveData.connect([this, parameters] (const Data& response) {
-    this->validateControlResponse(response, "/response", 100, "test", parameters.wireEncode());
-  });
+  m_manager.registerCommandHandler<TestCommandVoidParameters>("test-void", handler);
+  m_manager.registerCommandHandler<TestCommandRequireName>("test-require-name", handler);
+  setTopPrefixAndPrivilege("/localhost/nfd", "test-module");
 
-  testSendResponse("/response", 100, "test", parameters.wireEncode());
-  BOOST_REQUIRE(didCallbackFire());
+  auto testRegisterCommandHandler = [&wasCommandHandlerCalled, this] (const Name& commandName) {
+    wasCommandHandlerCalled = false;
+    receiveInterest(makeControlCommandRequest(commandName, ControlParameters()));
+  };
+
+  testRegisterCommandHandler("/localhost/nfd/test-module/test-void");
+  BOOST_CHECK(wasCommandHandlerCalled);
+
+  testRegisterCommandHandler("/localhost/nfd/test-module/test-require-name");
+  BOOST_CHECK(!wasCommandHandlerCalled);
 }
 
-
-BOOST_AUTO_TEST_CASE(SendResponse3Arg)
+BOOST_AUTO_TEST_CASE(RegisterStatusDataset)
 {
-  getInternalFace()->onReceiveData.connect([this] (const Data& response) {
-    this->validateControlResponse(response, "/response", 100, "test");
-  });
+  bool isStatusDatasetCalled = false;
+  auto handler = bind([&] { isStatusDatasetCalled = true; });
 
-  testSendResponse("/response", 100, "test");
-  BOOST_REQUIRE(didCallbackFire());
+  m_manager.registerStatusDatasetHandler("test-status", handler);
+  m_dispatcher.addTopPrefix("/localhost/nfd");
+  advanceClocks(time::milliseconds(1));
+
+  receiveInterest(makeInterest("/localhost/nfd/test-module/test-status"));
+  BOOST_CHECK(isStatusDatasetCalled);
 }
 
-BOOST_AUTO_TEST_CASE(SendResponse2Arg)
+BOOST_AUTO_TEST_CASE(RegisterNotificationStream)
 {
-  getInternalFace()->onReceiveData.connect([this] (const Data& response) {
-    this->validateControlResponse(response, "/response", 100, "test");
-  });
+  auto post = m_manager.registerNotificationStream("test-notification");
+  m_dispatcher.addTopPrefix("/localhost/nfd");
+  advanceClocks(time::milliseconds(1));
 
-  ControlResponse response(100, "test");
+  post(Block("\x82\x01\x02", 3));
+  advanceClocks(time::milliseconds(1));
 
-  testSendResponse("/response", 100, "test");
-  BOOST_REQUIRE(didCallbackFire());
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(m_responses[0].getName(),
+                    Name("/localhost/nfd/test-module/test-notification/%FE%00"));
+}
+
+BOOST_AUTO_TEST_CASE(CommandAuthorization)
+{
+  bool didAcceptCallbackFire = false;
+  bool didRejectCallbackFire = false;
+  auto testAuthorization = [&] {
+    didAcceptCallbackFire = false;
+    didRejectCallbackFire = false;
+
+    auto command = makeControlCommandRequest("/localhost/nfd/test-module/test-verb",
+                                             ControlParameters());
+    ndn::nfd::ControlParameters params;
+    m_manager.authorize("/top/prefix", *command, &params,
+                        bind([&] { didAcceptCallbackFire = true; }),
+                        bind([&] { didRejectCallbackFire = true; }));
+  };
+
+  testAuthorization();
+  BOOST_CHECK(!didAcceptCallbackFire);
+  BOOST_CHECK(didRejectCallbackFire);
+
+  m_validator.addInterestRule("^<localhost><nfd><test-module>", *m_certificate);
+  testAuthorization();
+  BOOST_CHECK(didAcceptCallbackFire);
+  BOOST_CHECK(!didRejectCallbackFire);
+}
+
+BOOST_AUTO_TEST_CASE(ExtractRequester)
+{
+  std::string requesterName;
+  auto testAccept = [&] (const std::string& requester) { requesterName = requester; };
+
+  auto unsignedCommand = makeInterest("/test/interest/unsigned");
+  auto signedCommand = makeControlCommandRequest("/test/interest/signed", ControlParameters());
+
+  m_manager.extractRequester(*unsignedCommand, testAccept);
+  BOOST_CHECK(requesterName.empty());
+
+  requesterName = "";
+  m_manager.extractRequester(*signedCommand, testAccept);
+  auto keyLocator = m_keyChain.getDefaultCertificateNameForIdentity(m_identityName).getPrefix(-1);
+  BOOST_CHECK_EQUAL(requesterName, keyLocator.toUri());
+}
+
+BOOST_AUTO_TEST_CASE(ValidateParameters)
+{
+  ControlParameters params;
+  TestCommandVoidParameters commandVoidParams;
+  TestCommandRequireName commandRequireName;
+
+  BOOST_CHECK_EQUAL(ManagerBase::validateParameters(commandVoidParams, params), true); // succeeds
+  BOOST_CHECK_EQUAL(ManagerBase::validateParameters(commandRequireName, params), false); // fails
+
+  params.setName("test-name");
+  BOOST_CHECK_EQUAL(ManagerBase::validateParameters(commandRequireName, params), true); // succeeds
+}
+
+BOOST_AUTO_TEST_CASE(MakeRelPrefix)
+{
+  auto generatedRelPrefix = m_manager.makeRelPrefix("test-verb");
+  BOOST_CHECK_EQUAL(generatedRelPrefix, PartialName("/test-module/test-verb"));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/daemon/mgmt/manager-common-fixture.cpp b/tests/daemon/mgmt/manager-common-fixture.cpp
new file mode 100644
index 0000000..b03449e
--- /dev/null
+++ b/tests/daemon/mgmt/manager-common-fixture.cpp
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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 "manager-common-fixture.hpp"
+
+namespace nfd {
+namespace tests {
+
+ManagerCommonFixture::ManagerCommonFixture()
+  : m_face(ndn::util::makeDummyClientFace(UnitTestTimeFixture::g_io, {true, true}))
+  , m_dispatcher(*m_face, m_keyChain, ndn::security::SigningInfo())
+  , m_responses(m_face->sentDatas)
+  , m_identityName("/unit-test/ManagerCommonFixture/identity")
+  , m_certificate(m_keyChain.getCertificate(m_keyChain.createIdentity(m_identityName)))
+{
+}
+
+void
+ManagerCommonFixture::setTopPrefixAndPrivilege(const Name& topPrefix,
+                                               const std::string& privilege)
+{
+  m_dispatcher.addTopPrefix(topPrefix); // such that all filters are added
+  advanceClocks(time::milliseconds(1));
+
+  std::string regex("^");
+  for (auto component : topPrefix) {
+    regex += "<" + component.toUri() + ">";
+  }
+  m_validator.addInterestRule(regex + "<" + privilege + ">", *m_certificate);
+}
+
+shared_ptr<Interest>
+ManagerCommonFixture::makeControlCommandRequest(Name commandName,
+                                                const ControlParameters& parameters,
+                                                const InterestHandler& beforeSigning)
+{
+  shared_ptr<Interest> command = makeInterest(commandName.append(parameters.wireEncode()));
+
+  if (beforeSigning != nullptr) {
+    beforeSigning(command);
+  }
+
+  m_keyChain.sign(*command, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
+                                                       m_identityName));
+  return command;
+}
+
+void
+ManagerCommonFixture::receiveInterest(shared_ptr<Interest> interest)
+{
+  m_face->receive<Interest>(*interest);
+  advanceClocks(time::milliseconds(1));
+}
+
+ControlResponse
+ManagerCommonFixture::makeResponse(uint32_t code, const std::string& text,
+                                   const ControlParameters& parameters)
+{
+  return ControlResponse(code, text).setBody(parameters.wireEncode());
+}
+
+ManagerCommonFixture::CheckResponseResult
+ManagerCommonFixture::checkResponse(size_t idx,
+                                    const Name& expectedName,
+                                    const ControlResponse& expectedResponse,
+                                    int expectedContentType /*= -1*/)
+{
+  Data data;
+  try {
+    data = m_responses.at(idx);
+  }
+  catch (const std::out_of_range&) {
+    return CheckResponseResult::OUT_OF_BOUNDARY;
+  }
+
+  if (data.getName() != expectedName) {
+    return CheckResponseResult::WRONG_NAME;
+  }
+
+  if (expectedContentType != -1 &&
+      data.getContentType() != static_cast<uint32_t>(expectedContentType)) {
+    return CheckResponseResult::WRONG_CONTENT_TYPE;
+  }
+
+  ControlResponse response;
+  try {
+    response.wireDecode(data.getContent().blockFromValue());
+  }
+  catch (const tlv::Error&) {
+    return CheckResponseResult::INVALID_RESPONSE;
+  }
+
+  if (response.getCode() != expectedResponse.getCode()) {
+    return CheckResponseResult::WRONG_CODE;
+  }
+
+  if (response.getText() != expectedResponse.getText()) {
+    return CheckResponseResult::WRONG_TEXT;
+  }
+
+  const Block& body = response.getBody();
+  const Block& expectedBody = expectedResponse.getBody();
+  if (body.value_size() != expectedBody.value_size()) {
+    return CheckResponseResult::WRONG_BODY_SIZE;
+  }
+  if (body.value_size() > 0 && memcmp(body.value(), expectedBody.value(), body.value_size()) != 0) {
+    return CheckResponseResult::WRONG_BODY_VALUE;
+  }
+
+  return CheckResponseResult::OK;
+}
+
+Block
+ManagerCommonFixture::concatenateResponses(size_t startIndex, size_t nResponses)
+{
+  size_t endIndex = startIndex + nResponses; // not included
+  if (nResponses == startIndex || endIndex > m_responses.size()) {
+    endIndex = m_responses.size();
+  }
+
+  ndn::EncodingBuffer encoder;
+  size_t valueLength = 0;
+  for (size_t i = startIndex; i < endIndex ; i ++) {
+    valueLength += encoder.appendByteArray(m_responses[i].getContent().value(),
+                                           m_responses[i].getContent().value_size());
+  }
+  encoder.prependVarNumber(valueLength);
+  encoder.prependVarNumber(tlv::Content);
+  return encoder.block();
+}
+
+std::ostream&
+operator<<(std::ostream &os, const ManagerCommonFixture::CheckResponseResult& result)
+{
+  switch (result) {
+  case ManagerCommonFixture::CheckResponseResult::OK:
+    os << "OK";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::OUT_OF_BOUNDARY:
+    os << "OUT_OF_BOUNDARY";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::WRONG_NAME:
+    os << "WRONG_NAME";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::WRONG_CONTENT_TYPE:
+    os << "WRONG_CONTENT_TYPE";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::INVALID_RESPONSE:
+    os << "INVALID_RESPONSE";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::WRONG_CODE:
+    os << "WRONG_CODE";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::WRONG_TEXT:
+    os << "WRONG_TEXT";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::WRONG_BODY_SIZE:
+    os << "WRONG_BODY_SIZE";
+    break;
+  case ManagerCommonFixture::CheckResponseResult::WRONG_BODY_VALUE:
+    os << "WRONG_BODY_VALUE";
+    break;
+  default:
+    break;
+  };
+
+  return os;
+}
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/manager-common-fixture.hpp b/tests/daemon/mgmt/manager-common-fixture.hpp
new file mode 100644
index 0000000..ffdb579
--- /dev/null
+++ b/tests/daemon/mgmt/manager-common-fixture.hpp
@@ -0,0 +1,163 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  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,
+ *                           The University of Memphis.
+ *
+ * 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_MANAGER_COMMON_HPP
+#define NFD_TESTS_NFD_MGMT_MANAGER_COMMON_HPP
+
+#include "tests/test-common.hpp"
+#include "tests/identity-management-fixture.hpp"
+#include "mgmt/manager-base.hpp"
+#include "fw/forwarder.hpp"
+
+#include <ndn-cxx/mgmt/dispatcher.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace nfd {
+namespace tests {
+
+/**
+ * @brief a collection of common functions shared by all manager's testing fixtures.
+ */
+class ManagerCommonFixture : public UnitTestTimeFixture
+                           , public IdentityManagementFixture
+{
+public: // initialize
+  ManagerCommonFixture();
+
+  /**
+   * @brief set topPrefix to the dispatcher and configure an interest rule for the module.
+   *
+   * after setting @param topPrefix, call advanceClocks to ensure all added filters take effects.
+   *
+   * @param topPrefix top prefix for the dispatcher
+   * @param privilege the module name
+   */
+  void
+  setTopPrefixAndPrivilege(const Name& topPrefix, const std::string& privilege);
+
+public: // test
+  typedef std::function<void(shared_ptr<Interest> interest)> InterestHandler;
+
+  /**
+   * @brief create a ControlCommand request
+   *
+   * step1: append the @param parameters to the @param commandName and make an Interest.
+   * step2: call @param beforeSinging to do something with the Interest.
+   * step3: sign the generated command
+   *
+   * @param commandName the command name
+   * @param parameters the ControlParameters
+   * @param beforeSigning a callback that can modify the Interest before it's signed
+   *
+   * @return the signed ControlCommand request
+   */
+  shared_ptr<Interest>
+  makeControlCommandRequest(Name commandName,
+                            const ControlParameters& parameters,
+                            const InterestHandler& beforeSigning = nullptr);
+
+  /**
+   * @brief cause management to receive an Interest
+   *
+   * call DummyClientFace::receive to receive Interest and then call advanceClocks to ensure
+   * the Interest dispatched
+   *
+   * @param interest the Interest to receive
+   */
+  void
+  receiveInterest(shared_ptr<Interest> interest);
+
+public: // verify
+  ControlResponse
+  makeResponse(uint32_t code, const std::string& text,
+               const ControlParameters& parameters);
+
+  enum class CheckResponseResult
+  {
+    OK,
+    OUT_OF_BOUNDARY,
+    WRONG_NAME,
+    WRONG_CONTENT_TYPE,
+    INVALID_RESPONSE,
+    WRONG_CODE,
+    WRONG_TEXT,
+    WRONG_BODY_SIZE,
+    WRONG_BODY_VALUE
+   };
+
+  /**
+   * @brief check a specified response data with the expected ControlResponse
+   *
+   * @param idx the index of the specified Data in m_responses
+   * @param expectedDataName the expected name of this Data
+   * @param expectedResponse the expected ControlResponse
+   * @param expectedContentType the expected content type of this Data, use -1 to skip this check
+   *
+   * @retval OK the response at the specified index can be decoded from the response data,
+   *            and its code, text and response body are all matched with the expected response
+   * @retval OUT_OF_BOUNDARY the specified index out of boundary
+   * @retval WRONG_NAME the name of the specified response data does not match
+   * @retval WRONG_CONTENT_TYPE the content type of the specified response data does not match
+   * @retval INVALID_RESPONSE the data name matches but it fails in decoding a ControlResponse from
+   *                          the content of the specified response data
+   * @retval WRONG_CODE a valid ControlResponse can be decoded but has a wrong code
+   * @retval WRONG_TEXT a valid ControlResponse can be decoded but has a wrong text
+   * @retval WRONG_BODY_SIZE the body size of decoded ControlResponse does not match
+   * @retval WRONT_BODY_VALUE the body value of decoded ControlResponse does not match
+   */
+  CheckResponseResult
+  checkResponse(size_t idx,
+                const Name& expectedName,
+                const ControlResponse& expectedResponse,
+                int expectedContentType = -1);
+
+  /**
+   * @brief concatenate specified response Data into a single block
+   *
+   * @param startIndex the start index in m_responses
+   * @param nResponses the number of response to concatenate
+   *
+   * @return the generated block
+   */
+  Block
+  concatenateResponses(size_t startIndex = 0, size_t nResponses = 0);
+
+protected:
+  shared_ptr<ndn::util::DummyClientFace> m_face;
+  ndn::mgmt::Dispatcher                  m_dispatcher;
+  CommandValidator                       m_validator;
+  Forwarder                              m_forwarder;
+  std::vector<Data>&                     m_responses; // a reference of m_face->sentDatas
+  Name                                   m_identityName; // the identity used to sign request
+  shared_ptr<ndn::IdentityCertificate>   m_certificate; // the certificate used to sign request
+};
+
+std::ostream&
+operator<<(std::ostream &os, const ManagerCommonFixture::CheckResponseResult& result);
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_NFD_MGMT_MANAGER_COMMON_HPP
diff --git a/tests/daemon/mgmt/strategy-choice-manager.t.cpp b/tests/daemon/mgmt/strategy-choice-manager.t.cpp
index d0c425d..9e7a8c2 100644
--- a/tests/daemon/mgmt/strategy-choice-manager.t.cpp
+++ b/tests/daemon/mgmt/strategy-choice-manager.t.cpp
@@ -24,623 +24,225 @@
  */
 
 #include "mgmt/strategy-choice-manager.hpp"
+#include "manager-common-fixture.hpp"
+
 #include "face/face.hpp"
-#include "mgmt/internal-face.hpp"
+#include "face/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 <ndn-cxx/util/random.hpp>
 #include <ndn-cxx/management/nfd-strategy-choice.hpp>
 
-#include "tests/test-common.hpp"
-#include "validation-common.hpp"
-
 namespace nfd {
 namespace tests {
 
-NFD_LOG_INIT("MgmtStrategyChoiceManager");
-
-class StrategyChoiceManagerFixture : protected BaseFixture
+class StrategyChoiceManagerFixture : public ManagerCommonFixture
 {
 public:
-
   StrategyChoiceManagerFixture()
     : m_strategyChoice(m_forwarder.getStrategyChoice())
-    , m_face(make_shared<InternalFace>())
-    , m_manager(m_strategyChoice, m_face, m_keyChain)
-    , m_callbackFired(false)
+    , m_manager(m_strategyChoice, m_dispatcher, m_validator)
   {
-    m_strategyChoice.install(make_shared<DummyStrategy>(ref(m_forwarder),
-                                                        "/localhost/nfd/strategy/test-strategy-a"));
-    m_strategyChoice.insert("ndn:/", "/localhost/nfd/strategy/test-strategy-a");
+    setTopPrefixAndPrivilege("/localhost/nfd", "strategy-choice");
   }
 
-  virtual
-  ~StrategyChoiceManagerFixture()
-  {
-
-  }
-
+public:
   void
-  validateControlResponseCommon(const Data& response,
-                                const Name& expectedName,
-                                uint32_t expectedCode,
-                                const std::string& expectedText,
-                                ControlResponse& control)
+  installStrategy(const Name& strategy)
   {
-    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);
+    m_strategyChoice.install(make_shared<DummyStrategy>(ref(m_forwarder), strategy));
   }
 
-  void
-  validateControlResponse(const Data& response,
-                          const Name& expectedName,
-                          uint32_t expectedCode,
-                          const std::string& expectedText)
+  const Name&
+  findStrategy(const Name& name)
   {
-    ControlResponse control;
-    validateControlResponseCommon(response, expectedName,
-                                  expectedCode, expectedText, control);
-
-    if (!control.getBody().empty())
-      {
-        BOOST_FAIL("found unexpected control response body");
-      }
+    return m_strategyChoice.findEffectiveStrategy(name).getName();
   }
 
-  void
-  validateControlResponse(const Data& response,
-                          const Name& expectedName,
-                          uint32_t expectedCode,
-                          const std::string& expectedText,
-                          const Block& expectedBody)
+  ControlParameters
+  makeParameters(const Name& name, const Name& strategy)
   {
-    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);
-
-  }
-
-  void
-  validateList(const Data& data, const ndn::nfd::StrategyChoice& expectedChoice)
-  {
-    m_callbackFired = true;
-    ndn::nfd::StrategyChoice choice(data.getContent().blockFromValue());
-    BOOST_CHECK_EQUAL(choice.getStrategy(), expectedChoice.getStrategy());
-    BOOST_CHECK_EQUAL(choice.getName(), expectedChoice.getName());
-  }
-
-  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);
+    return ControlParameters().setName(name).setStrategy(strategy);
   }
 
 protected:
-  Forwarder m_forwarder;
   StrategyChoice& m_strategyChoice;
-  shared_ptr<InternalFace> m_face;
   StrategyChoiceManager m_manager;
-  ndn::KeyChain m_keyChain;
-
-private:
-  bool m_callbackFired;
 };
 
-class AllStrategiesFixture : public StrategyChoiceManagerFixture
+BOOST_FIXTURE_TEST_SUITE(Mgmt, StrategyChoiceManagerFixture)
+BOOST_AUTO_TEST_SUITE(TestStrategyChoiceManager)
+
+BOOST_AUTO_TEST_CASE(SetStrategy)
+{
+  auto testSetStrategy = [this] (const ControlParameters& parameters) -> Name {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", parameters);
+    receiveInterest(command);
+    return command->getName();
+  };
+
+  installStrategy("/localhost/nfd/strategy/test-strategy-a");
+  installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%01"); // version 1
+  installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // version 2
+
+  auto parametersA  = makeParameters("test", "/localhost/nfd/strategy/test-strategy-a");
+  auto parametersB  = makeParameters("test", "/localhost/nfd/strategy/test-strategy-b");
+  auto parametersC1 = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c/%FD%01");
+  auto parametersC  = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c");
+
+  auto commandNameA = testSetStrategy(parametersA); // succeed
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandNameA, makeResponse(200, "OK", parametersA)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a");
+
+  auto commandNameB = testSetStrategy(parametersB); // not installed
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandNameB, ControlResponse(504, "Unsupported strategy")),
+                    CheckResponseResult::OK);
+
+  auto commandNameC1 = testSetStrategy(parametersC1); // specified version
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandNameC1, makeResponse(200, "OK", parametersC1)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%01");
+
+  auto commandNameC = testSetStrategy(parametersC); // latest version
+  parametersC.setStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // change to latest
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandNameC, makeResponse(200, "OK", parametersC)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%02");
+}
+
+BOOST_AUTO_TEST_CASE(UnsetStrategy)
+{
+  auto testUnsetStrategy = [this] (const ControlParameters& parameters) -> Name {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", parameters);
+    receiveInterest(command);
+    return command->getName();
+  };
+
+  installStrategy("/localhost/nfd/strategy/test-strategy-a");
+  installStrategy("/localhost/nfd/strategy/test-strategy-b");
+  installStrategy("/localhost/nfd/strategy/test-strategy-c");
+
+  BOOST_CHECK(m_strategyChoice.insert("ndn:/", "/localhost/nfd/strategy/test-strategy-a")); // root
+  BOOST_CHECK(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b")); // test
+  BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a");
+
+  auto parametersRoot = ControlParameters().setName("ndn:/"); // root prefix
+  auto parametersNone = ControlParameters().setName("/none"); // no such entry
+  auto parametersTest = ControlParameters().setName("/test"); // has such entry
+
+  BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // root
+  auto commandRootName = testUnsetStrategy(parametersRoot);
+  auto expectedResponse = ControlResponse(400, "failed in validating parameters");
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandRootName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // keep as root
+
+  BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
+  auto commandNoneName = testUnsetStrategy(parametersNone);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandNoneName, makeResponse(200, "OK", parametersNone)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
+
+  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-b"); // self
+  auto commandTestName = testUnsetStrategy(parametersTest);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandTestName, makeResponse(200, "OK", parametersTest)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a"); // parent
+}
+
+// @todo Remove when ndn::nfd::StrategyChoice implements operator!= and operator<<
+class StrategyChoice : public ndn::nfd::StrategyChoice
 {
 public:
-  AllStrategiesFixture()
+  StrategyChoice() = default;
+
+  StrategyChoice(const ndn::nfd::StrategyChoice& entry)
+    : ndn::nfd::StrategyChoice(entry)
   {
-    m_strategyChoice.install(make_shared<DummyStrategy>(ref(m_forwarder),
-                                                        "/localhost/nfd/strategy/test-strategy-b"));
-
-    const Name strategyCVersion1("/localhost/nfd/strategy/test-strategy-c/%FD%01");
-    m_strategyChoice.install(make_shared<DummyStrategy>(ref(m_forwarder),
-                                                        strategyCVersion1));
-
-    const Name strategyCVersion2("/localhost/nfd/strategy/test-strategy-c/%FD%02");
-    m_strategyChoice.install(make_shared<DummyStrategy>(ref(m_forwarder),
-                                                        strategyCVersion2));
-  }
-
-  virtual
-  ~AllStrategiesFixture()
-  {
-
   }
 };
 
-template <typename T> class AuthorizedCommandFixture : public CommandFixture<T>
+bool
+operator!=(const StrategyChoice& left, const StrategyChoice& right)
 {
-public:
-  AuthorizedCommandFixture()
-  {
-    const std::string regex = "^<localhost><nfd><strategy-choice>";
-    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
+  return left.getName() != right.getName() || left.getStrategy() != right.getStrategy();
+}
+
+std::ostream&
+operator<<(std::ostream &os, const StrategyChoice& entry)
+{
+  os << "[ " << entry.getName() << ", " << entry.getStrategy() << " ]";
+  return os;
+}
+
+BOOST_AUTO_TEST_CASE(ListChoices)
+{
+  size_t nPreInsertedStrategies = m_strategyChoice.size(); // the best-route strategy
+  std::set<Name> actualNames, actualStrategies;
+  for (auto&& entry : m_strategyChoice) {
+    actualNames.insert(entry.getPrefix());
+    actualStrategies.insert(entry.getStrategyName());
   }
 
-  virtual
-  ~AuthorizedCommandFixture()
-  {
-
+  size_t nEntries = 1024;
+  for (size_t i = 0 ; i < nEntries ; i++) {
+    auto name = Name("test-name").appendSegment(i);
+    auto strategy = Name("test-strategy").appendSegment(ndn::random::generateWord64());
+    auto entry = ndn::nfd::StrategyChoice().setName(name).setStrategy(strategy);
+    actualNames.insert(name);
+    actualStrategies.insert(strategy);
+    installStrategy(strategy);
+    m_strategyChoice.insert(name, strategy);
   }
-};
+  nEntries += nPreInsertedStrategies;
 
-BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoiceManager,
-                         AuthorizedCommandFixture<AllStrategiesFixture>)
+  receiveInterest(makeInterest("/localhost/nfd/strategy-choice/list"));
 
-BOOST_FIXTURE_TEST_CASE(ShortName, AllStrategiesFixture)
-{
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), nEntries);
 
-  getFace()->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
+  std::vector<StrategyChoice> receivedRecords, expectedRecords;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
 
-  getFace()->sendInterest(*command);
-  g_io.run_one();
+    StrategyChoice decodedEntry;
+    BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
+    receivedRecords.push_back(decodedEntry);
 
-  BOOST_REQUIRE(didCallbackFire());
-}
+    actualNames.erase(decodedEntry.getName());
+    actualStrategies.erase(decodedEntry.getStrategy());
 
-BOOST_FIXTURE_TEST_CASE(MalformedCommmand, AllStrategiesFixture)
-{
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
+    auto result = m_strategyChoice.get(decodedEntry.getName());
+    BOOST_REQUIRE(result.first);
 
-  getFace()->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command, encodedParameters] (const Data& response) {
-    this->validateControlResponse(response, 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(SetStrategySpecifiedVersion)
-{
-  ControlParameters parameters;
-  parameters.setName("/test");
-  parameters.setStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%01");
-
-  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.connect([this, command, encodedParameters] (const Data& response) {
-    this->validateControlResponse(response, 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-c/%FD%01");
-}
-
-BOOST_AUTO_TEST_CASE(SetStrategyLatestVersion)
-{
-  ControlParameters parameters;
-  parameters.setName("/test");
-  parameters.setStrategy("/localhost/nfd/strategy/test-strategy-c");
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/strategy-choice");
-  commandName.append("set");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-
-  ControlParameters responseParameters;
-  responseParameters.setName("/test");
-  responseParameters.setStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02");
-
-  getFace()->onReceiveData.connect([this, command, responseParameters] (const Data& response) {
-    this->validateControlResponse(response, command->getName(),
-                                  200, "Success", responseParameters.wireEncode());
-  });
-
-  getManager().onValidatedStrategyChoiceRequest(command);
-
-  BOOST_REQUIRE(didCallbackFire());
-  fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
-  BOOST_REQUIRE_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-c/%FD%02");
-}
-
-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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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()
-  {
-
+    auto record = StrategyChoice().setName(decodedEntry.getName()).setStrategy(result.second);
+    expectedRecords.push_back(record);
   }
 
-  virtual
-  ~DefaultStrategyOnlyFixture()
-  {
+  BOOST_CHECK_EQUAL(actualNames.size(), 0);
+  BOOST_CHECK_EQUAL(actualStrategies.size(), 0);
 
-  }
-};
-
-
-/// \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.connect([this, command, encodedParameters] (const Data& response) {
-    this->validateControlResponse(response, 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_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
+                                expectedRecords.begin(), expectedRecords.end());
 }
 
-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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, 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_CASE(Publish)
-{
-  Name commandName("/localhost/nfd/strategy-choice/list");
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-
-  ndn::nfd::StrategyChoice expectedChoice;
-  expectedChoice.setStrategy("/localhost/nfd/strategy/test-strategy-a");
-  expectedChoice.setName("/");
-
-  getFace()->onReceiveData.connect(bind(&StrategyChoiceManagerFixture::validateList,
-                                        this, _1, expectedChoice));
-
-  m_manager.onStrategyChoiceRequest(*command);
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
 
 } // namespace tests
 } // namespace nfd
diff --git a/tests/daemon/mgmt/strategy-choice-publisher.t.cpp b/tests/daemon/mgmt/strategy-choice-publisher.t.cpp
deleted file mode 100644
index 8f98cb5..0000000
--- a/tests/daemon/mgmt/strategy-choice-publisher.t.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  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,
- *                           The University of Memphis.
- *
- * 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_STRATEGY_CHOICE_PUBLISHER_HPP
-#define NFD_TESTS_NFD_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
-
-#include "mgmt/strategy-choice-publisher.hpp"
-#include "mgmt/app-face.hpp"
-#include "mgmt/internal-face.hpp"
-#include "fw/forwarder.hpp"
-#include "../fw/dummy-strategy.hpp"
-
-#include "tests/test-common.hpp"
-
-#include <ndn-cxx/management/nfd-strategy-choice.hpp>
-
-namespace nfd {
-namespace tests {
-
-class StrategyChoicePublisherFixture : BaseFixture
-{
-public:
-
-  StrategyChoicePublisherFixture()
-    : m_strategyChoice(m_forwarder.getStrategyChoice())
-    , m_face(make_shared<InternalFace>())
-    , m_publisher(m_strategyChoice, *m_face, "/localhost/nfd/strategy-choice/list", m_keyChain)
-    , STRATEGY_A(make_shared<DummyStrategy>(boost::ref(m_forwarder),
-                                            "/localhost/nfd/strategy/dummy-strategy-a"))
-    , STRATEGY_B(make_shared<DummyStrategy>(boost::ref(m_forwarder),
-                                            "/localhost/nfd/strategy/dummy-strategy-b"))
-    , m_finished(false)
-  {
-    m_strategyChoice.install(STRATEGY_A);
-    m_strategyChoice.install(STRATEGY_B);
-
-    ndn::nfd::StrategyChoice expectedRootEntry;
-    expectedRootEntry.setStrategy(STRATEGY_A->getName());
-    expectedRootEntry.setName("/");
-
-    m_strategyChoice.insert("/", STRATEGY_A->getName());
-    m_expectedEntries["/"] = expectedRootEntry;
-  }
-
-  void
-  validatePublish(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 Strategy Choice entries in a single Content TLV for easy parsing
-    m_buffer.prependVarNumber(m_buffer.size());
-    m_buffer.prependVarNumber(tlv::Content);
-
-    ndn::Block parser(m_buffer.buf(), m_buffer.size());
-    parser.parse();
-
-    BOOST_REQUIRE_EQUAL(parser.elements_size(), m_expectedEntries.size());
-
-    for (Block::element_const_iterator i = parser.elements_begin();
-         i != parser.elements_end();
-         ++i)
-      {
-        if (i->type() != ndn::tlv::nfd::StrategyChoice)
-          {
-            BOOST_FAIL("expected StrategyChoice, got type #" << i->type());
-          }
-
-        ndn::nfd::StrategyChoice entry(*i);
-
-        std::map<std::string, ndn::nfd::StrategyChoice>::const_iterator expectedEntryPos =
-          m_expectedEntries.find(entry.getName().toUri());
-
-        BOOST_REQUIRE(expectedEntryPos != m_expectedEntries.end());
-        const ndn::nfd::StrategyChoice& expectedEntry = expectedEntryPos->second;
-
-        BOOST_CHECK_EQUAL(entry.getStrategy(), expectedEntry.getStrategy());
-        BOOST_CHECK_EQUAL(entry.getName(), expectedEntry.getName());
-
-        m_matchedEntries.insert(entry.getName().toUri());
-      }
-
-    BOOST_CHECK_EQUAL(m_matchedEntries.size(), m_expectedEntries.size());
-
-    m_finished = true;
-  }
-
-protected:
-  Forwarder m_forwarder;
-  StrategyChoice& m_strategyChoice;
-  shared_ptr<InternalFace> m_face;
-  StrategyChoicePublisher m_publisher;
-
-  shared_ptr<DummyStrategy> STRATEGY_A;
-  shared_ptr<DummyStrategy> STRATEGY_B;
-
-  ndn::EncodingBuffer m_buffer;
-
-  std::map<std::string, ndn::nfd::StrategyChoice> m_expectedEntries;
-  std::set<std::string> m_matchedEntries;
-
-  bool m_finished;
-
-  ndn::KeyChain m_keyChain;
-};
-
-
-
-BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoicePublisher, StrategyChoicePublisherFixture)
-
-BOOST_AUTO_TEST_CASE(Publish)
-{
-  m_strategyChoice.insert("/test/a", STRATEGY_A->getName());
-  m_strategyChoice.insert("/test/b", STRATEGY_B->getName());
-
-  ndn::nfd::StrategyChoice expectedEntryA;
-  expectedEntryA.setStrategy(STRATEGY_A->getName());
-  expectedEntryA.setName("/test/a");
-
-  ndn::nfd::StrategyChoice expectedEntryB;
-  expectedEntryB.setStrategy(STRATEGY_B->getName());
-  expectedEntryB.setName("/test/b");
-
-  m_expectedEntries["/test/a"] = expectedEntryA;
-  m_expectedEntries["/test/b"] = expectedEntryB;
-
-  m_face->onReceiveData.connect(bind(&StrategyChoicePublisherFixture::validatePublish, this, _1));
-
-  m_publisher.publish();
-  BOOST_REQUIRE(m_finished);
-}
-
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nfd
-
-#endif // NFD_TESTS_NFD_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
diff --git a/tests/daemon/mgmt/validation-common.cpp b/tests/daemon/mgmt/validation-common.cpp
deleted file mode 100644
index 6065c27..0000000
--- a/tests/daemon/mgmt/validation-common.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- 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
deleted file mode 100644
index f8b1367..0000000
--- a/tests/daemon/mgmt/validation-common.hpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/* -*- 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-cxx/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
