diff --git a/rib/nrd.cpp b/rib/nrd.cpp
index bcee83c..d723a3f 100644
--- a/rib/nrd.cpp
+++ b/rib/nrd.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -63,10 +63,11 @@
 Nrd::initialize()
 {
   m_face.reset(new ndn::Face(getLocalNfdTransport(), getGlobalIoService(), m_keyChain));
+  m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_face, m_keyChain));
 
   initializeLogging();
 
-  m_ribManager.reset(new RibManager(*m_face, m_keyChain));
+  m_ribManager.reset(new RibManager(*m_dispatcher, *m_face, m_keyChain));
 
   ConfigFile config([] (const std::string& filename, const std::string& sectionName,
                         const ConfigSection& section, bool isDryRun) {
diff --git a/rib/nrd.hpp b/rib/nrd.hpp
index e861422..0d8743d 100644
--- a/rib/nrd.hpp
+++ b/rib/nrd.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -32,6 +32,7 @@
 #include <ndn-cxx/face.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/transport/transport.hpp>
+#include <ndn-cxx/mgmt/dispatcher.hpp>
 
 namespace nfd {
 namespace rib {
@@ -98,6 +99,7 @@
 
   ndn::KeyChain& m_keyChain;
   unique_ptr<ndn::Face> m_face;
+  unique_ptr<ndn::mgmt::Dispatcher> m_dispatcher;
   unique_ptr<RibManager> m_ribManager;
 };
 
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index 03faf21..edd6c5d 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -28,69 +28,41 @@
 #include "core/logger.hpp"
 #include "core/scheduler.hpp"
 #include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/management/nfd-rib-entry.hpp>
 
 namespace nfd {
 namespace rib {
 
 NFD_LOG_INIT("RibManager");
 
-const Name RibManager::COMMAND_PREFIX = "/localhost/nfd/rib";
-const Name RibManager::REMOTE_COMMAND_PREFIX = "/localhop/nfd/rib";
+const Name RibManager::LOCAL_HOST_TOP_PREFIX = "/localhost/nfd";
+const Name RibManager::LOCAL_HOP_TOP_PREFIX = "/localhop/nfd";
 const Name RibManager::FACES_LIST_DATASET_PREFIX = "/localhost/nfd/faces/list";
-
-const size_t RibManager::COMMAND_UNSIGNED_NCOMPS =
-  RibManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb options
-
-const size_t RibManager::COMMAND_SIGNED_NCOMPS =
-  RibManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const RibManager::SignedVerbAndProcessor RibManager::SIGNED_COMMAND_VERBS[] =
-  {
-    SignedVerbAndProcessor(
-                           Name::Component("register"),
-                           &RibManager::registerEntry
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("unregister"),
-                           &RibManager::unregisterEntry
-                           ),
-  };
-
-const RibManager::UnsignedVerbAndProcessor RibManager::UNSIGNED_COMMAND_VERBS[] =
-  {
-    UnsignedVerbAndProcessor(
-                             Name::Component("list"),
-                             &RibManager::listEntries
-                             ),
-  };
-
-const Name RibManager::LIST_COMMAND_PREFIX("/localhost/nfd/rib/list");
-const size_t RibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
-
 const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
 
-RibManager::RibManager(ndn::Face& face, ndn::KeyChain& keyChain)
-  : m_face(face)
+RibManager::RibManager(Dispatcher& dispatcher,
+                       ndn::Face& face,
+                       ndn::KeyChain& keyChain)
+  : ManagerBase(dispatcher, "rib")
+  , m_face(face)
   , m_keyChain(keyChain)
   , m_nfdController(m_face, m_keyChain)
+  , m_faceMonitor(m_face)
   , m_localhostValidator(m_face)
   , m_localhopValidator(m_face)
-  , m_faceMonitor(m_face)
   , m_isLocalhopEnabled(false)
-  , m_prefixPropagator(m_nfdController, m_keyChain, m_managedRib)
-  , m_ribStatusPublisher(m_managedRib, face, LIST_COMMAND_PREFIX, m_keyChain)
-  , m_fibUpdater(m_managedRib, m_nfdController)
-  , 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)))
+  , m_prefixPropagator(m_nfdController, m_keyChain, m_rib)
+  , m_fibUpdater(m_rib, m_nfdController)
+  , m_addTopPrefix([&dispatcher] (const Name& topPrefix) {
+      dispatcher.addTopPrefix(topPrefix, false);
+    })
 {
+  registerCommandHandler<ndn::nfd::RibRegisterCommand>("register",
+    bind(&RibManager::registerEntry, this, _2, _3, _4, _5));
+  registerCommandHandler<ndn::nfd::RibUnregisterCommand>("unregister",
+    bind(&RibManager::unregisterEntry, this, _2, _3, _4, _5));
+
+  registerStatusDatasetHandler("list", bind(&RibManager::listEntries, this, _1, _2, _3));
 }
 
 RibManager::~RibManager()
@@ -99,31 +71,12 @@
 }
 
 void
-RibManager::startListening(const Name& commandPrefix, const ndn::OnInterest& onRequest)
-{
-  NFD_LOG_INFO("Listening on: " << commandPrefix);
-
-  m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
-    ControlParameters()
-      .setName(commandPrefix)
-      .setFaceId(0),
-    bind(&RibManager::onNrdCommandPrefixAddNextHopSuccess, this, cref(commandPrefix), _1),
-    bind(&RibManager::onNrdCommandPrefixAddNextHopError, this, cref(commandPrefix), _2));
-
-  m_face.setInterestFilter(commandPrefix, onRequest);
-}
-
-void
 RibManager::registerWithNfd()
 {
-  //check whether the components of localhop and localhost prefixes are same
-  BOOST_ASSERT(COMMAND_PREFIX.size() == REMOTE_COMMAND_PREFIX.size());
-
-  this->startListening(COMMAND_PREFIX, bind(&RibManager::onLocalhostRequest, this, _2));
+  registerTopPrefix(LOCAL_HOST_TOP_PREFIX);
 
   if (m_isLocalhopEnabled) {
-    this->startListening(REMOTE_COMMAND_PREFIX,
-                         bind(&RibManager::onLocalhopRequest, this, _2));
+    registerTopPrefix(LOCAL_HOP_TOP_PREFIX);
   }
 
   NFD_LOG_INFO("Start monitoring face create/destroy events");
@@ -134,6 +87,16 @@
 }
 
 void
+RibManager::enableLocalControlHeader()
+{
+  m_nfdController.start<ndn::nfd::FaceEnableLocalControlCommand>(
+    ControlParameters()
+      .setLocalControlFeature(ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
+    bind(&RibManager::onControlHeaderSuccess, this),
+    bind(&RibManager::onControlHeaderError, this, _1, _2));
+}
+
+void
 RibManager::setConfigFile(ConfigFile& configFile)
 {
   configFile.addSectionHandler("rib",
@@ -141,6 +104,22 @@
 }
 
 void
+RibManager::onRibUpdateSuccess(const RibUpdate& update)
+{
+  NFD_LOG_DEBUG("RIB update succeeded for " << update);
+}
+
+void
+RibManager::onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error)
+{
+  NFD_LOG_DEBUG("RIB update failed for " << update << " (code: " << code
+                                                   << ", error: " << error << ")");
+
+  // Since the FIB rejected the update, clean up invalid routes
+  scheduleActiveFaceFetch(time::seconds(1));
+}
+
+void
 RibManager::onConfig(const ConfigSection& configSection,
                      bool isDryRun,
                      const std::string& filename)
@@ -177,120 +156,29 @@
 }
 
 void
-RibManager::sendResponse(const Name& name,
-                         const ControlResponse& response)
+RibManager::registerTopPrefix(const Name& topPrefix)
 {
-  const Block& encodedControl = response.wireEncode();
+  // register entry to the FIB
+  m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
+     ControlParameters()
+       .setName(topPrefix)
+       .setFaceId(0),
+     bind(&RibManager::onNrdCommandPrefixAddNextHopSuccess, this, cref(topPrefix), _1),
+     bind(&RibManager::onNrdCommandPrefixAddNextHopError, this, cref(topPrefix), _2));
 
-  shared_ptr<Data> responseData = make_shared<Data>(name);
-  responseData->setContent(encodedControl);
-
-  m_keyChain.sign(*responseData);
-  m_face.put(*responseData);
+  // add top prefix to the dispatcher
+  m_addTopPrefix(topPrefix);
 }
 
 void
