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
deleted file mode 100644
index db3b92f..0000000
--- a/daemon/mgmt/face-manager.cpp
+++ /dev/null
@@ -1,1199 +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-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"
-
-#ifdef HAVE_UNIX_SOCKETS
-#include "face/unix-stream-factory.hpp"
-#endif // HAVE_UNIX_SOCKETS
-
-#ifdef HAVE_LIBPCAP
-#include "face/ethernet-factory.hpp"
-#include "face/ethernet-face.hpp"
-#endif // HAVE_LIBPCAP
-
-#ifdef HAVE_WEBSOCKET
-#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)
-  , 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));
-}
-
-FaceManager::~FaceManager()
-{
-
-}
-
-void
-FaceManager::setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("face_system",
-                               bind(&FaceManager::onConfig, this, _1, _2, _3));
-}
-
-
-void
-FaceManager::onConfig(const ConfigSection& configSection,
-                      bool isDryRun,
-                      const std::string& filename)
-{
-  bool hasSeenUnix = false;
-  bool hasSeenTcp = false;
-  bool hasSeenUdp = false;
-  bool hasSeenEther = false;
-  bool hasSeenWebSocket = false;
-
-  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;
-
-          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
-FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRun)
-{
-  // ; the unix section contains settings of Unix stream faces and channels
-  // unix
-  // {
-  //   path /var/run/nfd.sock ; Unix stream listener path
-  // }
-
-#if defined(HAVE_UNIX_SOCKETS)
-
-  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"));
-        }
-    }
-
-  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);
-
-          // if (static_cast<bool>(unixChannel))
-          //   {
-          //     return;
-          //   }
-        }
-
-      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));
-    }
-#else
-  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without Unix sockets support, "
-                                          "cannot process \"unix\" section"));
-#endif // HAVE_UNIX_SOCKETS
-
-}
-
-void
-FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun)
-{
-  // ; the tcp section contains settings of TCP faces and channels
-  // tcp
-  // {
-  //   listen yes ; set to 'no' to disable TCP listener, default 'yes'
-  //   port 6363 ; TCP listener port number
-  // }
-
-  std::string port = "6363";
-  bool needToListen = true;
-  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"));
-        }
-    }
-
-  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;
-        }
-
-      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));
-        }
-    }
-}
-
-void
-FaceManager::processSectionUdp(const ConfigSection& configSection,
-                               bool isDryRun,
-                               const std::vector<NetworkInterfaceInfo>& nicList)
-{
-  // ; the udp section contains settings of UDP faces and channels
-  // udp
-  // {
-  //   port 6363 ; UDP unicast port number
-  //   idle_timeout 600 ; idle time (seconds) before closing a UDP unicast face
-  //   keep_alive_interval 25 ; interval (seconds) between keep-alive refreshes
-
-  //   ; NFD creates one UDP multicast face per NIC
-  //   mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
-  //   mcast_port 56363 ; UDP multicast port number
-  //   mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
-  // }
-
-  std::string port = "6363";
-  bool enableV4 = true;
-  bool enableV6 = true;
-  size_t timeout = 600;
-  size_t keepAliveInterval = 25;
-  bool useMcast = true;
-  std::string mcastGroup = "224.0.23.170";
-  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"]);
-      }
-      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);
-                }
-            }
-
-          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;
-            }
-#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);
-            }
-
-          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();
-            }
-        }
-    }
-}
-
-void
-FaceManager::processSectionEther(const ConfigSection& configSection,
-                                 bool isDryRun,
-                                 const std::vector<NetworkInterfaceInfo>& nicList)
-{
-  // ; the ether section contains settings of Ethernet faces and channels
-  // ether
-  // {
-  //   ; NFD creates one Ethernet multicast face per NIC
-  //   mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
-  //   mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
-  // }
-
-#if defined(HAVE_LIBPCAP)
-  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");
-        }
-
-      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 (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);
-
-                      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();
-            }
-        }
-      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();
-            }
-        }
-    }
-#else
-  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without libpcap, cannot "
-                                          "process \"ether\" section"));
-#endif // HAVE_LIBPCAP
-}
-
-void
-FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool isDryRun)
-{
-  // ; the websocket section contains settings of WebSocket faces and channels
-  // websocket
-  // {
-  //   listen yes ; set to 'no' to disable WebSocket listener, default 'yes'
-  //   port 9696 ; WebSocket listener port number
-  //   enable_v4 yes ; set to 'no' to disable listening on IPv4 socket, default 'yes'
-  //   enable_v6 yes ; set to 'no' to disable listening on IPv6 socket, default 'yes'
-  // }
-
-#if defined(HAVE_WEBSOCKET)
-
-  std::string port = "9696";
-  bool needToListen = true;
-  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"));
-        }
-    }
-
-  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;
-        }
-
-      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)
-{
-  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
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
deleted file mode 100644
index 74dc0dd..0000000
--- a/daemon/mgmt/face-manager.hpp
+++ /dev/null
@@ -1,250 +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_MANAGER_HPP
-#define NFD_DAEMON_MGMT_FACE_MANAGER_HPP
-
-#include "common.hpp"
-#include "core/notification-stream.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>
-
-namespace nfd {
-
-const std::string FACE_MANAGER_PRIVILEGE = "faces";
-
-class ConfigFile;
-class Face;
-class FaceTable;
-class LocalFace;
-class NetworkInterfaceInfo;
-class ProtocolFactory;
-
-class FaceManager : public ManagerBase
-{
-public:
-  class Error : public ManagerBase::Error
-  {
-  public:
-    Error(const std::string& what) : ManagerBase::Error(what) {}
-  };
-
-  /**
-   * \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
-   */
-  void
-  setConfigFile(ConfigFile& configFile);
-
-  void
-  onFaceRequest(const Interest& request);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  listFaces(const Interest& request);
-
-  void
-  listChannels(const Interest& request);
-
-  void
-  listQueriedFaces(const Interest& request);
-
-  shared_ptr<ProtocolFactory>
-  findFactory(const std::string& protocol);
-
-PROTECTED_WITH_TESTS_ELSE_PRIVATE:
-  void
-  onValidatedFaceRequest(const shared_ptr<const Interest>& request);
-
-  VIRTUAL_WITH_TESTS void
-  createFace(const Interest& request,
-             ControlParameters& parameters);
-
-  VIRTUAL_WITH_TESTS void
-  destroyFace(const Interest& request,
-              ControlParameters& parameters);
-
-  VIRTUAL_WITH_TESTS bool
-  extractLocalControlParameters(const Interest& request,
-                                ControlParameters& parameters,
-                                ControlCommand& command,
-                                shared_ptr<LocalFace>& outFace,
-                                LocalControlFeature& outFeature);
-
-  VIRTUAL_WITH_TESTS void
-  enableLocalControl(const Interest& request,
-                     ControlParameters& parambeters);
-
-  VIRTUAL_WITH_TESTS void
-  disableLocalControl(const Interest& request,
-                      ControlParameters& parameters);
-
-  void
-  ignoreUnsignedVerb(const Interest& request);
-
-  void
-  addCreatedFaceToForwarder(const shared_ptr<Face>& newFace);
-
-  void
-  onCreated(const Name& requestName,
-            ControlParameters& parameters,
-            const shared_ptr<Face>& newFace);
-
-  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);
-
-  void
-  processSectionUnix(const ConfigSection& configSection, bool isDryRun);
-
-  void
-  processSectionTcp(const ConfigSection& configSection, bool isDryRun);
-
-  void
-  processSectionUdp(const ConfigSection& configSection,
-                    bool isDryRun,
-                    const std::vector<NetworkInterfaceInfo>& nicList);
-
-  void
-  processSectionEther(const ConfigSection& configSection,
-                      bool isDryRun,
-                      const std::vector<NetworkInterfaceInfo>& nicList);
-
-  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);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef std::map<std::string/*protocol*/, shared_ptr<ProtocolFactory>> FactoryMap;
-  FactoryMap m_factories;
-
-private:
-  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
deleted file mode 100644
index 3db26e7..0000000
--- a/daemon/mgmt/fib-manager.cpp
+++ /dev/null
@@ -1,284 +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 "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>
-
-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)
-  , 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));
-}
-
-FibManager::~FibManager()
-{
-
-}
-
-void
-FibManager::onFibRequest(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(&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;
-    }
-
-  const Name& prefix = parameters.getName();
-  FaceId faceId = parameters.getFaceId();
-  uint64_t cost = parameters.getCost();
-
-  NFD_LOG_TRACE("add-nexthop prefix: " << prefix
-                << " 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;
-
-      entry->addNextHop(nextHopFace, 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");
-    }
-}
-
-void
-FibManager::removeNextHop(ControlParameters& parameters,
-                          ControlResponse& response)
-{
-  ndn::nfd::FibRemoveNextHopCommand command;
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("remove-nexthop result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
-
-  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());
-
-          if (!entry->hasNextHops())
-            {
-              m_managedFib.erase(*entry);
-            }
-        }
-      else
-        {
-          NFD_LOG_DEBUG("remove-nexthop result: OK, but entry for face id "
-                        << parameters.getFaceId() << " not found");
-        }
-    }
-  else
-    {
-      NFD_LOG_DEBUG("remove-nexthop result: OK, but face id "
-                    << parameters.getFaceId() << " not found");
-    }
-
-  setResponse(response, 200, "Success", parameters.wireEncode());
-}
-
-void
-FibManager::listEntries(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps < LIST_COMMAND_NCOMPS ||
-      !LIST_COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  m_fibEnumerationPublisher.publish();
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
deleted file mode 100644
index c8c21ea..0000000
--- a/daemon/mgmt/fib-manager.hpp
+++ /dev/null
@@ -1,114 +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_MANAGER_HPP
-#define NFD_DAEMON_MGMT_FIB_MANAGER_HPP
-
-#include "common.hpp"
-#include "mgmt/manager-base.hpp"
-#include "mgmt/fib-enumeration-publisher.hpp"
-
-namespace nfd {
-
-class Face;
-class Forwarder;
-class Fib;
-
-const std::string FIB_PRIVILEGE = "fib"; // config file privilege name
-
-class FibManager : public ManagerBase
-{
-public:
-
-  FibManager(Fib& fib,
-             function<shared_ptr<Face>(FaceId)> getFace,
-             shared_ptr<InternalFace> face,
-             ndn::KeyChain& keyChain);
-
-  virtual
-  ~FibManager();
-
-  void
-  onFibRequest(const Interest& request);
-
-private:
-
-  void
-  onValidatedFibRequest(const shared_ptr<const Interest>& request);
-
-  void
-  addNextHop(ControlParameters& parameters,
-             ControlResponse& response);
-
-  void
-  removeNextHop(ControlParameters& parameters,
-                ControlResponse& response);
-
-  void
-  listEntries(const Interest& request);
-
-private:
-
-  Fib& m_managedFib;
-  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
-
-#endif // NFD_DAEMON_MGMT_FIB_MANAGER_HPP
diff --git a/daemon/mgmt/manager-base.cpp b/daemon/mgmt/manager-base.cpp
deleted file mode 100644
index cf75d04..0000000
--- a/daemon/mgmt/manager-base.cpp
+++ /dev/null
@@ -1,144 +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 "manager-base.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("ManagerBase");
-
-ManagerBase::ManagerBase(shared_ptr<InternalFace> face, const std::string& privilege,
-                         ndn::KeyChain& keyChain)
-  : m_face(face)
-  , m_keyChain(keyChain)
-{
-  face->getValidator().addSupportedPrivilege(privilege);
-}
-
-ManagerBase::~ManagerBase()
-{
-
-}
-
-bool
-ManagerBase::extractParameters(const Name::Component& parameterComponent,
-                               ControlParameters& extractedParameters)
-{
-  try
-    {
-      Block rawParameters = parameterComponent.blockFromValue();
-      extractedParameters.wireDecode(rawParameters);
-    }
-  catch (const tlv::Error&)
-    {
-      return false;
-    }
-
-  NFD_LOG_DEBUG("Parameters parsed OK");
-  return true;
-}
-
-void
-ManagerBase::sendResponse(const Name& name,
-                          uint32_t code,
-                          const std::string& text)
-{
-  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");
-}
-
-
-} // namespace nfd
diff --git a/daemon/mgmt/manager-base.hpp b/daemon/mgmt/manager-base.hpp
deleted file mode 100644
index 1611615..0000000
--- a/daemon/mgmt/manager-base.hpp
+++ /dev/null
@@ -1,169 +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_MANAGER_BASE_HPP
-#define NFD_DAEMON_MGMT_MANAGER_BASE_HPP
-
-#include "common.hpp"
-
-#include "mgmt/command-validator.hpp"
-#include "mgmt/internal-face.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::nfd::ControlCommand;
-using ndn::nfd::ControlResponse;
-using ndn::nfd::ControlParameters;
-
-class InternalFace;
-
-class ManagerBase
-{
-public:
-
-  struct Error : public std::runtime_error
-  {
-    Error(const std::string& what) : std::runtime_error(what) {}
-  };
-
-  ManagerBase(shared_ptr<InternalFace> face,
-              const std::string& privilege,
-              ndn::KeyChain& keyChain);
-
-  virtual
-  ~ManagerBase();
-
-  void
-  onCommandValidationFailed(const shared_ptr<const Interest>& command,
-                            const std::string& error);
-
-protected:
-
-  static bool
-  extractParameters(const Name::Component& parameterComponent,
-                    ControlParameters& extractedParameters);
-
-  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);
-
-  void
-  sendResponse(const Name& name,
-               const ControlResponse& response);
-
-  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;
-};
-
-inline void
-ManagerBase::setResponse(ControlResponse& response,
-                         uint32_t code,
-                         const std::string& text)
-{
-  response.setCode(code);
-  response.setText(text);
-}
-
-inline void
-ManagerBase::setResponse(ControlResponse& response,
-                         uint32_t code,
-                         const std::string& text,
-                         const Block& body)
-{
-  setResponse(response, code, text);
-  response.setBody(body);
-}
-
-inline void
-ManagerBase::addInterestRule(const std::string& regex,
-                             const ndn::IdentityCertificate& certificate)
-{
-  m_face->getValidator().addInterestRule(regex, certificate);
-}
-
-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
deleted file mode 100644
index 4f2728c..0000000
--- a/daemon/mgmt/strategy-choice-manager.cpp
+++ /dev/null
@@ -1,214 +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-manager.hpp"
-#include "table/strategy-choice.hpp"
-#include "core/logger.hpp"
-#include "mgmt/app-face.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)
-  , m_strategyChoice(strategyChoice)
-  , m_listPublisher(strategyChoice, *m_face, LIST_DATASET_PREFIX, keyChain)
-{
-  face->setInterestFilter("/localhost/nfd/strategy-choice",
-                          bind(&StrategyChoiceManager::onStrategyChoiceRequest, this, _2));
-}
-
-StrategyChoiceManager::~StrategyChoiceManager()
-{
-
-}
-
-void
-StrategyChoiceManager::onStrategyChoiceRequest(const Interest& request)
-{
-  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.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");
-    }
-}
-
-void
-StrategyChoiceManager::unsetStrategy(ControlParameters& parameters,
-                                     ControlResponse& response)
-{
-  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());
-}
-
-
-
-} // namespace nfd
diff --git a/daemon/mgmt/strategy-choice-manager.hpp b/daemon/mgmt/strategy-choice-manager.hpp
deleted file mode 100644
index c2ccd53..0000000
--- a/daemon/mgmt/strategy-choice-manager.hpp
+++ /dev/null
@@ -1,91 +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_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>
-
-namespace nfd {
-
-const std::string STRATEGY_CHOICE_PRIVILEGE = "strategy-choice";
-
-class 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);
-
-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
-
-#endif // NFD_DAEMON_MGMT_STRATEGY_CHOICE_MANAGER_HPP
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 d880ebb..1041643 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -32,10 +32,10 @@
 #include "fw/forwarder.hpp"
 #include "face/null-face.hpp"
 #include "mgmt/internal-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/fib-manager.hpp"