-RibManager::sendResponse(const Name& name,
-                         uint32_t code,
-                         const std::string& text)
+RibManager::registerEntry(const Name& topPrefix, const Interest& interest,
+                          ControlParameters parameters,
+                          const ndn::mgmt::CommandContinuation& done)
 {
-  ControlResponse response(code, text);
-  sendResponse(name, response);
-}
-
-void
-RibManager::onLocalhostRequest(const Interest& request)
-{
-  const Name& command = request.getName();
-  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
-
-  UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
-
-  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end()) {
-    NFD_LOG_DEBUG("command result: processing unsigned verb: " << verb);
-    (unsignedVerbProcessor->second)(this, request);
-  }
-  else {
-    m_localhostValidator.validate(request,
-                                  bind(&RibManager::onCommandValidated, this, _1),
-                                  bind(&RibManager::onCommandValidationFailed, this, _1, _2));
-  }
-}
-
-void
-RibManager::onLocalhopRequest(const Interest& request)
-{
-  m_localhopValidator.validate(request,
-                               bind(&RibManager::onCommandValidated, this, _1),
-                               bind(&RibManager::onCommandValidationFailed, this, _1, _2));
-}
-
-void
-RibManager::onCommandValidated(const shared_ptr<const Interest>& request)
-{
-  // REMOTE_COMMAND_PREFIX number of componenets are same as
-  // NRD_COMMAND_PREFIX's so no extra checks are required.
-
-  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);
-
-      if (static_cast<bool>(request)) {
-        sendResponse(command, 400, "Malformed command");
-      }
-
-      return;
-    }
-
-    NFD_LOG_DEBUG("command result: processing verb: " << verb);
-    (verbProcessor->second)(this, request, parameters);
-  }
-  else {
-    NFD_LOG_DEBUG("Unsupported command: " << verb);
-
-    if (static_cast<bool>(request)) {
-      sendResponse(request->getName(), 501, "Unsupported command");
-    }
-  }
-}
-
-void
-RibManager::registerEntry(const shared_ptr<const Interest>& request,
-                          ControlParameters& parameters)
-{
-  ndn::nfd::RibRegisterCommand command;
-
-  if (!validateParameters(command, parameters)) {
-    NFD_LOG_DEBUG("register result: FAIL reason: malformed");
-
-    if (static_cast<bool>(request)) {
-      sendResponse(request->getName(), 400, "Malformed command");
-    }
-
-    return;
-  }
-
-  bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
-  if (isSelfRegistration) {
-    shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request->getTag<lp::IncomingFaceIdTag>();
-    if (incomingFaceIdTag == nullptr) {
-      sendResponse(request->getName(), 503,
-                   "requested self-registration, but IncomingFaceId is unavailable");
-      return;
-    }
-    parameters.setFaceId(*incomingFaceIdTag);
-  }
+  setFaceForSelfRegistration(interest, parameters);
 
   // Respond since command is valid and authorized
-  sendSuccessResponse(request, parameters);
+  done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
 
   Route route;
   route.faceId = parameters.getFaceId();
@@ -305,7 +193,7 @@
 
     // Schedule a new event, the old one will be cancelled during rib insertion.
     scheduler::EventId eventId = scheduler::schedule(parameters.getExpirationPeriod(),
-      bind(&Rib::onRouteExpiration, &m_managedRib, parameters.getName(), route));
+      bind(&Rib::onRouteExpiration, &m_rib, parameters.getName(), route));
 
     NFD_LOG_TRACE("Scheduled unregistration at: " << route.expires <<
                   " with EventId: " << eventId);
@@ -326,7 +214,7 @@
         .setName(parameters.getName())
         .setRoute(route);
 
-  m_managedRib.beginApplyUpdate(update,
+  m_rib.beginApplyUpdate(update,
                                 bind(&RibManager::onRibUpdateSuccess, this, update),
                                 bind(&RibManager::onRibUpdateFailure, this, update, _1, _2));
 
@@ -334,47 +222,14 @@
 }
 
 void
-RibManager::unregisterEntry(const shared_ptr<const Interest>& request,
-                            ControlParameters& params)
+RibManager::unregisterEntry(const Name& topPrefix, const Interest& interest,
+                            ControlParameters parameters,
+                            const ndn::mgmt::CommandContinuation& done)
 {
-  ndn::nfd::RibUnregisterCommand command;
-
-  // Passing all parameters gives error in validation,
-  // so passing only the required arguments.
-  ControlParameters parameters;
-  parameters.setName(params.getName());
-
-  if (params.hasFaceId()) {
-    parameters.setFaceId(params.getFaceId());
-  }
-
-  if (params.hasOrigin()) {
-    parameters.setOrigin(params.getOrigin());
-  }
-
-  if (!validateParameters(command, parameters)) {
-    NFD_LOG_DEBUG("unregister result: FAIL reason: malformed");
-
-    if (static_cast<bool>(request)) {
-      sendResponse(request->getName(), 400, "Malformed command");
-    }
-
-    return;
-  }
-
-  bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
-  if (isSelfRegistration) {
-    shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request->getTag<lp::IncomingFaceIdTag>();
-    if (incomingFaceIdTag == nullptr) {
-      sendResponse(request->getName(), 503,
-                   "requested self-registration, but IncomingFaceId is unavailable");
-      return;
-    }
-    parameters.setFaceId(*incomingFaceIdTag);
-  }
+  setFaceForSelfRegistration(interest, parameters);
 
   // Respond since command is valid and authorized
-  sendSuccessResponse(request, parameters);
+  done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
 
   Route route;
   route.faceId = parameters.getFaceId();
@@ -388,272 +243,72 @@
         .setName(parameters.getName())
         .setRoute(route);
 
-  m_managedRib.beginApplyUpdate(update,
+  m_rib.beginApplyUpdate(update,
                                 bind(&RibManager::onRibUpdateSuccess, this, update),
                                 bind(&RibManager::onRibUpdateFailure, this, update, _1, _2));
 }
 
 void
-RibManager::onCommandValidationFailed(const shared_ptr<const Interest>& request,
-                                      const std::string& failureInfo)
+RibManager::listEntries(const Name& topPrefix, const Interest& interest,
+                        ndn::mgmt::StatusDatasetContext& context)
 {
-  NFD_LOG_DEBUG("RibRequestValidationFailed: " << failureInfo);
+  for (auto&& ribTableEntry : m_rib) {
+    const auto& ribEntry = *ribTableEntry.second;
+    ndn::nfd::RibEntry record;
 
-  if (static_cast<bool>(request)) {
-    sendResponse(request->getName(), 403, failureInfo);
-  }
-}
+    for (auto&& route : ribEntry) {
+      ndn::nfd::Route routeElement;
+      routeElement.setFaceId(route.faceId)
+              .setOrigin(route.origin)
+              .setCost(route.cost)
+              .setFlags(route.flags);
 
+      if (route.expires < time::steady_clock::TimePoint::max()) {
+        routeElement.setExpirationPeriod(time::duration_cast<time::milliseconds>(
+          route.expires - time::steady_clock::now()));
+      }
 
-bool
-RibManager::extractParameters(const Name::Component& parameterComponent,
-                              ControlParameters& extractedParameters)
-{
-  try {
-    Block rawParameters = parameterComponent.blockFromValue();
-    extractedParameters.wireDecode(rawParameters);
-  }
-  catch (const tlv::Error&) {
-    return false;
+      record.addRoute(routeElement);
+    }
+
+    record.setName(ribEntry.getName());
+    context.append(record.wireEncode());
   }
 
-  NFD_LOG_DEBUG("Parameters parsed OK");
-  return true;
-}
-
-bool
-RibManager::validateParameters(const ControlCommand& command,
-                               ControlParameters& parameters)
-{
-  try {
-    command.validateRequest(parameters);
-  }
-  catch (const ControlCommand::ArgumentError&) {
-    return false;
-  }
-
-  command.applyDefaultsToRequest(parameters);
-
-  return true;
+  context.end();
 }
 
 void
-RibManager::onCommandError(uint32_t code, const std::string& error,
-                           const shared_ptr<const Interest>& request,
-                           const Route& route)
+RibManager::setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters)
 {
-  NFD_LOG_ERROR("NFD returned an error: " << error << " (code: " << code << ")");
-
-  ControlResponse response;
-
-  if (code == 404) {
-    response.setCode(code);
-    response.setText(error);
-  }
-  else {
-    response.setCode(533);
-    std::ostringstream os;
-    os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
-    response.setText(os.str());
-  }
-
-  if (static_cast<bool>(request)) {
-    sendResponse(request->getName(), response);
+  bool isSelfRegistration = (parameters.getFaceId() == 0);
+  if (isSelfRegistration) {
+    shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
+    // NDNLPv2 says "application MUST be prepared to receive a packet without IncomingFaceId field",
+    // but it's fine to assert IncomingFaceId is available, because InternalFace lives inside NFD
+    // and is initialized synchronously with IncomingFaceId field enabled.
+    BOOST_ASSERT(incomingFaceIdTag != nullptr);
+    parameters.setFaceId(*incomingFaceIdTag);
   }
 }
 
 void
-RibManager::onRegSuccess(const shared_ptr<const Interest>& request,
-                         const ControlParameters& parameters,
-                         const Route& route)
+RibManager::authorize(const Name& prefix, const Interest& interest,
+                      const ndn::mgmt::ControlParameters* params,
+                      ndn::mgmt::AcceptContinuation accept,
+                      ndn::mgmt::RejectContinuation reject)
 {
-  ControlResponse response;
+  BOOST_ASSERT(params != nullptr);
+  BOOST_ASSERT(typeid(*params) == typeid(ndn::nfd::ControlParameters));
+  BOOST_ASSERT(prefix == LOCAL_HOST_TOP_PREFIX || prefix == LOCAL_HOP_TOP_PREFIX);
 
-  response.setCode(200);
-  response.setText("Success");
-  response.setBody(parameters.wireEncode());
+  auto& validator = [this, &prefix] () -> ndn::ValidatorConfig & {
+    return prefix == LOCAL_HOST_TOP_PREFIX ? m_localhostValidator : m_localhopValidator;
+  }();
 
-  NFD_LOG_TRACE("onRegSuccess: registered " << route);
-
-  if (static_cast<bool>(request)) {
-    sendResponse(request->getName(), response);
-  }
-}
-
-
-void
-RibManager::onUnRegSuccess(const shared_ptr<const Interest>& request,
-                           const ControlParameters& parameters,
-                           const Route& route)
-{
-  ControlResponse response;
-
-  response.setCode(200);
-  response.setText("Success");
-  response.setBody(parameters.wireEncode());
-
-  NFD_LOG_TRACE("onUnRegSuccess: unregistered " << route);
-
-  if (static_cast<bool>(request)) {
-    sendResponse(request->getName(), response);
-  }
-}
-
-void
-RibManager::sendSuccessResponse(const shared_ptr<const Interest>& request,
-                                const ControlParameters& parameters)
-{
-  if (!static_cast<bool>(request)) {
-    return;
-  }
-
-  ControlResponse response;
-
-  response.setCode(200);
-  response.setText("Success");
-  response.setBody(parameters.wireEncode());
-
-  if (static_cast<bool>(request)) {
-    sendResponse(request->getName(), response);
-  }
-}
-
-void
-RibManager::sendErrorResponse(uint32_t code, const std::string& error,
-                              const shared_ptr<const Interest>& request)
-{
-  NFD_LOG_ERROR("NFD returned an error: " << error << " (code: " << code << ")");
-
-  if (!static_cast<bool>(request)) {
-    return;
-  }
-
-  ControlResponse response;
-
-  if (code == 404) {
-    response.setCode(code);
-    response.setText(error);
-  }
-  else {
-    response.setCode(533);
-    std::ostringstream os;
-    os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
-    response.setText(os.str());
-  }
-
-  if (static_cast<bool>(request)) {
-    sendResponse(request->getName(), response);
-  }
-}
-
-void
-RibManager::onRibUpdateSuccess(const RibUpdate& update)
-{
-  NFD_LOG_DEBUG("RIB update succeeded for " << update);
-}
-
-void
-RibManager::onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error)
-{
-  NFD_LOG_DEBUG("RIB update failed for " << update << " (code: " << code
-                                                   << ", error: " << error << ")");
-
-  // Since the FIB rejected the update, clean up invalid routes
-  scheduleActiveFaceFetch(time::seconds(1));
-}
-
-void
-RibManager::onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
-                                                const ndn::nfd::ControlParameters& result)
-{
-  NFD_LOG_DEBUG("Successfully registered " + prefix.toUri() + " with NFD");
-
-  // Routes must be inserted into the RIB so route flags can be applied
-  Route route;
-  route.faceId = result.getFaceId();
-  route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
-  route.expires = time::steady_clock::TimePoint::max();
-  route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
-
-  m_managedRib.insert(prefix, route);
-
-  m_registeredFaces.insert(route.faceId);
-}
-
-void
-RibManager::onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
-{
-  BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
-}
-
-void
-RibManager::onControlHeaderSuccess()
-{
-  NFD_LOG_DEBUG("Local control header enabled");
-}
-
-void
-RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
-{
-  std::ostringstream os;
-  os << "Couldn't enable local control header "
-     << "(code: " << code << ", info: " << reason << ")";
-  BOOST_THROW_EXCEPTION(Error(os.str()));
-}
-
-void
-RibManager::enableLocalControlHeader()
-{
-  m_nfdController.start<ndn::nfd::FaceEnableLocalControlCommand>(
-    ControlParameters()
-      .setLocalControlFeature(ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
-    bind(&RibManager::onControlHeaderSuccess, this),
-    bind(&RibManager::onControlHeaderError, this, _1, _2));
-}
-
-void
-RibManager::onNotification(const FaceEventNotification& notification)
-{
-  NFD_LOG_TRACE("onNotification: " << notification);
-
-  if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
-    NFD_LOG_DEBUG("Received notification for destroyed faceId: " << notification.getFaceId());
-
-    scheduler::schedule(time::seconds(0),
-                        bind(&RibManager::onFaceDestroyedEvent, this, notification.getFaceId()));
-  }
-}
-
-void
-RibManager::onFaceDestroyedEvent(uint64_t faceId)
-{
-  m_managedRib.beginRemoveFace(faceId);
-  m_registeredFaces.erase(faceId);
-}
-
-void
-RibManager::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_ribStatusPublisher.publish();
-}
-
-void
-RibManager::scheduleActiveFaceFetch(const time::seconds& timeToWait)
-{
-  scheduler::cancel(m_activeFaceFetchEvent);
-
-  m_activeFaceFetchEvent = scheduler::schedule(timeToWait,
-                                               bind(&RibManager::fetchActiveFaces, this));
+  validator.validate(interest,
+                     bind([&interest, this, accept] { extractRequester(interest, accept); }),
+                     bind([reject] { reject(ndn::mgmt::RejectReply::STATUS403); }));
 }
 
 void
@@ -693,6 +348,29 @@
 }
 
 void