+// #include "mgmt/face-manager.hpp"
+// #include "mgmt/strategy-choice-manager.hpp"
+// #include "mgmt/status-server.hpp"
 #include "mgmt/general-config-section.hpp"
 #include "mgmt/tables-config-section.hpp"
 
@@ -47,14 +47,14 @@
 
 Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
   : m_configFile(configFile)
-  , m_keyChain(keyChain)
+  // , m_keyChain(keyChain)
   , m_networkMonitor(getGlobalIoService())
 {
 }
 
 Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
   : m_configSection(config)
-  , m_keyChain(keyChain)
+  // , m_keyChain(keyChain)
   , m_networkMonitor(getGlobalIoService())
 {
 }
@@ -129,16 +129,16 @@
 {
   m_internalFace = make_shared<InternalFace>();
 
-  m_fibManager.reset(new FibManager(m_forwarder->getFib(),
-                                    bind(&Forwarder::getFace, m_forwarder.get(), _1),
-                                    m_internalFace, m_keyChain));
+  // m_fibManager.reset(new FibManager(m_forwarder->getFib(),
+  //                                   bind(&Forwarder::getFace, m_forwarder.get(), _1),
+  //                                   m_internalFace, m_keyChain));
 
-  m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(), m_internalFace, m_keyChain));
+  // m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(), m_internalFace, m_keyChain));
 