+RibManager::onFetchFaceStatusTimeout()
+{
+  std::cerr << "Face Status Dataset request timed out" << std::endl;
+  scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+}
+
+void
+RibManager::onFaceDestroyedEvent(uint64_t faceId)
+{
+  m_rib.beginRemoveFace(faceId);
+  m_registeredFaces.erase(faceId);
+}
+
+void
+RibManager::scheduleActiveFaceFetch(const time::seconds& timeToWait)
+{
+  scheduler::cancel(m_activeFaceFetchEvent);
+
+  m_activeFaceFetchEvent = scheduler::schedule(timeToWait,
+                                               bind(&RibManager::fetchActiveFaces, this));
+}
+
+void
 RibManager::removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer)
 {
   NFD_LOG_DEBUG("Checking for invalid face registrations");
@@ -719,7 +397,7 @@
 
   // Look for face IDs that were registered but not active to find missed
   // face destroyed events
-  for (uint64_t faceId : m_registeredFaces) {
+  for (auto&& faceId : m_registeredFaces) {
     if (activeFaces.find(faceId) == activeFaces.end()) {
       NFD_LOG_DEBUG("Removing invalid face ID: " << faceId);
 
@@ -733,10 +411,55 @@
 }
 
 void
-RibManager::onFetchFaceStatusTimeout()
+RibManager::onNotification(const FaceEventNotification& notification)
 {
-  std::cerr << "Face Status Dataset request timed out" << std::endl;
-  scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+  NFD_LOG_TRACE("onNotification: " << notification);
+
+  if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
+    NFD_LOG_DEBUG("Received notification for destroyed faceId: " << notification.getFaceId());
+
+    scheduler::schedule(time::seconds(0),
+                        bind(&RibManager::onFaceDestroyedEvent, this, notification.getFaceId()));
+  }
+}
+
+void
+RibManager::onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
+                                                const ndn::nfd::ControlParameters& result)
+{
+  NFD_LOG_DEBUG("Successfully registered " + prefix.toUri() + " with NFD");
+
+  // Routes must be inserted into the RIB so route flags can be applied
+  Route route;
+  route.faceId = result.getFaceId();
+  route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
+  route.expires = time::steady_clock::TimePoint::max();
+  route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
+
+  m_rib.insert(prefix, route);
+
+  m_registeredFaces.insert(route.faceId);
+}
+
+void
+RibManager::onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
+{
+  BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
+}
+
+void
+RibManager::onControlHeaderSuccess()
+{
+  NFD_LOG_DEBUG("Local control header enabled");
+}
+
+void
+RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
+{
+  std::ostringstream os;
+  os << "Couldn't enable local control header "
+     << "(code: " << code << ", info: " << reason << ")";
+  BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
 } // namespace rib
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index d7c6819..0e5d68d 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -28,6 +28,7 @@
 
 #include "rib.hpp"
 #include "core/config-file.hpp"
+#include "core/manager-base.hpp"
 #include "rib-status-publisher.hpp"
 #include "auto-prefix-propagator.hpp"
 #include "fib-updater.hpp"
@@ -48,7 +49,7 @@
 
 using ndn::nfd::FaceEventNotification;
 
-class RibManager : noncopyable
+class RibManager : public nfd::ManagerBase
 {
 public:
   class Error : public std::runtime_error
@@ -61,7 +62,8 @@
     }
   };
 
-  RibManager(ndn::Face& face, ndn::KeyChain& keyChain);
+public:
+  RibManager(Dispatcher& dispatcher, ndn::Face& face, ndn::KeyChain& keyChain);
 
   ~RibManager();
 
@@ -80,107 +82,55 @@
   void
   onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error);
 
-private:
+private: // initialization helpers
   void
-  onConfig(const ConfigSection& configSection,
-           bool isDryRun,
-           const std::string& filename);
+  onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
 
   void
-  startListening(const Name& commandPrefix, const ndn::OnInterest& onRequest);
+  registerTopPrefix(const Name& topPrefix);
+
+private: // ControlCommand and StatusDataset
+  void
+  registerEntry(const Name& topPrefix, const Interest& interest,
+                ControlParameters parameters,
+                const ndn::mgmt::CommandContinuation& done);
 
   void
-  onLocalhopRequest(const Interest& request);
+  unregisterEntry(const Name& topPrefix, const Interest& interest,
+                  ControlParameters parameters,
+                  const ndn::mgmt::CommandContinuation& done);
 
   void
-  onLocalhostRequest(const Interest& request);
+  listEntries(const Name& topPrefix, const Interest& interest,
+              ndn::mgmt::StatusDatasetContext& context);
 
   void
-  sendResponse(const Name& name,
-               const ControlResponse& response);
+  setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
 
-  void
-  sendResponse(const Name& name,
-               uint32_t code,
-               const std::string& text);
+private: // command validation
+  /**
+   * @brief validate a request for ControlCommand.
+   *
+   * This is called by the dispatcher.
+   *
+   * @pre params != null
+   * @pre typeid(*params) == typeid(ndn::nfd::ControlParameters)
+   *
+   * @param prefix the top prefix
+   * @param interest a request for ControlCommand
+   * @param params the parameters for ControlCommand
+   * @param accept callback of successful validation, take the requester string as a argument
+   * @param reject callback of failure in validation, take the action code as a argument
+   *
+   * use m_localhostValidator / m_localhopValidator to validate commands according to @p prefix.
+   */
+  virtual void
+  authorize(const Name& prefix, const Interest& interest,
+            const ndn::mgmt::ControlParameters* params,
+            ndn::mgmt::AcceptContinuation accept,
+            ndn::mgmt::RejectContinuation reject) override;
 
-  void
-  sendSuccessResponse(const shared_ptr<const Interest>& request,
-                      const ControlParameters& parameters);
-
-  void
-  sendErrorResponse(uint32_t code, const std::string& error,
-                    const shared_ptr<const Interest>& request);
-
-  void
-  registerEntry(const shared_ptr<const Interest>& request,
-                ControlParameters& parameters);
-
-  void
-  unregisterEntry(const shared_ptr<const Interest>& request,
-                  ControlParameters& parameters);
-
-private:
-  void
-  onCommandValidated(const shared_ptr<const Interest>& request);
-
-  void
-  onCommandValidationFailed(const shared_ptr<const Interest>& request,
-                            const std::string& failureInfo);
-
-
-  void
-  onCommandError(uint32_t code, const std::string& error,
-                 const shared_ptr<const Interest>& request,
-                 const Route& route);
-
-  void
-  onRegSuccess(const shared_ptr<const Interest>& request,
-               const ControlParameters& parameters,
-               const Route& route);
-
-  void
-  onUnRegSuccess(const shared_ptr<const Interest>& request,
-                 const ControlParameters& parameters,
-                 const Route& route);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
-                                      const ndn::nfd::ControlParameters& result);
-
-private:
-  void
-  onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg);
-
-  void
-  onControlHeaderSuccess();
-
-  void
-  onControlHeaderError(uint32_t code, const std::string& reason);
-
-  static bool
-  extractParameters(const Name::Component& parameterComponent,
-                    ControlParameters& extractedParameters);
-
-  bool
-  validateParameters(const ControlCommand& command,
-                     ControlParameters& parameters);
-
-  void
-  onNotification(const FaceEventNotification& notification);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  onFaceDestroyedEvent(uint64_t faceId);
-
-private:
-  void
-  listEntries(const Interest& request);
-
-  void
-  scheduleActiveFaceFetch(const time::seconds& timeToWait);
-
+private: // Face monitor
   void
   fetchActiveFaces();
 
@@ -190,70 +140,61 @@
   void
   onFetchFaceStatusTimeout();
 
+  void
+  onFaceDestroyedEvent(uint64_t faceId);
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  /** \param buffer Face dataset contents
+  void
+  scheduleActiveFaceFetch(const time::seconds& timeToWait);
+
+  /**
+   * @brief remove invalid faces
+   *
+   * @param buffer Face dataset contents
   */
   void
   removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer);
 
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  Rib m_managedRib;
+  /**
+   * @brief response to face events
+   *
+   * @param notification
+   */
+  void
+  onNotification(const FaceEventNotification& notification);
+
+private:
+  void
+  onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
+                                      const ndn::nfd::ControlParameters& result);
+
+  void
+  onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg);
+
+  void
+  onControlHeaderSuccess();
+
+  void
+  onControlHeaderError(uint32_t code, const std::string& reason);
 
 private:
   ndn::Face& m_face;
   ndn::KeyChain& m_keyChain;
   ndn::nfd::Controller m_nfdController;
+  ndn::nfd::FaceMonitor m_faceMonitor;
   ndn::ValidatorConfig m_localhostValidator;
   ndn::ValidatorConfig m_localhopValidator;
-  ndn::nfd::FaceMonitor m_faceMonitor;
   bool m_isLocalhopEnabled;
   AutoPrefixPropagator m_prefixPropagator;
 
-  RibStatusPublisher m_ribStatusPublisher;
-
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  Rib m_rib;
   FibUpdater m_fibUpdater;
 
 private:
-  typedef function<void(RibManager*,
-                        const shared_ptr<const Interest>& request,
-                        ControlParameters& parameters)> SignedVerbProcessor;
-
-  typedef std::map<name::Component, SignedVerbProcessor> SignedVerbDispatchTable;
-
-  typedef std::pair<name::Component, SignedVerbProcessor> SignedVerbAndProcessor;
-
-
-  const SignedVerbDispatchTable m_signedVerbDispatch;
-
-  static const Name COMMAND_PREFIX; // /localhost/nrd
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  static const Name REMOTE_COMMAND_PREFIX; // /localhop/nrd
-
-private:
-  // number of components in an invalid, but not malformed, unsigned command.
-  // (/localhost/nrd + verb + options) = 4
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed Interest.
-  // 8 with signed Interest support.
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const SignedVerbAndProcessor SIGNED_COMMAND_VERBS[];
-
-  typedef function<void(RibManager*, const Interest&)> UnsignedVerbProcessor;
-  typedef std::map<Name::Component, UnsignedVerbProcessor> UnsignedVerbDispatchTable;
-  typedef std::pair<Name::Component, UnsignedVerbProcessor> UnsignedVerbAndProcessor;
-
-  const UnsignedVerbDispatchTable m_unsignedVerbDispatch;
-  static const UnsignedVerbAndProcessor UNSIGNED_COMMAND_VERBS[];
-
-  static const Name LIST_COMMAND_PREFIX;
-  static const size_t LIST_COMMAND_NCOMPS;
-
+  static const Name LOCAL_HOST_TOP_PREFIX;
+  static const Name LOCAL_HOP_TOP_PREFIX;
   static const Name FACES_LIST_DATASET_PREFIX;
-
   static const time::seconds ACTIVE_FACE_FETCH_INTERVAL;
   scheduler::EventId m_activeFaceFetchEvent;
 
@@ -261,6 +202,8 @@
   /** \brief contains FaceIds with one or more Routes in the RIB
   */
   FaceIdSet m_registeredFaces;
+
+  std::function<void(const Name& topPrefix)> m_addTopPrefix;
 };
 
 } // namespace rib
diff --git a/tests/rib/rib-manager.t.cpp b/tests/rib/rib-manager.t.cpp
index 1287284..0f1e3f7 100644
--- a/tests/rib/rib-manager.t.cpp
+++ b/tests/rib/rib-manager.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,11 +24,12 @@
  */
 
 #include "rib/rib-manager.hpp"
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include "rib/rib-status-publisher-common.hpp"
+#include "manager-common-fixture.hpp"
 
-#include "tests/test-common.hpp"
-#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/management/nfd-rib-entry.hpp>
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/management/nfd-face-event-notification.hpp>
+#include <ndn-cxx/util/random.hpp>
 
 namespace nfd {
 namespace rib {
@@ -36,448 +37,587 @@
 
 using namespace nfd::tests;
 
-class RibManagerFixture : public UnitTestTimeFixture
+struct ConfigurationStatus
 {
-public:
-  RibManagerFixture()
-  {
-    face = ndn::util::makeDummyClientFace(g_io);
-
-    manager = make_shared<RibManager>(*face, keyChain);
-    manager->registerWithNfd();
-
-    advanceClocks(time::milliseconds(1));
-    face->sentInterests.clear();
-  }
-
-  ~RibManagerFixture()
-  {
-    manager.reset();
-    face.reset();
-  }
-
-  void
-  extractParameters(Interest& interest, Name::Component& verb,
-                    ControlParameters& extractedParameters)
-  {
-    const Name& name = interest.getName();
-    verb = name[COMMAND_PREFIX.size()];
-    const Name::Component& parameterComponent = name[COMMAND_PREFIX.size() + 1];
-
-    Block rawParameters = parameterComponent.blockFromValue();
-    extractedParameters.wireDecode(rawParameters);
-  }
-
-  void
-  receiveCommandInterest(const Name& name, ControlParameters& parameters,
-                         uint64_t incomingFaceId = DEFAULT_INCOMING_FACE_ID)
-  {
-    Name commandName = name;
-    commandName.append(parameters.wireEncode());
-
-    Interest commandInterest(commandName);
-    commandInterest.setTag(make_shared<lp::IncomingFaceIdTag>(incomingFaceId));
-
-    manager->m_managedRib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue,
-                                                        this, _1, parameters);
-
-    face->receive(commandInterest);
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  onSendBatchFromQueue(const RibUpdateBatch& batch, const ControlParameters parameters)
-  {
-    BOOST_REQUIRE(batch.begin() != batch.end());
-    RibUpdate update = *(batch.begin());
-
-    Rib::UpdateSuccessCallback managerCallback =
-      bind(&RibManager::onRibUpdateSuccess, manager, update);
-
-    Rib& rib = manager->m_managedRib;
-
-    // Simulate a successful response from NFD
-    FibUpdater& updater = manager->m_fibUpdater;
-    rib.onFibUpdateSuccess(batch, updater.m_inheritedRoutes, managerCallback);
-  }
-
-
-public:
-  shared_ptr<RibManager> manager;
-  shared_ptr<ndn::util::DummyClientFace> face;
-  ndn::KeyChain keyChain;
-
-  static const uint64_t DEFAULT_INCOMING_FACE_ID;
-
-  static const Name COMMAND_PREFIX;
-  static const name::Component ADD_NEXTHOP_VERB;
-  static const name::Component REMOVE_NEXTHOP_VERB;
-
-  static const Name REGISTER_COMMAND;
-  static const Name UNREGISTER_COMMAND;
+  bool isLocalhostConfigured;
+  bool isLocalhopConfigured;
 };
 
-const uint64_t RibManagerFixture::DEFAULT_INCOMING_FACE_ID = 25122;
-const Name RibManagerFixture::COMMAND_PREFIX("/localhost/nfd/rib");
-const name::Component RibManagerFixture::ADD_NEXTHOP_VERB("add-nexthop");
-const name::Component RibManagerFixture::REMOVE_NEXTHOP_VERB("remove-nexthop");
-const Name RibManagerFixture::REGISTER_COMMAND("/localhost/nfd/rib/register");
-const Name RibManagerFixture::UNREGISTER_COMMAND("/localhost/nfd/rib/unregister");
-
-class AuthorizedRibManager : public RibManagerFixture
+class RibManagerFixture : public ManagerCommonFixture
 {
 public:
-  AuthorizedRibManager()
+  explicit
+  RibManagerFixture(const ConfigurationStatus& status,
+                    bool shouldClearRib)
+    : m_commands(m_face->sentInterests)
+    , m_status(status)
+    , m_manager(m_dispatcher, *m_face, m_keyChain)
+    , m_rib(m_manager.m_rib)
   {
-    ConfigFile config;
-    manager->setConfigFile(config);
+    m_rib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue, this, _1);
 
-    const std::string CONFIG_STRING =
-    "rib\n"
-    "{\n"
-    "  localhost_security\n"
+    const std::string prefix = "rib\n{\n";
+    const std::string suffix = "}";
+    const std::string localhostSection = "  localhost_security\n"
     "  {\n"
     "    trust-anchor\n"
     "    {\n"
     "      type any\n"
     "    }\n"
-    "  }"
-    "}";
+    "  }\n";
+    const std::string localhopSection = "  localhop_security\n"
+    "  {\n"
+    "    trust-anchor\n"
+    "    {\n"
+    "      type any\n"
+    "    }\n"
+    "  }\n";
 
-    config.parse(CONFIG_STRING, true, "test-rib");
+    std::string ribSection = "";
+    if (m_status.isLocalhostConfigured) {
+      ribSection += localhostSection;
+    }
+    if (m_status.isLocalhopConfigured) {
+      ribSection += localhopSection;
+    }
+    const std::string CONFIG_STR = prefix + ribSection + suffix;
+
+    ConfigFile config;
+    m_manager.setConfigFile(config);
+    config.parse(CONFIG_STR, true, "test-rib");
+
+    registerWithNfd();
+
+    if (shouldClearRib) {
+      clearRib();
+    }
+  }
+
+private:
+  void
+  registerWithNfd()
+  {
+    m_manager.registerWithNfd();
+    advanceClocks(time::milliseconds(1));
+
+    auto replyFibAddCommand = [this] (const Interest& interest) {
+      nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
+      params.setFaceId(1).setCost(0);
+      nfd::ControlResponse resp;
+
+      resp.setCode(200).setBody(params.wireEncode());
+      shared_ptr<Data> data = make_shared<Data>(interest.getName());
+      data->setContent(resp.wireEncode());
+
+      m_keyChain.sign(*data, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_SHA256));
+
+      m_face->getIoService().post([this, data] { m_face->receive(*data); });
+    };
+
+    Name commandPrefix("/localhost/nfd/fib/add-nexthop");
+    for (auto&& command : m_commands) {
+      if (commandPrefix.isPrefixOf(command.getName())) {
+        replyFibAddCommand(command);
+        advanceClocks(time::milliseconds(1));
+      }
+    }
+
+    // clear commands and responses
+    m_responses.clear();
+    m_commands.clear();
+  }
+
+  void clearRib()
+  {
+    while (!m_rib.empty()) {
+      auto& name = m_rib.begin()->first;
+      auto& routes = m_rib.begin()->second->getRoutes();
+      while (!routes.empty()) {
+        m_rib.erase(name, *routes.begin());
+      }
+    }
+  }
+
+public:
+  ControlParameters
+  makeRegisterParameters(const Name& name, uint64_t id = 0,
+                         const time::milliseconds expiry = time::milliseconds::max())
+  {
+    return ControlParameters()
+      .setName(name)
+      .setFaceId(id)
+      .setOrigin(128)
+      .setCost(10)
+      .setFlags(0)
+      .setExpirationPeriod(expiry);
+  }
+
+  ControlParameters
+  makeUnregisterParameters(const Name& name, uint64_t id = 0)
+  {
+    return ControlParameters()
+      .setName(name)
+      .setFaceId(id)
+      .setOrigin(128);
+  }
+
+  void
+  onSendBatchFromQueue(const RibUpdateBatch& batch)
+  {
+    BOOST_ASSERT(batch.begin() != batch.end());
+    RibUpdate update = *(batch.begin());
+
+    // Simulate a successful response from NFD
+    FibUpdater& updater = m_manager.m_fibUpdater;
+    m_manager.m_rib.onFibUpdateSuccess(batch, updater.m_inheritedRoutes,
+                                              bind(&RibManager::onRibUpdateSuccess, &m_manager, update));
+  }
+
+public:
+  enum class CheckCommandResult {
+    OK,
+    OUT_OF_BOUNDARY,
+    WRONG_FORMAT,
+    WRONG_VERB,
+    WRONG_PARAMS_FORMAT,
+    WRONG_PARAMS_NAME,
+    WRONG_PARAMS_FACE
+   };
+
+  CheckCommandResult
+  checkCommand(size_t idx, const char* verbStr, ControlParameters expectedParams)
+  {
+    if (idx > m_commands.size()) {
+      return CheckCommandResult::OUT_OF_BOUNDARY;
+    }
+    const auto& name = m_commands[idx].getName();
+
+    if (!FIB_COMMAND_PREFIX.isPrefixOf(name) || FIB_COMMAND_PREFIX.size() >= name.size()) {
+      return CheckCommandResult::WRONG_FORMAT;
+    }
+    const auto& verb = name[FIB_COMMAND_PREFIX.size()];
+
+    Name::Component expectedVerb(verbStr);
+    if (verb != expectedVerb) {
+      return CheckCommandResult::WRONG_VERB;
+    }
+
+    ControlParameters parameters;
+    try {
+      Block rawParameters = name[FIB_COMMAND_PREFIX.size() + 1].blockFromValue();
+      parameters.wireDecode(rawParameters);
+    }
+    catch (...) {
+      return CheckCommandResult::WRONG_PARAMS_FORMAT;
+    }
+
+    if (parameters.getName() != expectedParams.getName()) {
+      return CheckCommandResult::WRONG_PARAMS_NAME;
+    }
+
+    if (parameters.getFaceId() != expectedParams.getFaceId()) {
+      return CheckCommandResult::WRONG_PARAMS_FACE;
+    }
+
+    return CheckCommandResult::OK;
+  }
+
+public:
+  std::vector<Interest>& m_commands;
+  ConfigurationStatus m_status;
+  static const Name FIB_COMMAND_PREFIX;
+
+protected:
+  RibManager m_manager;
+  Rib& m_rib;
+};
+
+const Name RibManagerFixture::FIB_COMMAND_PREFIX("/localhost/nfd/fib");
+
+std::ostream&
+operator<<(std::ostream& os, const RibManagerFixture::CheckCommandResult& result)
+{
+  switch (result) {
+  case RibManagerFixture::CheckCommandResult::OK:
+    os << "OK";
+    break;
+  case RibManagerFixture::CheckCommandResult::OUT_OF_BOUNDARY:
+    os << "OUT_OF_BOUNDARY";
+    break;
+  case RibManagerFixture::CheckCommandResult::WRONG_FORMAT:
+    os << "WRONG_FORMAT";
+    break;
+  case RibManagerFixture::CheckCommandResult::WRONG_VERB:
+    os << "WRONG_VERB";
+    break;
+  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FORMAT:
+    os << "WRONG_COST";
+    break;
+  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_NAME:
+    os << "WRONG_PARAMS_NAME";
+    break;
+  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FACE:
+    os << "WRONG_PARAMS_FACE";
+    break;
+  default:
+    break;
+  };
+
+  return os;
+}
+
+BOOST_AUTO_TEST_SUITE(Rib)
+BOOST_AUTO_TEST_SUITE(TestRibManager)
+
+class AddTopPrefixFixture : public RibManagerFixture
+{
+public:
+  AddTopPrefixFixture()
+    : RibManagerFixture({true, true}, false)
+  {
   }
 };
 