-  m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
-                                                          m_internalFace, m_keyChain));
+  // m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
+  //                                                         m_internalFace, m_keyChain));
 
-  m_statusServer.reset(new StatusServer(m_internalFace, *m_forwarder, m_keyChain));
+  // m_statusServer.reset(new StatusServer(m_internalFace, *m_forwarder, m_keyChain));
 
   ConfigFile config(&ignoreRibAndLogSections);
   general::setConfigFile(config);
@@ -154,7 +154,7 @@
 
   m_forwarder->getFaceTable().addReserved(m_internalFace, FACEID_INTERNAL_FACE);
 
-  m_faceManager->setConfigFile(config);
+  // m_faceManager->setConfigFile(config);
 
   // parse config file
   if (!m_configFile.empty()) {
@@ -194,7 +194,7 @@
   tablesConfig.setConfigFile(config);
 
   m_internalFace->getValidator().setConfigFile(config);
-  m_faceManager->setConfigFile(config);
+  // m_faceManager->setConfigFile(config);
 
   if (!m_configFile.empty()) {
     config.parse(m_configFile, false);
@@ -209,7 +209,7 @@
 {
   // reload only face_system section of the config file to re-initialize multicast faces
   ConfigFile config(&ConfigFile::ignoreUnknownSection);
-  m_faceManager->setConfigFile(config);
+  // m_faceManager->setConfigFile(config);
 
   if (!m_configFile.empty()) {
     config.parse(m_configFile, false);
diff --git a/daemon/nfd.hpp b/daemon/nfd.hpp
index 4710554..acd3096 100644
--- a/daemon/nfd.hpp
+++ b/daemon/nfd.hpp
@@ -98,12 +98,12 @@
   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;
+  // unique_ptr<FibManager>            m_fibManager;
+  // unique_ptr<FaceManager>           m_faceManager;
+  // unique_ptr<StrategyChoiceManager> m_strategyChoiceManager;
+  // unique_ptr<StatusServer>          m_statusServer;
 
-  ndn::KeyChain&                    m_keyChain;
+  // ndn::KeyChain&                    m_keyChain;
 
   ndn::util::NetworkMonitor         m_networkMonitor;
   scheduler::ScopedEventId          m_reloadConfigEvent;
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.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
deleted file mode 100644
index 36e9e8a..0000000
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ /dev/null
@@ -1,1876 +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/face-manager.hpp"
-#include "mgmt/internal-face.hpp"
-#include "mgmt/face-status-publisher.hpp"
-
-#include "face/face.hpp"
-#include "../face/dummy-face.hpp"
-#include "fw/face-table.hpp"
-#include "fw/forwarder.hpp"
-#include "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/encoding/tlv.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
-{
-public:
-  FaceManagerFixture()
-    : m_manager(m_faceTable, m_face, m_testKeyChain)
-  {
-    m_manager.setConfigFile(m_config);
-  }
-
-  virtual
-  ~FaceManagerFixture()
-  {
-
-  }
-
-  void
-  parseConfig(const std::string configuration, bool isDryRun)
-  {
-    m_config.parse(configuration, isDryRun, "dummy-config");
-  }
-
-  FaceManager&
-  getManager()
-  {
-    return m_manager;
-  }
-
-  void
-  addInterestRule(const std::string& regex,
-                  ndn::IdentityCertificate& certificate)
-  {
-    m_manager.addInterestRule(regex, certificate);
-  }
-
-  bool
-  didFaceTableAddFire() const
-  {
-    return m_faceTable.didAddFire();
-  }
-
-  bool
-  didFaceTableGetFire() const
-  {
-    return m_faceTable.didGetFire();
-  }
-
-  void
-  resetFaceTable()
-  {
-    m_faceTable.reset();
-  }
-
-protected:
-  FaceManager m_manager;
-  ConfigFile m_config;
-};
-
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, FaceManagerFixture)
-
-bool
-isExpectedException(const ConfigFile::Error& error, const std::string& expectedMessage)
-{
-  if (error.what() != expectedMessage)
-    {
-      NFD_LOG_ERROR("expected: " << expectedMessage << "\tgot: " << error.what());
-    }
-  return error.what() == expectedMessage;
-}
-
-#ifdef HAVE_UNIX_SOCKETS
-
-BOOST_AUTO_TEST_CASE(TestProcessSectionUnix)
-{
-  const std::string CONFIG =
-    "face_system\n"
-    "{\n"
-    "  unix\n"
-    "  {\n"
-    "    path /tmp/nfd.sock\n"
-    "  }\n"
-    "}\n";
-  BOOST_TEST_CHECKPOINT("Calling parse");
-  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
-}
-
-BOOST_AUTO_TEST_CASE(TestProcessSectionUnixDryRun)
-{
-  const std::string CONFIG =
-    "face_system\n"
-    "{\n"
-    "  unix\n"
-    "  {\n"
-    "    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");
-  }
-
-  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(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");
-  }
-
-  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_CASE(ShortName)
-{
-  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");
-  });
-
-  getFace()->sendInterest(*command);
-  g_io.run_one();
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_AUTO_TEST_CASE(MalformedCommmand)
-{
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
-
-  getFace()->onReceiveData.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>
-{
-public:
-  AuthorizedCommandFixture()
-  {
-    const std::string regex = "^<localhost><nfd><faces>";
-    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
-  }
-
-  virtual
-  ~AuthorizedCommandFixture()
-  {
-
-  }
-};
-
-BOOST_FIXTURE_TEST_CASE(UnsupportedCommand, AuthorizedCommandFixture<FaceManagerFixture>)
-{
-  ControlParameters parameters;
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/faces");
-  commandName.append("unsupported");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  getFace()->onReceiveData.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
-{
-public:
-
-  ValidatedFaceRequestFixture()
-    : FaceManager(TestFaceTableFixture::m_faceTable, getFace(), m_testKeyChain),
-      m_createFaceFired(false),
-      m_destroyFaceFired(false)
-  {
-
-  }
-
-  virtual void
-  createFace(const Interest& request,
-             ControlParameters& parameters)
-  {
-    m_createFaceFired = true;
-  }
-
-  virtual void
-  destroyFace(const Interest& request,
-              ControlParameters& parameters)
-  {
-    m_destroyFaceFired = true;
-  }
-
-  virtual
-  ~ValidatedFaceRequestFixture()
-  {
-
-  }
-
-  bool
-  didCreateFaceFire() const
-  {
-    return m_createFaceFired;
-  }
-
-  bool
-  didDestroyFaceFire() const
-  {
-    return m_destroyFaceFired;
-  }
-
-private:
-  bool m_createFaceFired;
-  bool m_destroyFaceFired;
-};
-
-BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestBadOptionParse,
-                        AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
-{
-  Name commandName("/localhost/nfd/faces");
-  commandName.append("create");
-  commandName.append("NotReallyParameters");
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  getFace()->onReceiveData.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)
-  {
-  }
-
-  virtual
-  ~FaceTableFixture()
-  {
-  }
-
-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()
-
-} // 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
deleted file mode 100644
index 3a70619..0000000
--- a/tests/daemon/mgmt/face-manager/create-face.t.cpp
+++ /dev/null
@@ -1,449 +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/face-manager.hpp"
-#include "mgmt/internal-face.hpp"
-#include "fw/forwarder.hpp"
-
-#include "tests/test-common.hpp"
-
-#include <boost/property_tree/info_parser.hpp>
-
-namespace nfd {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, BaseFixture)
-
-BOOST_AUTO_TEST_SUITE(CreateFace)
-
-class FaceManagerNode
-{
-public:
-  FaceManagerNode(ndn::KeyChain& keyChain, const std::string& port = "6363")
-    : face(make_shared<InternalFace>())
-    , manager(forwarder.getFaceTable(), face, keyChain)
-  {
-    std::string basicConfig =
-      "face_system\n"
-      "{\n"
-      "  tcp\n"
-      "  {\n"
-      "    port " + port + "\n"
-      "  }\n"
-      "  udp\n"
-      "  {\n"
-      "    port " + port + "\n"
-      "  }\n"
-      "}\n"
-      "authorizations\n"
-      "{\n"
-      "  authorize\n"
-      "  {\n"
-      "    certfile any\n"
-      "    privileges\n"
-      "    {\n"
-      "      faces\n"
-      "    }\n"
-      "  }\n"
-      "}\n"
-      "\n";
-    std::istringstream input(basicConfig);
-    nfd::ConfigSection configSection;
-    boost::property_tree::read_info(input, configSection);
-
-    ConfigFile config;
-    manager.setConfigFile(config);
-    face->getValidator().setConfigFile(config);
-    config.parse(configSection, false, "dummy-config");
-  }
-
-  void
-  closeFaces()
-  {
-    std::vector<shared_ptr<Face>> facesToClose;
-    std::copy(forwarder.getFaceTable().begin(), forwarder.getFaceTable().end(),
-              std::back_inserter(facesToClose));
-    for (auto face : facesToClose) {
-      face->close();
-    }
-  }
-
-public:
-  Forwarder forwarder;
-  shared_ptr<InternalFace> face;
-  FaceManager manager;
-};
-
-class FaceManagerFixture : public UnitTestTimeFixture
-{
-public:
-  FaceManagerFixture()
-    : node1(keyChain, "16363")
-    , node2(keyChain, "26363")
-  {
-  }
-
-  ~FaceManagerFixture()
-  {
-    node1.closeFaces();
-    node2.closeFaces();
-    advanceClocks(time::milliseconds(1), 100);
-  }
-
-public:
-  ndn::KeyChain keyChain;
-  FaceManagerNode node1; // used to test FaceManager
-  FaceManagerNode node2; // acts as a remote endpoint
-};
-
-class TcpFaceOnDemand
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("tcp4://127.0.0.1:26363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
-  }
-};
-
-class TcpFacePersistent
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("tcp4://127.0.0.1:26363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-  }
-};
-
-class TcpFacePermanent
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("tcp4://127.0.0.1:26363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
-  }
-};
-
-class UdpFaceOnDemand
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("udp4://127.0.0.1:26363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
-  }
-};
-
-class UdpFacePersistent
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("udp4://127.0.0.1:26363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-  }
-};
-
-class UdpFacePermanent
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("udp4://127.0.0.1:26363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
-  }
-};
-
-class Success
-{
-public:
-  ControlResponse
-  getExpected()
-  {
-    return ControlResponse()
-      .setCode(200)
-      .setText("Success");
-  }
-};
-
-template<int CODE>
-class Failure
-{
-public:
-  ControlResponse
-  getExpected()
-  {
-    return ControlResponse()
-      .setCode(CODE)
-      .setText("Error"); // error description should not be checked
-  }
-};
-
-namespace mpl = boost::mpl;
-
-// pairs of CreateCommand and Success status
-typedef mpl::vector<mpl::pair<TcpFaceOnDemand, Failure<500>>,
-                    mpl::pair<TcpFacePersistent, Success>,
-                    mpl::pair<TcpFacePermanent, Failure<500>>,
-                    mpl::pair<UdpFaceOnDemand, Failure<500>>,
-                    mpl::pair<UdpFacePersistent, Success>,
-                    mpl::pair<UdpFacePermanent, Success>> Faces;
-
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerFixture)
-{
-  typedef typename T::first FaceType;
-  typedef typename T::second CreateResult;
-
-  Name commandName("/localhost/nfd/faces");
-  commandName.append("create");
-  commandName.append(FaceType().getParameters().wireEncode());
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  this->keyChain.sign(*command);
-
-  bool hasCallbackFired = false;
-  this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
-      if (!command->getName().isPrefixOf(response.getName())) {
-        return;
-      }
-
-      ControlResponse actual(response.getContent().blockFromValue());
-      ControlResponse expected(CreateResult().getExpected());
-      BOOST_CHECK_EQUAL(expected.getCode(), actual.getCode());
-      BOOST_MESSAGE(actual.getText());
-
-      if (actual.getBody().hasWire()) {
-        ControlParameters expectedParams(FaceType().getParameters());
-        ControlParameters actualParams(actual.getBody());
-
-        BOOST_CHECK_EQUAL(expectedParams.getUri(), actualParams.getUri());
-        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
-      }
-      hasCallbackFired = true;
-    });
-
-  this->node1.face->sendInterest(*command);
-  this->advanceClocks(time::milliseconds(1), 10);
-
-  BOOST_CHECK(hasCallbackFired);
-}
-
-
-typedef mpl::vector<// mpl::pair<mpl::pair<TcpFacePersistent, TcpFacePermanent>, TcpFacePermanent>, // no need to check now
-                    // mpl::pair<mpl::pair<TcpFacePermanent, TcpFacePersistent>, TcpFacePermanent>, // no need to check now
-                    mpl::pair<mpl::pair<UdpFacePersistent, UdpFacePermanent>, UdpFacePermanent>,
-                    mpl::pair<mpl::pair<UdpFacePermanent, UdpFacePersistent>, UdpFacePermanent>> FaceTransitions;
-
-
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFace, T, FaceTransitions, FaceManagerFixture)
-{
-  typedef typename T::first::first FaceType1;
-  typedef typename T::first::second FaceType2;
-  typedef typename T::second FinalFaceType;
-
-  {
-    // create face
-
-    Name commandName("/localhost/nfd/faces");
-    commandName.append("create");
-    commandName.append(FaceType1().getParameters().wireEncode());
-
-    shared_ptr<Interest> command(make_shared<Interest>(commandName));
-    this->keyChain.sign(*command);
-
-    this->node1.face->sendInterest(*command);
-    this->advanceClocks(time::milliseconds(1), 10);
-  }
-
-  //
-  {
-    // re-create face (= change face persistency)
-
-    Name commandName("/localhost/nfd/faces");
-    commandName.append("create");
-    commandName.append(FaceType2().getParameters().wireEncode());
-
-    shared_ptr<Interest> command(make_shared<Interest>(commandName));
-    this->keyChain.sign(*command);
-
-    bool hasCallbackFired = false;
-    this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
-        if (!command->getName().isPrefixOf(response.getName())) {
-          return;
-        }
-
-        ControlResponse actual(response.getContent().blockFromValue());
-        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
-
-        ControlParameters expectedParams(FinalFaceType().getParameters());
-        ControlParameters actualParams(actual.getBody());
-        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
-
-        hasCallbackFired = true;
-      });
-
-    this->node1.face->sendInterest(*command);
-    this->advanceClocks(time::milliseconds(1), 10);
-
-    BOOST_CHECK(hasCallbackFired);
-  }
-}
-
-
-// class TcpFace
-// {
-// public:
-//   ControlParameters
-//   getParameters()
-//   {
-//     return ControlParameters()
-//       .setUri("tcp4://127.0.0.1:16363")
-//       .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-//   }
-// };
-
-class UdpFace
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("udp4://127.0.0.1:16363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-  }
-};
-
-
-// Note that the transitions from on-demand TcpFace are intentionally not tested.
-// On-demand TcpFace has a remote endpoint with a randomized port number.  Normal face
-// creation operations will not need to create a face toward a remote port not listened by
-// a channel.
-
-typedef mpl::vector<mpl::pair<UdpFace, UdpFacePersistent>,
-                    mpl::pair<UdpFace, UdpFacePermanent>> OnDemandFaceTransitions;
-
-// need a slightly different logic to test transitions from OnDemand state
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFaceOnDemand, T, OnDemandFaceTransitions, FaceManagerFixture)
-{
-  typedef typename T::first  OtherNodeFace;
-  typedef typename T::second FaceType;
-
-  {
-    // create on-demand face
-
-    Name commandName("/localhost/nfd/faces");
-    commandName.append("create");
-    commandName.append(OtherNodeFace().getParameters().wireEncode());
-
-    shared_ptr<Interest> command(make_shared<Interest>(commandName));
-    this->keyChain.sign(*command);
-
-    ndn::util::signal::ScopedConnection connection =
-      this->node2.face->onReceiveData.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.getCode(), 200);
-          uint64_t faceId = ControlParameters(controlResponse.getBody()).getFaceId();
-          auto face = this->node2.forwarder.getFace(static_cast<FaceId>(faceId));
-
-          // to force creation of on-demand face
-          auto dummyInterest = make_shared<Interest>("/hello/world");
-          face->sendInterest(*dummyInterest);
-        });
-
-    this->node2.face->sendInterest(*command);
-    this->advanceClocks(time::milliseconds(1), 10);
-  }
-
-  // make sure there is on-demand face
-  bool onDemandFaceFound = false;
-  FaceUri onDemandFaceUri(FaceType().getParameters().getUri());
-  for (auto face : this->node1.forwarder.getFaceTable()) {
-    if (face->getRemoteUri() == onDemandFaceUri) {
-      onDemandFaceFound = true;
-      break;
-    }
-  }
-  BOOST_REQUIRE(onDemandFaceFound);
-
-  //
-  {
-    // re-create face (= change face persistency)
-
-    Name commandName("/localhost/nfd/faces");
-    commandName.append("create");
-    commandName.append(FaceType().getParameters().wireEncode());
-
-    shared_ptr<Interest> command(make_shared<Interest>(commandName));
-    this->keyChain.sign(*command);
-
-    bool hasCallbackFired = false;
-    this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
-        if (!command->getName().isPrefixOf(response.getName())) {
-          return;
-        }
-
-        ControlResponse actual(response.getContent().blockFromValue());
-        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
-
-        ControlParameters expectedParams(FaceType().getParameters());
-        ControlParameters actualParams(actual.getBody());
-        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
-
-        hasCallbackFired = true;
-      });
-
-    this->node1.face->sendInterest(*command);
-    this->advanceClocks(time::milliseconds(1), 10);
-
-    BOOST_CHECK(hasCallbackFired);
-  }
-}
-
-BOOST_AUTO_TEST_SUITE_END() // CreateFace
-
-BOOST_AUTO_TEST_SUITE_END() // MgmtFaceManager
-
-} // tests
-} // 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
deleted file mode 100644
index 82e70b9..0000000
--- a/tests/daemon/mgmt/fib-manager.t.cpp
+++ /dev/null
@@ -1,925 +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-manager.hpp"
-#include "table/fib.hpp"
-#include "table/fib-nexthop.hpp"
-#include "face/face.hpp"
-#include "mgmt/internal-face.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
-
-#include "validation-common.hpp"
-#include "tests/test-common.hpp"
-
-#include "fib-enumeration-publisher-common.hpp"
-
-namespace nfd {
-namespace tests {
-
-NFD_LOG_INIT("FibManagerTest");
-
-class FibManagerFixture : public FibEnumerationPublisherFixture
-{
-public:
-
-  virtual
-  ~FibManagerFixture()
-  {
-  }
-
-  shared_ptr<Face>
-  getFace(FaceId id)
-  {
-    if (id > 0 && static_cast<size_t>(id) <= m_faces.size())
-      {
-        return m_faces[id - 1];
-      }
-    NFD_LOG_DEBUG("No face found returning NULL");
-    return shared_ptr<DummyFace>();
-  }
-
-  void
-  addFace(shared_ptr<Face> face)
-  {
-    m_faces.push_back(face);
-  }
-
-  void
-  validateControlResponseCommon(const Data& response,
-                                const Name& expectedName,
-                                uint32_t expectedCode,
-                                const std::string& expectedText,
-                                ControlResponse& control)
-  {
-    m_callbackFired = true;
-    Block controlRaw = response.getContent().blockFromValue();
-
-    control.wireDecode(controlRaw);
-
-    // NFD_LOG_DEBUG("received control response"
-    //               << " Name: " << response.getName()
-    //               << " code: " << control.getCode()
-    //               << " text: " << control.getText());
-
-    BOOST_CHECK_EQUAL(response.getName(), expectedName);
-    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
-    BOOST_CHECK_EQUAL(control.getText(), expectedText);
-  }
-
-  void
-  validateControlResponse(const Data& response,
-                          const Name& expectedName,
-                          uint32_t expectedCode,
-                          const std::string& expectedText)
-  {
-    ControlResponse control;
-    validateControlResponseCommon(response, expectedName,
-                                  expectedCode, expectedText, control);
-
-    if (!control.getBody().empty())
-      {
-        BOOST_FAIL("found unexpected control response body");
-      }
-  }
-
-  void
-  validateControlResponse(const Data& response,
-                          const Name& expectedName,
-                          uint32_t expectedCode,
-                          const std::string& expectedText,
-                          const Block& expectedBody)
-  {
-    ControlResponse control;
-    validateControlResponseCommon(response, expectedName,
-                                  expectedCode, expectedText, control);
-
-    BOOST_REQUIRE(!control.getBody().empty());
-    BOOST_REQUIRE_EQUAL(control.getBody().value_size(), expectedBody.value_size());
-
-    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
-                       expectedBody.value_size()) == 0);
-
-  }
-
-  bool
-  didCallbackFire()
-  {
-    return m_callbackFired;
-  }
-
-  void
-  resetCallbackFired()
-  {
-    m_callbackFired = false;
-  }
-
-  shared_ptr<InternalFace>
-  getInternalFace()
-  {
-    return m_face;
-  }
-
-  FibManager&
-  getFibManager()
-  {
-    return m_manager;
-  }
-
-  Fib&
-  getFib()
-  {
-    return m_fib;
-  }
-
-  void
-  addInterestRule(const std::string& regex,
-                  ndn::IdentityCertificate& certificate)
-  {
-    m_manager.addInterestRule(regex, certificate);
-  }
-
-protected:
-  FibManagerFixture()
-    : m_manager(ref(m_fib), bind(&FibManagerFixture::getFace, this, _1), m_face, m_keyChain)
-    , m_callbackFired(false)
-  {
-  }
-
-protected:
-  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>
-{
-public:
-  AuthorizedCommandFixture()
-  {
-    const std::string regex = "^<localhost><nfd><fib>";
-    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
-  }
-
-  virtual
-  ~AuthorizedCommandFixture()
-  {
-  }
-};
-
-BOOST_FIXTURE_TEST_SUITE(MgmtFibManager, AuthorizedCommandFixture<FibManagerFixture>)
-
-bool
-foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
-{
-  return id == next.getFace()->getId() && next.getCost() == cost;
-}
-
-bool
-addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
-{
-  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
-
-  if (static_cast<bool>(entry))
-    {
-      const fib::NextHopList& hops = entry->getNextHops();
-      return hops.size() == oldSize + 1 &&
-        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
-    }
-  return false;
-}
-
-bool
-foundNextHopWithFace(FaceId id, uint32_t cost,
-                     shared_ptr<Face> face, const fib::NextHop& next)
-{
-  return id == next.getFace()->getId() && next.getCost() == cost && face == next.getFace();
-}
-
-bool
-addedNextHopWithFace(const Fib& fib, const Name& prefix, size_t oldSize,
-                     uint32_t cost, shared_ptr<Face> face)
-{
-  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
-
-  if (static_cast<bool>(entry))
-    {
-      const fib::NextHopList& hops = entry->getNextHops();
-      return hops.size() == oldSize + 1 &&
-        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
-    }
-  return false;
-}
-
-BOOST_AUTO_TEST_CASE(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_CASE(UnknownFaceId)
-{
-  addFace(make_shared<DummyFace>());
-
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  ControlParameters parameters;
-  parameters.setName("/hello");
-  parameters.setFaceId(1000);
-  parameters.setCost(101);
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/fib");
-  commandName.append("add-nexthop");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  face->onReceiveData.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);
-}
-
-BOOST_AUTO_TEST_CASE(AddNextHopVerbImplicitFaceId)
-{
-  addFace(make_shared<DummyFace>());
-
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  std::vector<ControlParameters> testedParameters;
-  testedParameters.push_back(ControlParameters().setName("/hello").setCost(101).setFaceId(0));
-  testedParameters.push_back(ControlParameters().setName("/hello").setCost(101));
-
-  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);
-  }
-}
-
-BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
-{
-  addFace(make_shared<DummyFace>());
-
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  ControlParameters parameters;
-  parameters.setName("/hello");
-  parameters.setFaceId(1);
-  parameters.setCost(101);
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/fib");
-  commandName.append("add-nexthop");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  face->onReceiveData.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));
-}
-
-BOOST_AUTO_TEST_CASE(AddNextHopVerbImplicitCost)
-{
-  addFace(make_shared<DummyFace>());
-
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  ControlParameters parameters;
-  parameters.setName("/hello");
-  parameters.setFaceId(1);
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/fib");
-  commandName.append("add-nexthop");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  ControlParameters resultParameters;
-  resultParameters.setName("/hello");
-  resultParameters.setFaceId(1);
-  resultParameters.setCost(0);
-
-  face->onReceiveData.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));
-}
-
-BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
-{
-  addFace(make_shared<DummyFace>());
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  for (int i = 1; i <= 2; i++)
-    {
-
-      ControlParameters parameters;
-      parameters.setName("/hello");
-      parameters.setFaceId(1);
-      parameters.setCost(100 + i);
-
-      Block encodedParameters(parameters.wireEncode());
-
-      Name commandName("/localhost/nfd/fib");
-      commandName.append("add-nexthop");
-      commandName.append(encodedParameters);
-
-      shared_ptr<Interest> command(make_shared<Interest>(commandName));
-      generateCommand(*command);
-
-      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_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
-{
-  addFace(make_shared<DummyFace>());
-  shared_ptr<InternalFace> face = getInternalFace();
-
-  ControlParameters parameters;
-  parameters.setName("/hello");
-  parameters.setFaceId(1);
-
-  {
-    parameters.setCost(1);
-
-    Block encodedParameters(parameters.wireEncode());
-
-    Name commandName("/localhost/nfd/fib");
-    commandName.append("add-nexthop");
-    commandName.append(encodedParameters);
-
-    shared_ptr<Interest> command(make_shared<Interest>(commandName));
-    generateCommand(*command);
-
-    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)
-{
-  shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
-
-  if (static_cast<bool>(entry))
-    {
-      const fib::NextHopList& hops = entry->getNextHops();
-      return hops.size() == oldSize - 1 &&
-        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
-    }
-  return false;
-}
-
-void
-testRemoveNextHop(CommandFixture<FibManagerFixture>* fixture,
-                  FibManager& manager,
-                  Fib& fib,
-                  shared_ptr<Face> face,
-                  const Name& targetName,
-                  FaceId targetFace)
-{
-  ControlParameters parameters;
-  parameters.setName(targetName);
-  parameters.setFaceId(targetFace);
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/fib");
-  commandName.append("remove-nexthop");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  fixture->generateCommand(*command);
-
-  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();
-  }
-}
-
-BOOST_FIXTURE_TEST_CASE(TestFibEnumerationRequest, FibManagerFixture)
-{
-  for (int i = 0; i < 87; i++)
-    {
-      Name prefix("/test");
-      prefix.appendSegment(i);
-
-      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
-      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
-
-      shared_ptr<fib::Entry> entry = m_fib.insert(prefix).first;
-      entry->addNextHop(dummy1, std::numeric_limits<uint64_t>::max() - 1);
-      entry->addNextHop(dummy2, std::numeric_limits<uint64_t>::max() - 2);
-
-      m_referenceEntries.insert(entry);
-    }
-  for (int i = 0; i < 2; i++)
-    {
-      Name prefix("/test2");
-      prefix.appendSegment(i);
-
-      shared_ptr<DummyFace> dummy1(make_shared<DummyFace>());
-      shared_ptr<DummyFace> dummy2(make_shared<DummyFace>());
-
-      shared_ptr<fib::Entry> entry = m_fib.insert(prefix).first;
-      entry->addNextHop(dummy1, std::numeric_limits<uint8_t>::max() - 1);
-      entry->addNextHop(dummy2, std::numeric_limits<uint8_t>::max() - 2);
-
-      m_referenceEntries.insert(entry);
-    }
-
-  ndn::EncodingBuffer buffer;
-
-  m_face->onReceiveData.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_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
deleted file mode 100644
index 1b78175..0000000
--- a/tests/daemon/mgmt/manager-base.t.cpp
+++ /dev/null
@@ -1,203 +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/manager-base.hpp"
-#include "mgmt/internal-face.hpp"
-
-#include "tests/test-common.hpp"
-
-namespace nfd {
-namespace tests {
-
-NFD_LOG_INIT("ManagerBaseTest");
-
-class ManagerBaseTest : public ManagerBase, protected BaseFixture
-{
-
-public:
-
-  ManagerBaseTest()
-    : ManagerBase(make_shared<InternalFace>(), "TEST-PRIVILEGE", m_keyChain),
-      m_callbackFired(false)
-  {
-
-  }
-
-  void
-  testSetResponse(ControlResponse& response,
-                  uint32_t code,
-                  const std::string& text)
-  {
-    setResponse(response, code, text);
-  }
-
-  void
-  testSendResponse(const Name& name,
-                   uint32_t code,
-                   const std::string& text,
-                   const Block& body)
-  {
-    sendResponse(name, code, text, body);
-  }
-
-  void
-  testSendResponse(const Name& name,
-                   uint32_t code,
-                   const std::string& text)
-  {
-    sendResponse(name, code, text);
-  }
-
-  void
-  testSendResponse(const Name& name,
-                   const ControlResponse& response)
-  {
-    sendResponse(name, response);
-  }
-
-  shared_ptr<InternalFace>
-  getInternalFace()
-  {
-    return 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)
-{
-  ControlResponse response(200, "OK");
-
-  BOOST_CHECK_EQUAL(response.getCode(), 200);
-  BOOST_CHECK_EQUAL(response.getText(), "OK");
-
-  testSetResponse(response, 100, "test");
-
-  BOOST_CHECK_EQUAL(response.getCode(), 100);
-  BOOST_CHECK_EQUAL(response.getText(), "test");
-}
-
-BOOST_AUTO_TEST_CASE(SendResponse4Arg)
-{
-  ndn::nfd::ControlParameters parameters;
-  parameters.setName("/test/body");
-
-  getInternalFace()->onReceiveData.connect([this, parameters] (const Data& response) {
-    this->validateControlResponse(response, "/response", 100, "test", parameters.wireEncode());
-  });
-
-  testSendResponse("/response", 100, "test", parameters.wireEncode());
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-
-BOOST_AUTO_TEST_CASE(SendResponse3Arg)
-{
-  getInternalFace()->onReceiveData.connect([this] (const Data& response) {
-    this->validateControlResponse(response, "/response", 100, "test");
-  });
-
-  testSendResponse("/response", 100, "test");
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_AUTO_TEST_CASE(SendResponse2Arg)
-{
-  getInternalFace()->onReceiveData.connect([this] (const Data& response) {
-    this->validateControlResponse(response, "/response", 100, "test");
-  });
-
-  ControlResponse response(100, "test");
-
-  testSendResponse("/response", 100, "test");
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nfd
diff --git a/tests/daemon/mgmt/status-server.t.cpp b/tests/daemon/mgmt/status-server.t.cpp
deleted file mode 100644
index 4cf7c13..0000000
--- a/tests/daemon/mgmt/status-server.t.cpp
+++ /dev/null
@@ -1,105 +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/status-server.hpp"
-#include "fw/forwarder.hpp"
-#include "version.hpp"
-#include "mgmt/internal-face.hpp"
-
-#include "tests/test-common.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
-
-namespace nfd {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(MgmtStatusServer, BaseFixture)
-
-shared_ptr<const Data> g_response;
-
-void
-interceptResponse(const Data& data)
-{
-  g_response = data.shared_from_this();
-}
-
-BOOST_AUTO_TEST_CASE(Status)
-{
-  // initialize
-  time::system_clock::TimePoint t1 = time::system_clock::now();
-  Forwarder forwarder;
-  shared_ptr<InternalFace> internalFace = make_shared<InternalFace>();
-  internalFace->onReceiveData.connect(&interceptResponse);
-  ndn::KeyChain keyChain;
-  StatusServer statusServer(internalFace, ref(forwarder), keyChain);
-  time::system_clock::TimePoint t2 = time::system_clock::now();
-
-  // populate tables
-  forwarder.getFib().insert("ndn:/fib1");
-  forwarder.getPit().insert(*makeInterest("ndn:/pit1"));
-  forwarder.getPit().insert(*makeInterest("ndn:/pit2"));
-  forwarder.getPit().insert(*makeInterest("ndn:/pit3"));
-  forwarder.getPit().insert(*makeInterest("ndn:/pit4"));
-  forwarder.getMeasurements().get("ndn:/measurements1");
-  forwarder.getMeasurements().get("ndn:/measurements2");
-  forwarder.getMeasurements().get("ndn:/measurements3");
-  BOOST_CHECK_GE(forwarder.getFib().size(), 1);
-  BOOST_CHECK_GE(forwarder.getPit().size(), 4);
-  BOOST_CHECK_GE(forwarder.getMeasurements().size(), 3);
-
-  // request
-  shared_ptr<Interest> request = makeInterest("ndn:/localhost/nfd/status");
-  request->setMustBeFresh(true);
-  request->setChildSelector(1);
-
-  g_response.reset();
-  time::system_clock::TimePoint t3 = time::system_clock::now();
-  internalFace->sendInterest(*request);
-  g_io.run_one();
-  time::system_clock::TimePoint t4 = time::system_clock::now();
-  BOOST_REQUIRE(static_cast<bool>(g_response));
-
-  // verify
-  ndn::nfd::ForwarderStatus status;
-  BOOST_REQUIRE_NO_THROW(status.wireDecode(g_response->getContent()));
-
-  BOOST_CHECK_EQUAL(status.getNfdVersion(), NFD_VERSION_BUILD_STRING);
-  BOOST_CHECK_GE(time::toUnixTimestamp(status.getStartTimestamp()), time::toUnixTimestamp(t1));
-  BOOST_CHECK_LE(time::toUnixTimestamp(status.getStartTimestamp()), time::toUnixTimestamp(t2));
-  BOOST_CHECK_GE(time::toUnixTimestamp(status.getCurrentTimestamp()), time::toUnixTimestamp(t3));
-  BOOST_CHECK_LE(time::toUnixTimestamp(status.getCurrentTimestamp()), time::toUnixTimestamp(t4));
-
-  // StatusServer under test isn't added to Forwarder,
-  // so request and response won't affect table size
-  BOOST_CHECK_EQUAL(status.getNNameTreeEntries(), forwarder.getNameTree().size());
-  BOOST_CHECK_EQUAL(status.getNFibEntries(), forwarder.getFib().size());
-  BOOST_CHECK_EQUAL(status.getNPitEntries(), forwarder.getPit().size());
-  BOOST_CHECK_EQUAL(status.getNMeasurementsEntries(), forwarder.getMeasurements().size());
-  BOOST_CHECK_EQUAL(status.getNCsEntries(), forwarder.getCs().size());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nfd
diff --git a/tests/daemon/mgmt/strategy-choice-manager.t.cpp b/tests/daemon/mgmt/strategy-choice-manager.t.cpp
deleted file mode 100644
index d0c425d..0000000
--- a/tests/daemon/mgmt/strategy-choice-manager.t.cpp
+++ /dev/null
@@ -1,646 +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/strategy-choice-manager.hpp"
-#include "face/face.hpp"
-#include "mgmt/internal-face.hpp"
-#include "table/name-tree.hpp"
-#include "table/strategy-choice.hpp"
-#include "fw/forwarder.hpp"
-#include "fw/strategy.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
-#include "tests/daemon/fw/dummy-strategy.hpp"
-
-#include <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
-{
-public:
-
-  StrategyChoiceManagerFixture()
-    : m_strategyChoice(m_forwarder.getStrategyChoice())
-    , m_face(make_shared<InternalFace>())
-    , m_manager(m_strategyChoice, m_face, m_keyChain)
-    , m_callbackFired(false)
-  {
-    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");
-  }
-
-  virtual
-  ~StrategyChoiceManagerFixture()
-  {
-
-  }
-
-  void
-  validateControlResponseCommon(const Data& response,
-                                const Name& expectedName,
-                                uint32_t expectedCode,
-                                const std::string& expectedText,
-                                ControlResponse& control)
-  {
-    m_callbackFired = true;
-    Block controlRaw = response.getContent().blockFromValue();
-
-    control.wireDecode(controlRaw);
-
-    NFD_LOG_DEBUG("received control response"
-                  << " Name: " << response.getName()
-                  << " code: " << control.getCode()
-                  << " text: " << control.getText());
-
-    BOOST_CHECK_EQUAL(response.getName(), expectedName);
-    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
-    BOOST_CHECK_EQUAL(control.getText(), expectedText);
-  }
-
-  void
-  validateControlResponse(const Data& response,
-                          const Name& expectedName,
-                          uint32_t expectedCode,
-                          const std::string& expectedText)
-  {
-    ControlResponse control;
-    validateControlResponseCommon(response, expectedName,
-                                  expectedCode, expectedText, control);
-
-    if (!control.getBody().empty())
-      {
-        BOOST_FAIL("found unexpected control response body");
-      }
-  }
-
-  void
-  validateControlResponse(const Data& response,
-                          const Name& expectedName,
-                          uint32_t expectedCode,
-                          const std::string& expectedText,
-                          const Block& expectedBody)
-  {
-    ControlResponse control;
-    validateControlResponseCommon(response, expectedName,
-                                  expectedCode, expectedText, control);
-
-    BOOST_REQUIRE(!control.getBody().empty());
-    BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
-
-    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
-                       expectedBody.value_size()) == 0);
-
-  }
-
-  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);
-  }
-
-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
-{
-public:
-  AllStrategiesFixture()
-  {
-    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>
-{
-public:
-  AuthorizedCommandFixture()
-  {
-    const std::string regex = "^<localhost><nfd><strategy-choice>";
-    T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
-  }
-
-  virtual
-  ~AuthorizedCommandFixture()
-  {
-
-  }
-};
-
-BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoiceManager,
-                         AuthorizedCommandFixture<AllStrategiesFixture>)
-
-BOOST_FIXTURE_TEST_CASE(ShortName, AllStrategiesFixture)
-{
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
-
-  getFace()->onReceiveData.connect([this, command] (const Data& response) {
-    this->validateControlResponse(response, command->getName(), 400, "Malformed command");
-  });
-
-  getFace()->sendInterest(*command);
-  g_io.run_one();
-
-  BOOST_REQUIRE(didCallbackFire());
-}
-
-BOOST_FIXTURE_TEST_CASE(MalformedCommmand, AllStrategiesFixture)
-{
-  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
-
-  getFace()->onReceiveData.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()
-  {
-
-  }
-
-  virtual
-  ~DefaultStrategyOnlyFixture()
-  {
-
-  }
-};
-
-
-/// \todo I'm not sure this code branch (code 405) can happen. The manager tests for the strategy first and will return 504.
-// BOOST_FIXTURE_TEST_CASE(SetNotInstalled, DefaultStrategyOnlyFixture)
-// {
-//   BOOST_REQUIRE(!getStrategyChoice().hasStrategy("/localhost/nfd/strategy/test-strategy-b"));
-//   ControlParameters parameters;
-//   parameters.setName("/test");
-//   parameters.setStrategy("/localhost/nfd/strategy/test-strategy-b");
-
-//   Block encodedParameters(parameters.wireEncode());
-
-//   Name commandName("/localhost/nfd/strategy-choice");
-//   commandName.append("set");
-//   commandName.append(encodedParameters);
-
-//   shared_ptr<Interest> command(make_shared<Interest>(commandName));
-//   generateCommand(*command);
-
-//   getFace()->onReceiveData +=
-//     bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
-//          command->getName(), 405, "Strategy not installed");
-
-//   getManager().onValidatedStrategyChoiceRequest(command);
-
-//   BOOST_REQUIRE(didCallbackFire());
-//   fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
-//   BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
-// }
-
-BOOST_AUTO_TEST_CASE(Unset)
-{
-  ControlParameters parameters;
-  parameters.setName("/test");
-
-  BOOST_REQUIRE(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b"));
-  BOOST_REQUIRE_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
-                      "/localhost/nfd/strategy/test-strategy-b");
-
-  Block encodedParameters(parameters.wireEncode());
-
-  Name commandName("/localhost/nfd/strategy-choice");
-  commandName.append("unset");
-  commandName.append(encodedParameters);
-
-  shared_ptr<Interest> command(make_shared<Interest>(commandName));
-  generateCommand(*command);
-
-  getFace()->onReceiveData.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_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()
-
-} // 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