-typedef RibManagerFixture UnauthorizedRibManager;
-
-BOOST_FIXTURE_TEST_SUITE(TestRibManager, RibManagerFixture)
-
-BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager)
+BOOST_FIXTURE_TEST_CASE(AddTopPrefix, AddTopPrefixFixture)
 {
-  Name commandName("/localhost/nfd/rib");
-  ndn::nfd::ControlParameters parameters;
+  BOOST_CHECK_EQUAL(m_rib.size(), 2);
 
-  receiveCommandInterest(commandName, parameters);
-  // TODO verify error response
+  std::vector<Name> ribEntryNames;
+  for (auto&& entry : m_rib) {
+    ribEntryNames.push_back(entry.first);
+  }
+  BOOST_CHECK_EQUAL(ribEntryNames[0], "/localhop/nfd");
+  BOOST_CHECK_EQUAL(ribEntryNames[1], "/localhost/nfd");
 }
 
-BOOST_FIXTURE_TEST_CASE(Basic, AuthorizedRibManager)
+class UnauthorizedRibManagerFixture : public RibManagerFixture
 {
-  ControlParameters parameters;
-  parameters
-    .setName("/hello")
-    .setFaceId(1)
-    .setCost(10)
-    .setFlags(0)
-    .setOrigin(128)
-    .setExpirationPeriod(ndn::time::milliseconds::max());
+public:
+  UnauthorizedRibManagerFixture()
+    : RibManagerFixture({false, false}, true)
+  {
+  }
+};
 
-  receiveCommandInterest(REGISTER_COMMAND, parameters);
+class LocalhostAuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  LocalhostAuthorizedRibManagerFixture()
+    : RibManagerFixture({true, false}, true)
+  {
+  }
+};
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+class LocalhopAuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  LocalhopAuthorizedRibManagerFixture()
+    : RibManagerFixture({false, true}, true)
+  {
+  }
+};
+
+class AuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  AuthorizedRibManagerFixture()
+    : RibManagerFixture({true, true}, true)
+  {
+  }
+};
+
+typedef boost::mpl::vector<
+  UnauthorizedRibManagerFixture,
+  LocalhostAuthorizedRibManagerFixture,
+  LocalhopAuthorizedRibManagerFixture,
+  AuthorizedRibManagerFixture
+> AllFixtures;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(CommandAuthorization, T, AllFixtures, T)
+{
+  auto parameters  = this->makeRegisterParameters("/test-authorization", 9527);
+  auto commandHost = this->makeControlCommandRequest("/localhost/nfd/rib/register", parameters);
+  auto commandHop  = this->makeControlCommandRequest("/localhop/nfd/rib/register", parameters);
+  auto successResp = this->makeResponse(200, "Success", parameters);
+  auto failureResp = ControlResponse(403, "authorization rejected");
+
+  BOOST_CHECK_EQUAL(this->m_responses.size(), 0);
+  this->receiveInterest(commandHost);
+  this->receiveInterest(commandHop);
+
+  auto nExpectedResponses = this->m_status.isLocalhopConfigured ? 2 : 1;
+  auto expectedLocalhostResponse = this->m_status.isLocalhostConfigured ? successResp : failureResp;
+  auto expectedLocalhopResponse = this->m_status.isLocalhopConfigured ? successResp : failureResp;
+
+  BOOST_REQUIRE_EQUAL(this->m_responses.size(), nExpectedResponses);
+  BOOST_CHECK_EQUAL(this->checkResponse(0, commandHost->getName(), expectedLocalhostResponse),
+                    ManagerCommonFixture::CheckResponseResult::OK);
+  if (nExpectedResponses == 2) {
+    BOOST_CHECK_EQUAL(this->checkResponse(1, commandHop->getName(), expectedLocalhopResponse),
+                      ManagerCommonFixture::CheckResponseResult::OK);
+  }
 }
 
-BOOST_FIXTURE_TEST_CASE(Register, AuthorizedRibManager)
+BOOST_FIXTURE_TEST_SUITE(RegisterUnregister, LocalhostAuthorizedRibManagerFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
 {
-  ControlParameters parameters;
-  parameters
-    .setName("/hello")
-    .setFaceId(1)
-    .setCost(10)
-    .setFlags(0)
-    .setOrigin(128)
-    .setExpirationPeriod(ndn::time::milliseconds::max());
+  auto paramsRegister    = makeRegisterParameters("/test-register-unregister", 9527);
+  auto paramsUnregister  = makeUnregisterParameters("/test-register-unregister", 9527);
 
-  receiveCommandInterest(REGISTER_COMMAND, parameters);
+  auto setInFaceId = [] (shared_ptr<Interest> commandInterest) {
+    commandInterest->setTag(make_shared<lp::IncomingFaceIdTag>(1234));
+  };
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+  auto commandRegister   = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister, setInFaceId);
+  auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister, setInFaceId);
 
-  Interest& request = face->sentInterests[0];
+  receiveInterest(commandRegister);
+  receiveInterest(commandUnregister);
 
-  ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister->getName(), makeResponse(200, "Success", paramsRegister)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister->getName(), makeResponse(200, "Success", paramsUnregister)),
+                    CheckResponseResult::OK);
 
-  BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
-  BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), parameters.getFaceId());
-  BOOST_CHECK_EQUAL(extractedParameters.getCost(), parameters.getCost());
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
 }
 
-BOOST_FIXTURE_TEST_CASE(Unregister, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(SelfOperation)
 {
-  ControlParameters addParameters;
-  addParameters
-    .setName("/hello")
-    .setFaceId(1)
-    .setCost(10)
-    .setFlags(0)
-    .setOrigin(128)
-    .setExpirationPeriod(ndn::time::milliseconds::max());
+  auto paramsRegister = makeRegisterParameters("/test-self-register-unregister");
+  auto paramsUnregister = makeUnregisterParameters("/test-self-register-unregister");
+  BOOST_CHECK_EQUAL(paramsRegister.getFaceId(), 0);
+  BOOST_CHECK_EQUAL(paramsUnregister.getFaceId(), 0);
 
-  receiveCommandInterest(REGISTER_COMMAND, addParameters);
-  face->sentInterests.clear();
+  const uint64_t inFaceId = 9527;
+  auto setInFaceId = [&inFaceId] (shared_ptr<Interest> commandInterest) {
+    commandInterest->setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));
+  };
+  auto commandRegister   = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister, setInFaceId);
+  auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister, setInFaceId);
 
-  ControlParameters removeParameters;
-  removeParameters
-    .setName("/hello")
-    .setFaceId(1)
-    .setOrigin(128);
+  receiveInterest(commandRegister);
+  receiveInterest(commandUnregister);
 
-  receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
+  paramsRegister.setFaceId(inFaceId);
+  paramsUnregister.setFaceId(inFaceId);
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister->getName(), makeResponse(200, "Success", paramsRegister)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister->getName(), makeResponse(200, "Success", paramsUnregister)),
+                    CheckResponseResult::OK);
 
-  Interest& request = face->sentInterests[0];
-
-  ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
-  BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId());
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
 }
 
-BOOST_FIXTURE_TEST_CASE(SelfRegister, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(Expiration)
 {
-  ControlParameters parameters;
-  parameters
-    .setName("/hello");
+  auto paramsRegister = makeRegisterParameters("/test-expiry", 9527, time::milliseconds(50));
+  auto paramsUnregister = makeRegisterParameters("/test-expiry", 9527);
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));
 
-  receiveCommandInterest(REGISTER_COMMAND, parameters, 10129);
+  advanceClocks(time::milliseconds(55));
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2); // the registered route has expired
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+  m_commands.clear();
+  paramsRegister.setExpirationPeriod(time::milliseconds(100));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));
 
-  Interest& request = face->sentInterests[0];
-
-  ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
-  BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), 10129);
+  advanceClocks(time::milliseconds(55));
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 1); // the registered route is still active
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
 }
 
-BOOST_FIXTURE_TEST_CASE(SelfUnregister, AuthorizedRibManager)
+BOOST_AUTO_TEST_SUITE_END() // RegisterUnregister
+
+// @todo Remove when ndn::nfd::RibEntry implements operator!=
+class RibEntry : public ndn::nfd::RibEntry
 {
-  ControlParameters addParameters;
-  addParameters
-    .setName("/hello")
-    .setFaceId(10129);
+public:
+  RibEntry() = default;
 
-  receiveCommandInterest(REGISTER_COMMAND, addParameters);
-  face->sentInterests.clear();
+  RibEntry(const ndn::nfd::RibEntry& entry)
+    : ndn::nfd::RibEntry(entry)
+  {
+  }
+};
 
-  ControlParameters removeParameters;
-  removeParameters
-    .setName("/hello");
+bool
+operator!=(const RibEntry& left, const RibEntry& right)
+{
+  if (left.getName() != right.getName()) {
+    return true;
+  }
 
-  receiveCommandInterest(UNREGISTER_COMMAND, removeParameters, 10129);
+  auto leftRoutes = left.getRoutes();
+  auto rightRoutes = right.getRoutes();
+  if (leftRoutes.size() != rightRoutes.size()) {
+    return true;
+  }
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+  for (auto&& route : leftRoutes) {
+    auto hitEntry =
+      std::find_if(rightRoutes.begin(), rightRoutes.end(), [&] (const ndn::nfd::Route& record) {
+          return route.getFaceId() == record.getFaceId() &&
+            route.getCost() == record.getCost() &&
+            route.getOrigin() == record.getOrigin() &&
+            route.getFlags() == record.getFlags() &&
+            route.getExpirationPeriod() == record.getExpirationPeriod();
+        });
 
-  Interest& request = face->sentInterests[0];
+    if (hitEntry == rightRoutes.end()) {
+      return true;
+    }
+  }
 
-  ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
-  BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), 10129);
+  return false;
 }
 
-BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager)
+BOOST_FIXTURE_TEST_CASE(RibDataset, UnauthorizedRibManagerFixture)
 {
-  ControlParameters parameters;
-  parameters
-    .setName("/hello")
-    .setFaceId(1)
-    .setCost(10)
-    .setFlags(0)
-    .setOrigin(128)
-    .setExpirationPeriod(ndn::time::milliseconds::max());
+  uint64_t faceId = 0;
+  auto generateRoute = [&faceId] () -> Route {
+    Route route;
+    route.faceId = ++faceId;
+    route.cost = ndn::random::generateWord64();
+    route.expires = time::steady_clock::TimePoint::max();
+    return route;
+  };
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
+  const size_t nEntries = 108;
+  std::set<Name> actualPrefixes;
+  for (size_t i = 0; i < nEntries; ++i) {
+    Name prefix = Name("/test-dataset").appendNumber(i);
+    actualPrefixes.insert(prefix);
+    m_rib.insert(prefix, generateRoute());
+    if (i & 0x1) {
+      m_rib.insert(prefix, generateRoute());
+      m_rib.insert(prefix, generateRoute());
+    }
+  }
 
-  receiveCommandInterest(REGISTER_COMMAND, parameters);
+  receiveInterest(makeInterest("/localhost/nfd/rib/list"));
 
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  std::vector<RibEntry> receivedRecords, expectedRecords;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    RibEntry decodedEntry;
+    BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
+    receivedRecords.push_back(decodedEntry);
+
+    actualPrefixes.erase(decodedEntry.getName());
+
+    auto matchedEntryIt = m_rib.find(decodedEntry.getName());
+    BOOST_REQUIRE(matchedEntryIt != m_rib.end());
+
+    auto matchedEntry = matchedEntryIt->second;
+    BOOST_REQUIRE(matchedEntry != nullptr);
+
+    RibEntry record;
+    record.setName(matchedEntry->getName());
+    const auto& routes = matchedEntry->getRoutes();
+    for (auto&& route : routes) {
+      ndn::nfd::Route routeRecord;
+      routeRecord.setFaceId(route.faceId);
+      routeRecord.setOrigin(route.origin);
+      routeRecord.setFlags(route.flags);
+      routeRecord.setCost(route.cost);
+      record.addRoute(routeRecord);
+    }
+    expectedRecords.push_back(record);
+  }
+
+  BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
+                                expectedRecords.begin(), expectedRecords.end());
 }
 
-BOOST_FIXTURE_TEST_CASE(RibStatusRequest, AuthorizedRibManager)
+BOOST_FIXTURE_TEST_SUITE(FaceMonitor, LocalhostAuthorizedRibManagerFixture)
+
+BOOST_AUTO_TEST_CASE(FetchActiveFacesEvent)
 {
-  Name prefix("/");
+  BOOST_CHECK_EQUAL(m_commands.size(), 0);
 
-  Route route;
-  route.faceId = 1;
-  route.origin = 128;
-  route.cost = 32;
-  route.flags = ndn::nfd::ROUTE_FLAG_CAPTURE;
-
-  manager->m_managedRib.insert(prefix, route);
-
-  face->receive(Interest("/localhost/nfd/rib/list"));
-  advanceClocks(time::milliseconds(1));
-
-  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
-  RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], prefix, route);
+  advanceClocks(time::seconds(301)); // RibManager::ACTIVE_FACE_FETCH_INTERVAL = 300s
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+  BOOST_CHECK_EQUAL(m_commands[0].getName(), "/localhost/nfd/faces/events");
+  BOOST_CHECK_EQUAL(m_commands[1].getName(), "/localhost/nfd/faces/list");
 }
 
-BOOST_FIXTURE_TEST_CASE(CancelExpirationEvent, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(RemoveInvalidFaces)
 {
-  // Register route
-  ControlParameters addParameters;
-  addParameters
-    .setName("/expire")
-    .setFaceId(1)
-    .setCost(10)
-    .setFlags(0)
-    .setOrigin(128)
-    .setExpirationPeriod(ndn::time::milliseconds(500));
+  auto parameters1 = makeRegisterParameters("/test-remove-invalid-faces-1");
+  auto parameters2 = makeRegisterParameters("/test-remove-invalid-faces-2");
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(1)));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(2)));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2.setFaceId(2)));
+  BOOST_REQUIRE_EQUAL(m_rib.size(), 3);
 
-  receiveCommandInterest(REGISTER_COMMAND, addParameters);
-  face->sentInterests.clear();
-
-  // Unregister route
-  ControlParameters removeParameters;
-  removeParameters
-    .setName("/expire")
-    .setFaceId(1)
-    .setOrigin(128);
-
-  receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
-
-  // Reregister route
-  addParameters.setExpirationPeriod(ndn::time::milliseconds::max());
-  receiveCommandInterest(REGISTER_COMMAND, addParameters);
-
-  advanceClocks(time::milliseconds(100), time::seconds(1));
-
-  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-}
-
-BOOST_FIXTURE_TEST_CASE(RemoveInvalidFaces, AuthorizedRibManager)
-{
-  // Register valid face
-  ControlParameters validParameters;
-  validParameters
-    .setName("/test")
-    .setFaceId(1);
-
-  receiveCommandInterest(REGISTER_COMMAND, validParameters);
-
-  // Register invalid face
-  ControlParameters invalidParameters;
-  invalidParameters
-    .setName("/test")
-    .setFaceId(2);
-
-  receiveCommandInterest(REGISTER_COMMAND, invalidParameters);
-
-  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 2);
-
-  // Receive status with only faceId: 1
   ndn::nfd::FaceStatus status;
   status.setFaceId(1);
 
-  shared_ptr<Data> data = nfd::tests::makeData("/localhost/nfd/faces/list");
+  auto data = makeData("/localhost/nfd/faces/list");
   data->setContent(status.wireEncode());
 
-  shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
+  auto buffer = make_shared<ndn::OBufferStream>();
   buffer->write(reinterpret_cast<const char*>(data->getContent().value()),
                 data->getContent().value_size());
 
-  manager->removeInvalidFaces(buffer);
+  m_manager.removeInvalidFaces(buffer);
+  advanceClocks(time::milliseconds(100));
+  BOOST_REQUIRE_EQUAL(m_rib.size(), 1);
 
-  // Run scheduler
-  advanceClocks(time::milliseconds(100), time::seconds(1));
-
-  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-
-  Rib::const_iterator it = manager->m_managedRib.find("/test");
-  BOOST_REQUIRE(it != manager->m_managedRib.end());
-
-  shared_ptr<RibEntry> entry = it->second;
-  BOOST_CHECK_EQUAL(entry->hasFaceId(1), true);
-  BOOST_CHECK_EQUAL(entry->hasFaceId(2), false);
+  auto it1 = m_rib.find("/test-remove-invalid-faces-1");
+  auto it2 = m_rib.find("/test-remove-invalid-faces-2");
+  BOOST_CHECK(it2 == m_rib.end());
+  BOOST_REQUIRE(it1 != m_rib.end());
+  BOOST_CHECK(it1->second->hasFaceId(1));
+  BOOST_CHECK(!it1->second->hasFaceId(2));
 }
 
-BOOST_FIXTURE_TEST_CASE(LocalHopInherit, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(OnNotification)
 {
-  using nfd::rib::RibManager;
+  auto parameters1 = makeRegisterParameters("/test-face-event-notification-1", 1);
+  auto parameters2 = makeRegisterParameters("/test-face-event-notification-2", 1);
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2));
+  BOOST_REQUIRE_EQUAL(m_rib.size(), 2);
 
-  // Simulate NFD response
-  ControlParameters result;
-  result.setFaceId(261);
+  auto makeNotification = [] (ndn::nfd::FaceEventKind eventKind, uint64_t faceId) -> ndn::nfd::FaceEventNotification {
+    ndn::nfd::FaceEventNotification notification;
+    notification.setKind(eventKind).setFaceId(faceId);
+    return notification;
+  };
 
-  manager->onNrdCommandPrefixAddNextHopSuccess(RibManager::REMOTE_COMMAND_PREFIX, result);
+  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_DESTROYED, 1));
+  advanceClocks(time::milliseconds(100));
+  BOOST_CHECK_EQUAL(m_rib.size(), 0);
 
-  // Register route that localhop prefix should inherit
-  ControlParameters parameters;
-  parameters
-    .setName("/localhop/nfd")
-    .setFaceId(262)
-    .setCost(25)
-    .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
-
-  Name commandName("/localhost/nfd/rib/register");
-
-  receiveCommandInterest(commandName, parameters);
-
-  // REMOTE_COMMAND_PREFIX should have its original route and the inherited route
-  auto it = manager->m_managedRib.find(RibManager::REMOTE_COMMAND_PREFIX);
-
-  BOOST_REQUIRE(it != manager->m_managedRib.end());
-  const RibEntry::RouteList& inheritedRoutes = (*(it->second)).getInheritedRoutes();
-
-  BOOST_CHECK_EQUAL(inheritedRoutes.size(), 1);
-  auto routeIt = inheritedRoutes.begin();
-
-  BOOST_CHECK_EQUAL(routeIt->faceId, 262);
-  BOOST_CHECK_EQUAL(routeIt->cost, 25);
+  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_CREATED, 2));
+  advanceClocks(time::milliseconds(100));
+  BOOST_CHECK_EQUAL(m_rib.size(), 0);
 }
 
-BOOST_FIXTURE_TEST_CASE(RouteExpiration, AuthorizedRibManager)
-{
-  // Register route
-  ControlParameters parameters;
-  parameters.setName("/expire")
-            .setExpirationPeriod(ndn::time::milliseconds(500));
+BOOST_AUTO_TEST_SUITE_END() // FaceMonitor
 
-  receiveCommandInterest(REGISTER_COMMAND, parameters);
-  face->sentInterests.clear();
-
-  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-
-  // Route should expire
-  advanceClocks(time::milliseconds(100), time::seconds(1));
-
-  BOOST_CHECK_EQUAL(manager->m_managedRib.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, AuthorizedRibManager)
-{
-  uint64_t faceToDestroy = 128;
-
-  // Register valid face
-  ControlParameters parameters;
-  parameters.setName("/test")
-            .setFaceId(faceToDestroy);
-
-  receiveCommandInterest(REGISTER_COMMAND, parameters);
-  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-
-  // Don't respond with a success message from the FIB
-  manager->m_managedRib.m_onSendBatchFromQueue = nullptr;
-
-  manager->onFaceDestroyedEvent(faceToDestroy);
-  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestRibManager
+BOOST_AUTO_TEST_SUITE_END() // Rib
 
 } // namespace tests
 } // namespace rib
