diff --git a/nfd.conf.sample.in b/nfd.conf.sample.in
index 24407c7..682b8e7 100644
--- a/nfd.conf.sample.in
+++ b/nfd.conf.sample.in
@@ -316,14 +316,19 @@
   ;   }
   ; }
 
-  remote_register
+  auto_prefix_propagate
   {
     cost 15 ; forwarding cost of prefix registered on remote router
-    timeout 10000 ; timeout (in milliseconds) of remote prefix registration command
-    retry 0 ; maximum number of retries for each remote prefix registration command
+    timeout 10000 ; timeout (in milliseconds) of prefix registration command for propagation
 
-    refresh_interval 300 ; interval (in seconds) before refreshing the registration
+    refresh_interval 300 ; interval (in seconds) before refreshing the propagation
     ; This setting should be less than face_system.udp.idle_time,
     ; so that the face is kept alive on the remote router.
+
+    base_retry_wait 50 ; base wait time (in seconds) before retrying propagation
+    max_retry_wait 3600 ; maximum wait time (in seconds) before retrying propagation
+    ; for consequent retries, the wait time before each retry is calculated based on the back-off
+    ; policy. Initially, the wait time is set to base_retry_wait, then it will be doubled for every
+    ; retry unless beyond the max_retry_wait, in which case max_retry_wait is set as the wait time.
   }
 }
diff --git a/rib/auto-prefix-propagator.cpp b/rib/auto-prefix-propagator.cpp
new file mode 100644
index 0000000..12344e2
--- /dev/null
+++ b/rib/auto-prefix-propagator.cpp
@@ -0,0 +1,472 @@
+/* -*- 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 "auto-prefix-propagator.hpp"
+#include "core/logger.hpp"
+#include "core/scheduler.hpp"
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <vector>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT("AutoPrefixPropagator");
+
+using ndn::nfd::ControlParameters;
+using ndn::nfd::CommandOptions;
+
+const Name LOCAL_REGISTRATION_PREFIX("/localhost");
+const Name LINK_LOCAL_NFD_PREFIX("/localhop/nfd");
+const name::Component IGNORE_COMMPONENT("nrd");
+const time::seconds PREFIX_PROPAGATION_DEFAULT_REFRESH_INTERVAL = time::seconds(25);
+const time::seconds PREFIX_PROPAGATION_MAX_REFRESH_INTERVAL = time::seconds(600);
+const time::seconds PREFIX_PROPAGATION_DEFAULT_BASE_RETRY_WAIT = time::seconds(50);
+const time::seconds PREFIX_PROPAGATION_DEFAULT_MAX_RETRY_WAIT = time::seconds(3600);
+const uint64_t PREFIX_PROPAGATION_DEFAULT_COST = 15;
+const time::milliseconds PREFIX_PROPAGATION_DEFAULT_TIMEOUT = time::milliseconds(10000);
+
+AutoPrefixPropagator::AutoPrefixPropagator(ndn::nfd::Controller& controller,
+                                           ndn::KeyChain& keyChain,
+                                           Rib& rib)
+  : m_nfdController(controller)
+  , m_keyChain(keyChain)
+  , m_rib(rib)
+  , m_refreshInterval(PREFIX_PROPAGATION_DEFAULT_REFRESH_INTERVAL)
+  , m_baseRetryWait(PREFIX_PROPAGATION_DEFAULT_BASE_RETRY_WAIT)
+  , m_maxRetryWait(PREFIX_PROPAGATION_DEFAULT_MAX_RETRY_WAIT)
+  , m_hasConnectedHub(false)
+{
+}
+
+void
+AutoPrefixPropagator::loadConfig(const ConfigSection& configSection)
+{
+  m_refreshInterval = PREFIX_PROPAGATION_DEFAULT_REFRESH_INTERVAL;
+  m_baseRetryWait = PREFIX_PROPAGATION_DEFAULT_BASE_RETRY_WAIT;
+  m_maxRetryWait = PREFIX_PROPAGATION_DEFAULT_MAX_RETRY_WAIT;
+
+  m_controlParameters
+     .setCost(PREFIX_PROPAGATION_DEFAULT_COST)
+     .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)// set origin to client.
+     .setFaceId(0);// the remote hub will take the input face as the faceId.
+
+   m_commandOptions
+     .setPrefix(LINK_LOCAL_NFD_PREFIX)
+     .setTimeout(PREFIX_PROPAGATION_DEFAULT_TIMEOUT);
+
+  NFD_LOG_INFO("Load auto_prefix_propagate section in rib section");
+
+  for (auto&& i : configSection) {
+    if (i.first == "cost") {
+      m_controlParameters.setCost(i.second.get_value<uint64_t>());
+    }
+    else if (i.first == "timeout") {
+      m_commandOptions.setTimeout(time::milliseconds(i.second.get_value<size_t>()));
+    }
+    else if (i.first == "refresh_interval") {
+      m_refreshInterval = std::min(PREFIX_PROPAGATION_MAX_REFRESH_INTERVAL,
+                                   time::seconds(i.second.get_value<size_t>()));
+    }
+    else if (i.first == "base_retry_wait") {
+      m_baseRetryWait = time::seconds(i.second.get_value<size_t>());
+    }
+    else if (i.first == "max_retry_wait") {
+      m_maxRetryWait = time::seconds(i.second.get_value<size_t>());
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i.first +
+                                              "\" in \"auto_prefix_propagate\" section"));
+    }
+  }
+}
+
+void
+AutoPrefixPropagator::enable()
+{
+  m_afterInsertConnection =
+    m_rib.afterInsertEntry.connect(bind(&AutoPrefixPropagator::afterInsertRibEntry, this, _1));
+  m_afterEraseConnection =
+    m_rib.afterEraseEntry.connect(bind(&AutoPrefixPropagator::afterEraseRibEntry, this, _1));
+}
+
+void
+AutoPrefixPropagator::disable()
+{
+  m_afterInsertConnection.disconnect();
+  m_afterEraseConnection.disconnect();
+}
+
+AutoPrefixPropagator::PrefixPropagationParameters
+AutoPrefixPropagator::getPrefixPropagationParameters(const Name& localRibPrefix)
+{
+  // get all identities from the KeyChain
+  std::vector<Name> identities;
+  m_keyChain.getAllIdentities(identities, false); // get all except the default
+  identities.push_back(m_keyChain.getDefaultIdentity()); // get the default
+
+  // shortest prefix matching to all identies.
+  Name propagatedPrefix, signingIdentity;
+  bool isFound = false;
+  for (auto&& i : identities) {
+    Name prefix = !i.empty() && IGNORE_COMMPONENT == i.at(-1) ? i.getPrefix(-1) : i;
+    if (prefix.isPrefixOf(localRibPrefix) && (!isFound || i.size() < signingIdentity.size())) {
+      isFound = true;
+      propagatedPrefix = prefix;
+      signingIdentity = i;
+    }
+  }
+
+  PrefixPropagationParameters propagateParameters;
+  if (!isFound) {
+    propagateParameters.isValid = false;
+  }
+  else {
+    propagateParameters.isValid = true;
+    propagateParameters.parameters = m_controlParameters;
+    propagateParameters.options = m_commandOptions;
+    propagateParameters.parameters.setName(propagatedPrefix);
+    propagateParameters.options.setSigningInfo(signingByIdentity(signingIdentity));
+  }
+
+  return propagateParameters;
+}
+
+void
+AutoPrefixPropagator::afterInsertRibEntry(const Name& prefix)
+{
+  if (LOCAL_REGISTRATION_PREFIX.isPrefixOf(prefix)) {
+    NFD_LOG_INFO("local registration only for " << prefix);
+    return;
+  }
+
+  if (prefix == LINK_LOCAL_NFD_PREFIX) {
+    NFD_LOG_INFO("this is a prefix registered by some hub: " << prefix);
+
+    m_hasConnectedHub = true;
+    return afterHubConnect();
+  }
+
+  auto propagateParameters = getPrefixPropagationParameters(prefix);
+  if (!propagateParameters.isValid) {
+    NFD_LOG_INFO("no signing identity available for: " << prefix);
+    return;
+  }
+
+  auto entryIt = m_propagatedEntries.find(propagateParameters.parameters.getName());
+  if (entryIt != m_propagatedEntries.end()) {
+    BOOST_ASSERT(!entryIt->second.isNew());
+    NFD_LOG_INFO("prefix has already been propagated: "
+                 << propagateParameters.parameters.getName());
+    return;
+  }
+
+  afterRibInsert(propagateParameters.parameters, propagateParameters.options);
+}
+
+void
+AutoPrefixPropagator::afterEraseRibEntry(const Name& prefix)
+{
+  if (LOCAL_REGISTRATION_PREFIX.isPrefixOf(prefix)) {
+    NFD_LOG_INFO("local unregistration only for " << prefix);
+    return;
+  }
+
+  if (prefix == LINK_LOCAL_NFD_PREFIX) {
+    NFD_LOG_INFO("disconnected to hub with prefix: " << prefix);
+
+    m_hasConnectedHub = false;
+    return afterHubDisconnect();
+  }
+
+  auto propagateParameters = getPrefixPropagationParameters(prefix);
+  if (!propagateParameters.isValid) {
+    NFD_LOG_INFO("no signing identity available for: " << prefix);
+    return;
+  }
+
+  auto entryIt = m_propagatedEntries.find(propagateParameters.parameters.getName());
+  if (entryIt == m_propagatedEntries.end()) {
+    NFD_LOG_INFO("prefix has not been propagated yet: "
+                 << propagateParameters.parameters.getName());
+    return;
+  }
+
+  for (auto&& ribTableEntry : m_rib) {
+    if (propagateParameters.parameters.getName().isPrefixOf(ribTableEntry.first) &&
+        propagateParameters.options.getSigningInfo().getSignerName() ==
+        getPrefixPropagationParameters(ribTableEntry.first)
+          .options.getSigningInfo().getSignerName()) {
+      NFD_LOG_INFO("should be kept for another RIB entry: " << ribTableEntry.first);
+      return;
+    }
+  }
+
+  afterRibErase(propagateParameters.parameters.unsetCost(), propagateParameters.options);
+}
+
+bool
+AutoPrefixPropagator::doesCurrentPropagatedPrefixWork(const Name& prefix)
+{
+  auto propagateParameters = getPrefixPropagationParameters(prefix);
+  if (!propagateParameters.isValid) {
+    // no identity can sign the input prefix
+    return false;
+  }
+
+  // there is at least one identity can sign the input prefix, so the prefix selected for
+  // propagation (i.e., propagateParameters.parameters.getName()) must be a prefix of the input
+  // prefix. Namely it's either equal to the input prefix or a better choice.
+  return propagateParameters.parameters.getName().size() == prefix.size();
+}
+
+void
+AutoPrefixPropagator::redoPropagation(PropagatedEntryIt entryIt,
+                                      const ControlParameters& parameters,
+                                      const CommandOptions& options,
+                                      time::seconds retryWaitTime)
+{
+  if (doesCurrentPropagatedPrefixWork(parameters.getName())) {
+    // PROPAGATED / PROPAGATE_FAIL --> PROPAGATING
+    entryIt->second.startPropagation();
+    return startPropagation(parameters, options, retryWaitTime);
+  }
+
+  NFD_LOG_INFO("current propagated prefix does not work any more");
+  m_propagatedEntries.erase(entryIt);
+
+  // re-handle all locally RIB entries that can be covered by this propagated prefix
+  for (auto&& ribTableEntry : m_rib) {
+    if (parameters.getName().isPrefixOf(ribTableEntry.first)) {
+      afterInsertRibEntry(ribTableEntry.first);
+    }
+  }
+}
+
+void
+AutoPrefixPropagator::startPropagation(const ControlParameters& parameters,
+                                       const CommandOptions& options,
+                                       time::seconds retryWaitTime)
+{
+  NFD_LOG_TRACE("start propagate " << parameters.getName());
+
+  ndn::Scheduler::Event refreshEvent =
+    bind(&AutoPrefixPropagator::onRefreshTimer, this, parameters, options);
+  ndn::Scheduler::Event retryEvent =
+    bind(&AutoPrefixPropagator::onRetryTimer, this, parameters, options,
+         std::min(m_maxRetryWait, retryWaitTime * 2));
+
+  m_nfdController.start<ndn::nfd::RibRegisterCommand>(
+     parameters,
+     bind(&AutoPrefixPropagator::afterPropagateSucceed, this, parameters, options, refreshEvent),
+     bind(&AutoPrefixPropagator::afterPropagateFail,
+          this, _1, _2, parameters, options, retryWaitTime, retryEvent),
+     options);
+}
+
+void
+AutoPrefixPropagator::startRevocation(const ControlParameters& parameters,
+                                      const CommandOptions& options,
+                                      time::seconds retryWaitTime)
+{
+  NFD_LOG_INFO("start revoke propagation of " << parameters.getName());
+
+  m_nfdController.start<ndn::nfd::RibUnregisterCommand>(
+     parameters,
+     bind(&AutoPrefixPropagator::afterRevokeSucceed, this, parameters, options, retryWaitTime),
+     bind(&AutoPrefixPropagator::afterRevokeFail, this, _1, _2, parameters, options),
+     options);
+}
+
+void
+AutoPrefixPropagator::afterRibInsert(const ControlParameters& parameters,
+                                     const CommandOptions& options)
+{
+  BOOST_ASSERT(m_propagatedEntries.find(parameters.getName()) == m_propagatedEntries.end());
+
+  // keep valid entries although there is no connectivity to hub
+  auto& entry = m_propagatedEntries[parameters.getName()]
+    .setSigningIdentity(options.getSigningInfo().getSignerName());
+
+  if (!m_hasConnectedHub) {
+    NFD_LOG_INFO("no hub connected to propagate " << parameters.getName());
+    return;
+  }
+
+  // NEW --> PROPAGATING
+  entry.startPropagation();
+  startPropagation(parameters, options, m_baseRetryWait);
+}
+
+void
+AutoPrefixPropagator::afterRibErase(const ControlParameters& parameters,
+                                    const CommandOptions& options)
+{
+  auto entryIt = m_propagatedEntries.find(parameters.getName());
+  BOOST_ASSERT(entryIt != m_propagatedEntries.end());
+
+  bool hasPropagationSucceeded = entryIt->second.isPropagated();
+
+  // --> "RELEASED"
+  m_propagatedEntries.erase(entryIt);
+
+  if (!m_hasConnectedHub) {
+    NFD_LOG_INFO("no hub connected to revoke propagation of " << parameters.getName());
+    return;
+  }
+
+  if (!hasPropagationSucceeded) {
+    NFD_LOG_INFO("propagation has not succeeded: " << parameters.getName());
+    return;
+  }
+
+  startRevocation(parameters, options, m_baseRetryWait);
+}
+
+void
+AutoPrefixPropagator::afterHubConnect()
+{
+  NFD_LOG_INFO("redo " << m_propagatedEntries.size()
+                       << " propagations when new Hub connectivity is built.");
+
+  std::vector<PropagatedEntryIt> regEntryIterators;
+  for (auto it = m_propagatedEntries.begin() ; it != m_propagatedEntries.end() ; it ++) {
+    BOOST_ASSERT(it->second.isNew());
+    regEntryIterators.push_back(it);
+  }
+
+  for (auto&& it : regEntryIterators) {
+    auto parameters = m_controlParameters;
+    auto options = m_commandOptions;
+
+    redoPropagation(it,
+                     parameters.setName(it->first),
+                     options.setSigningInfo(signingByIdentity(it->second.getSigningIdentity())),
+                     m_baseRetryWait);
+  }
+}
+
+void
+AutoPrefixPropagator::afterHubDisconnect()
+{
+  for (auto&& entry : m_propagatedEntries) {
+    // --> NEW
+    BOOST_ASSERT(!entry.second.isNew());
+    entry.second.initialize();
+  }
+}
+
+void
+AutoPrefixPropagator::afterPropagateSucceed(const ControlParameters& parameters,
+                                            const CommandOptions& options,
+                                            const ndn::Scheduler::Event& refreshEvent)
+{
+  NFD_LOG_TRACE("success to propagate " << parameters.getName());
+
+  auto entryIt = m_propagatedEntries.find(parameters.getName());
+  if (entryIt == m_propagatedEntries.end()) {
+    // propagation should be revoked if this entry has been erased (i.e., be in RELEASED state)
+    NFD_LOG_DEBUG("Already erased!");
+    ControlParameters newParameters = parameters;
+    return startRevocation(newParameters.unsetCost(), options, m_baseRetryWait);
+  }
+
+  // PROPAGATING --> PROPAGATED
+  BOOST_ASSERT(entryIt->second.isPropagating());
+  entryIt->second.succeed(scheduler::schedule(m_refreshInterval, refreshEvent));
+}
+
+void
+AutoPrefixPropagator::afterPropagateFail(uint32_t code, const std::string& reason,
+                                         const ControlParameters& parameters,
+                                         const CommandOptions& options,
+                                         time::seconds retryWaitTime,
+                                         const ndn::Scheduler::Event& retryEvent)
+{
+  NFD_LOG_TRACE("fail to propagate " << parameters.getName()
+                                     << "\n\t reason:" << reason
+                                     << "\n\t retry wait time: " << retryWaitTime);
+
+  auto entryIt = m_propagatedEntries.find(parameters.getName());
+  if (entryIt == m_propagatedEntries.end()) {
+    // current state is RELEASED
+    return;
+  }
+
+  // PROPAGATING --> PROPAGATE_FAIL
+  BOOST_ASSERT(entryIt->second.isPropagating());
+  entryIt->second.fail(scheduler::schedule(retryWaitTime, retryEvent));
+}
+
+void
+AutoPrefixPropagator::afterRevokeSucceed(const ControlParameters& parameters,
+                                         const CommandOptions& options,
+                                         time::seconds retryWaitTime)
+{
+  NFD_LOG_TRACE("success to revoke propagation of " << parameters.getName());
+
+  auto entryIt = m_propagatedEntries.find(parameters.getName());
+  if (m_propagatedEntries.end() != entryIt && !entryIt->second.isPropagateFail()) {
+    // if is not RELEASED or PROPAGATE_FAIL
+    NFD_LOG_DEBUG("propagated entry still exists");
+
+    // PROPAGATING / PROPAGATED --> PROPAGATING
+    BOOST_ASSERT(!entryIt->second.isNew());
+    entryIt->second.startPropagation();
+
+    ControlParameters newParameters = parameters;
+    startPropagation(newParameters.setCost(m_controlParameters.getCost()), options, retryWaitTime);
+  }
+}
+
+void
+AutoPrefixPropagator::afterRevokeFail(uint32_t code, const std::string& reason,
+                                       const ControlParameters& parameters,
+                                       const CommandOptions& options)
+{
+  NFD_LOG_INFO("fail to revoke the propagation of  " << parameters.getName()
+                                                     << "\n\t reason:" << reason);
+}
+
+void
+AutoPrefixPropagator::onRefreshTimer(const ControlParameters& parameters,
+                                     const CommandOptions& options)
+{
+  auto entryIt = m_propagatedEntries.find(parameters.getName());
+  BOOST_ASSERT(entryIt != m_propagatedEntries.end() && entryIt->second.isPropagated());
+  redoPropagation(entryIt, parameters, options, m_baseRetryWait);
+}
+
+void
+AutoPrefixPropagator::onRetryTimer(const ControlParameters& parameters,
+                                   const CommandOptions& options,
+                                   time::seconds retryWaitTime)
+{
+  auto entryIt = m_propagatedEntries.find(parameters.getName());
+  BOOST_ASSERT(entryIt != m_propagatedEntries.end() && entryIt->second.isPropagateFail());
+  redoPropagation(entryIt, parameters, options, retryWaitTime);
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/rib/auto-prefix-propagator.hpp b/rib/auto-prefix-propagator.hpp
new file mode 100644
index 0000000..11ad67f
--- /dev/null
+++ b/rib/auto-prefix-propagator.hpp
@@ -0,0 +1,418 @@
+/* -*- 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_RIB_AUTO_PREFIX_PROPAGATOR_HPP
+#define NFD_RIB_AUTO_PREFIX_PROPAGATOR_HPP
+
+#include "rib.hpp"
+#include "core/config-file.hpp"
+#include "rib-status-publisher.hpp"
+#include "propagated-entry.hpp"
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/management/nfd-controller.hpp>
+#include <ndn-cxx/management/nfd-control-command.hpp>
+#include <ndn-cxx/management/nfd-control-parameters.hpp>
+#include <ndn-cxx/management/nfd-command-options.hpp>
+#include <ndn-cxx/util/signal.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** @brief provides automatic prefix propagation feature
+ *
+ * The AutoPrefixPropagator monitors changes to local RIB, and registers prefixes onto a
+ * connected gateway router (HUB), so that Interests under propagated prefixes will be forwarded
+ * toward the local host by the HUB.
+ *
+ * The route origin of propagated prefix is CLIENT, as shown on the HUB.
+ *
+ * Connectivity to a HUB is indicated with a special RIB entry "ndn:/localhop/nfd".
+ * Currently, the AutoPrefixPropagator can process the connection to at most one HUB.
+ *
+ * For every RIB entry except "ndn:/localhop/nfd" and those starting with "ndn:/localhost", the
+ * AutoPrefixPropagator queries the local KeyChain for signing identities that is authorized
+ * to sign a prefix registration command of a prefix of the RIB prefix.
+ *
+ * If one or more signing identities are found, the identity that can sign a prefix registration
+ * command of the shortest prefix is chosen, and the AutoPrefixPropagator will attempt to
+ * propagte a prefix to the HUB using the shortest prefix. It's noteworthy that no route flags will
+ * be inherited from the local registration.
+ * If no signing identity is available, no prefix of the RIB entry is propagated to the HUB.
+ *
+ * When a RIB entry is erased, the corresponding propagated entry would be revoked,
+ * unless another local RIB entry is causing the propagation of that prefix.
+ *
+ * After a successful propagation, the AutoPrefixPropagator will refresh the propagation
+ * periodically by resending the registration command.
+ *
+ * In case of a failure or timeout in a registration command, the command will be retried with an
+ * exponential back-off strategy.
+ *
+ * The AutoPrefixPropagator can be configured in NFD configuration file, at the
+ * rib.auto_prefix_propagate section.
+ */
+class AutoPrefixPropagator : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  AutoPrefixPropagator(ndn::nfd::Controller& controller,
+                       ndn::KeyChain& keyChain,
+                       Rib& rib);
+  /**
+   * @brief load the "auto_prefix_propagate" section from config file
+   *
+   * @param configSection the sub section in "rib" section.
+   */
+  void
+  loadConfig(const ConfigSection& configSection);
+
+  /**
+   * @brief enable automatic prefix propagation
+   */
+  void
+  enable();
+
+  /**
+   * @brief disable automatic prefix propagation
+   */
+  void
+  disable();
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers
+  /**
+   * When a local RIB prefix triggers prefix propagation, we propagate the shortest identity that
+   * can sign this prefix to the HUB.
+   *
+   * Thus, the propagated prefix does not equal to local RIB prefix.
+   * So it needs separate storage instead of storing within the RIB.
+   *
+   * the propagated prefix is used as the key to retrive the corresponding entry.
+   */
+  typedef std::unordered_map<Name, PropagatedEntry> PropagatedEntryList;
+  typedef PropagatedEntryList::iterator PropagatedEntryIt;
+
+  /**
+   * @brief parameters used by the registration commands for prefix propagation
+   *
+   * consists of a ControlParameters and a CommandOptions, as well as a bool variable indicates
+   * whether this set of parameters is valid (i.e., the signing identity exists)
+   */
+  struct PrefixPropagationParameters
+  {
+    bool isValid;
+    ndn::nfd::ControlParameters parameters;
+    ndn::nfd::CommandOptions options;
+  };
+
+  /**
+   * @brief get the required parameters for prefix propagation.
+   *
+   * given a local RIB prefix @p localRibPrefix, find out, in local KeyChain, a proper identity
+   * whose namespace covers the input prefix. If there is no desired identity, return a invalid
+   * PrefixPropagationParameters.
+   *
+   * Otherwise, set the selected identity as the signing identity in CommandOptions. Meanwhile,
+   * set this identity (or its prefix with the last component eliminated if it ends with "nrd")
+   * as the name of ControlParameters.
+   *
+   * @return the PrefixPropagationParameters.
+   */
+  PrefixPropagationParameters
+  getPrefixPropagationParameters(const Name& localRibPrefix);
+
+  /**
+   * @brief check whether current propagated prefix still works
+   *
+   * the current propagated prefix @p prefix will still work if and only if its corresponding
+   * signing identity still exists and there is no better signing identity covering it.
+   *
+   * @return true if current propagated prefix still works, otherwise false
+   */
+  bool
+  doesCurrentPropagatedPrefixWork(const Name& prefix);
+
+  /**
+   * @brief process re-propagation for the given propagated entry
+   *
+   * This function may be invoked in 3 cases:
+   * 1. After the hub is connected to redo some propagations.
+   * 2. On refresh timer to handle refresh requests.
+   * 3. On retry timer to handle retry requests.
+   *
+   * @param entryIt the propagated entry need to do re-propagation
+   * @param parameters the ControlParameters used by registration commands for propagation
+   * @param options the CommandOptions used for registration commands for propagation
+   * @param retryWaitTime the current wait time before retrying propagation
+   */
+  void
+  redoPropagation(PropagatedEntryIt entryIt,
+                  const ndn::nfd::ControlParameters& parameters,
+                  const ndn::nfd::CommandOptions& options,
+                  time::seconds retryWaitTime);
+
+private:
+  /**
+   * @brief send out the registration command for propagation
+   *
+   * Before sending out the command, two events, for refresh and retry respectively, are
+   * established (but not scheduled) and assigned to two callbacks, afterPropagateSucceed and
+   * afterPropagateFail respectively.
+   *
+   * The retry event requires an argument to define the retry wait time, which is calculated
+   * according to the back-off policy based on current retry wait time @p retryWaitTime and the
+   * maxRetryWait.
+   *
+   * The baseRetryWait and maxRetryWait used in back-off strategy are all configured at
+   * rib.auto_prefix_propagate.base_retry_wait and
+   * rib.auto_prefix_propagate.max_retry_wait respectively
+
+   * @param parameters the ControlParameters used by the registration command for propagation
+   * @param options the CommandOptions used by the registration command for propagation
+   * @param retryWaitTime the current wait time before retrying propagation
+   */
+  void
+  startPropagation(const ndn::nfd::ControlParameters& parameters,
+                   const ndn::nfd::CommandOptions& options,
+                   time::seconds retryWaitTime);
+
+  /**
+   * @brief send out the unregistration command to revoke the corresponding propagation.
+   *
+   * @param parameters the ControlParameters used by the unregistration command for revocation
+   * @param options the CommandOptions used by the unregistration command for revocation
+   * @param retryWaitTime the current wait time before retrying propagation
+   */
+  void
+  startRevocation(const ndn::nfd::ControlParameters& parameters,
+                  const ndn::nfd::CommandOptions& options,
+                  time::seconds retryWaitTime);
+
+  /**
+   * @brief invoked when Rib::afterInsertEntry signal is emitted
+   *
+   * step1: if the local RIB prefix @param prefix is for local use only, return
+   * step2: if the local RIB prefix @param prefix is a hub prefix, invoke afterHubConnect
+   * step3: if no valid PrefixPropagationParameters can be found for the local RIB prefix
+   *        @param prefix, or the propagated prefix has already been processed, return
+   * step4: invoke afterRibInsert
+   */
+  void
+  afterInsertRibEntry(const Name& prefix);
+
+  /**
+   * @brief invoked when Rib::afterEraseEntry signal is emitted
+   *
+   * step1: if local RIB prefix @param prefix is for local use only, return
+   * step2: if local RIB prefix @param prefix is a hub prefix, invoke afterHubDisconnect
+   * step3: if no valid PrefixPropagationParameters can be found for local RIB prefix
+   *        @param prefix, or there are other local RIB prefixes can be covered by the propagated
+   *        prefix, return
+   * step4: invoke afterRibErase
+   */
+  void
+  afterEraseRibEntry(const Name& prefix);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // PropagatedEntry state changes
+  /**
+   * @brief invoked after rib insertion for non-hub prefixes
+   * @pre the PropagatedEntry is in RELEASED state
+   * @post the PropagatedEntry will be in NEW state
+   *
+   * @param parameters the ControlParameters used by registration commands for propagation
+   * @param options the CommandOptions used by registration commands for propagation
+   */
+  void
+  afterRibInsert(const ndn::nfd::ControlParameters& parameters,
+                 const ndn::nfd::CommandOptions& options);
+
+  /**
+   * @brief invoked after rib deletion for non-hub prefixes
+   * @pre the PropagatedEntry is not in RELEASED state
+   * @post the PropagatedEntry will be in RELEASED state
+   *
+   * @param parameters the ControlParameters used by registration commands for propagation
+   * @param options the CommandOptions used by registration commands for propagation
+   */
+  void
+  afterRibErase(const ndn::nfd::ControlParameters& parameters,
+                const ndn::nfd::CommandOptions& options);
+
+  /**
+   * @brief invoked after the hub is connected
+   * @pre the PropagatedEntry is in NEW state or RELEASED state
+   * @post the PropagatedEntry will be in PROPAGATING state or keep in RELEASED state
+   *
+   * call redoPropagation for each propagated entry.
+   */
+  void
+  afterHubConnect();
+
+  /**
+   * @brief invoked after the hub is disconnected
+   * @pre the PropagatedEntry is not in NEW state
+   * @post the PropagatedEntry will be in NEW state or keep in RELEASED state
+   *
+   * for each propagated entry, switch its state to NEW and cancel its event.
+   */
+  void
+  afterHubDisconnect();
+
+  /**
+   * @brief invoked after propagation succeeds
+   * @pre the PropagatedEntry is in PROPAGATING state or RELEASED state
+   * @post the PropagatedEntry will be in PROPAGATED state or keep in RELEASED state
+   *
+   * If the PropagatedEntry does not exist (in RELEASED state), an unregistration command is
+   * sent immediately for revocation.
+   *
+   * If the PropagatedEntry is in PROPAGATING state, switch it to PROPAGATED, and schedule a
+   * refresh timer to redo propagation after a duration, which is configured at
+   * rib.auto_prefix_propagate.refresh_interval.
+   *
+   * Otherwise, make a copy of the ControlParameters @p parameters, unset its Cost field, and then
+   * invoke startRevocation with this new ControlParameters.
+   *
+   * @param parameters the ControlParameters used by the registration command for propagation
+   * @param options the CommandOptions used by the registration command for propagation
+   * @param refreshEvent the event of refreshing propagation
+   */
+  void
+  afterPropagateSucceed(const ndn::nfd::ControlParameters& parameters,
+                        const ndn::nfd::CommandOptions& options,
+                        const ndn::Scheduler::Event& refreshEvent);
+
+  /**
+   * @brief invoked after propagation fails.
+   * @pre the PropagatedEntry is in PROPAGATING state or RELEASED state
+   * @post the PropagatedEntry will be in PROPAGATE_FAIL state or keep in RELEASED state
+   *
+   * If the PropagatedEntry still exists, schedule a retry timer to redo propagation
+   * after a duration defined by current retry time @p retryWaitTime
+   *
+   * @param code error code.
+   * @param reason error reason in string.
+   * @param parameters the ControlParameters used by the registration command for propagation
+   * @param options the CommandOptions used by registration command for propagation
+   * @param retryWaitTime the current wait time before retrying propagation
+   * @param retryEvent the event of retrying propagation
+   */
+  void
+  afterPropagateFail(uint32_t code, const std::string& reason,
+                     const ndn::nfd::ControlParameters& parameters,
+                     const ndn::nfd::CommandOptions& options,
+                     time::seconds retryWaitTime,
+                     const ndn::Scheduler::Event& retryEvent);
+
+  /**
+   * @brief invoked after revocation succeeds
+   * @pre the PropagatedEntry is not in NEW state
+   * @post the PropagatedEntry will be in PROPAGATING state, or keep in PROPAGATE_FAIL state,
+   * or keep in RELEASED state
+   *
+   * If the PropagatedEntry still exists and is not in PROPAGATE_FAIL state, switch it to
+   * PROPAGATING. Then make a copy of the ControlParameters @p parameters, reset its Cost, and
+   * invoke startPropagation with this new ControlParameters.
+   *
+   * @param parameters the ControlParameters used by the unregistration command for revocation
+   * @param options the CommandOptions used by the unregistration command for revocation
+   * @param retryWaitTime the current wait time before retrying propagation
+   */
+  void
+  afterRevokeSucceed(const ndn::nfd::ControlParameters& parameters,
+                     const ndn::nfd::CommandOptions& options,
+                     time::seconds retryWaitTime);
+
+  /**
+   * @brief invoked after revocation fails.
+   *
+   * @param code error code.
+   * @param reason error reason in string.
+   * @param parameters the ControlParameters used by the unregistration command for revocation
+   * @param options the CommandOptions used by the unregistration command for revocation
+   */
+  void
+  afterRevokeFail(uint32_t code, const std::string& reason,
+                  const ndn::nfd::ControlParameters& parameters,
+                  const ndn::nfd::CommandOptions& options);
+
+  /**
+   * @brief invoked when the refresh timer is triggered.
+   * @pre the PropagatedEntry is in PROPAGATED state
+   * @post the PropagatedEntry will be in PROPAGATING state
+   *
+   * call redoPropagation to handle this refresh request
+   *
+   * @param parameters the ControlParameters used by registration commands for propagation
+   * @param options the CommandOptions used by registration commands for propagation
+   */
+  void
+  onRefreshTimer(const ndn::nfd::ControlParameters& parameters,
+                 const ndn::nfd::CommandOptions& options);
+
+  /**
+   * @brief invoked when the retry timer is triggered.
+   * @pre the PropagatedEntry is in PROPAGATE_FAIL state
+   * @post the PropagatedEntry will be in PROPAGATING state
+   *
+   * call redoPropagation to handle this retry request
+   *
+   * @param parameters the ControlParameters used by registration commands for propagation
+   * @param options the CommandOptions used by registration commands for propagation
+   * @param retryWaitTime the current wait time before retrying propagation
+   */
+  void
+  onRetryTimer(const ndn::nfd::ControlParameters& parameters,
+               const ndn::nfd::CommandOptions& options,
+               time::seconds retryWaitTime);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  ndn::nfd::Controller& m_nfdController;
+  ndn::KeyChain& m_keyChain;
+  Rib& m_rib;
+  ndn::util::signal::ScopedConnection m_afterInsertConnection;
+  ndn::util::signal::ScopedConnection m_afterEraseConnection;
+  ndn::nfd::ControlParameters m_controlParameters;
+  ndn::nfd::CommandOptions m_commandOptions;
+  time::seconds m_refreshInterval;
+  time::seconds m_baseRetryWait;
+  time::seconds m_maxRetryWait;
+  bool m_hasConnectedHub;
+  PropagatedEntryList m_propagatedEntries;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_RIB_AUTO_PREFIX_PROPAGATOR_HPP
diff --git a/rib/propagated-entry.cpp b/rib/propagated-entry.cpp
new file mode 100644
index 0000000..8dff54a
--- /dev/null
+++ b/rib/propagated-entry.cpp
@@ -0,0 +1,131 @@
+/* -*- 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 "core/logger.hpp"
+#include "propagated-entry.hpp"
+
+namespace nfd {
+namespace rib {
+
+void
+operator<<(std::ostream& out, PropagationStatus status)
+{
+  switch (status) {
+  case PropagationStatus::NEW:
+    out << "NEW";
+    break;
+  case PropagationStatus::PROPAGATING:
+    out << "PROPAGATING";
+    break;
+  case PropagationStatus::PROPAGATED:
+    out << "PROPAGATED";
+    break;
+  case PropagationStatus::PROPAGATE_FAIL:
+    out << "PROPAGATE_FAIL";
+    break;
+  default:
+    out << "undefined status";
+    break;
+  }
+}
+
+PropagatedEntry::PropagatedEntry()
+  : m_propagationStatus(PropagationStatus::NEW)
+{
+}
+
+PropagatedEntry::PropagatedEntry(const PropagatedEntry& other)
+  : m_signingIdentity(other.m_signingIdentity)
+  , m_propagationStatus(other.m_propagationStatus)
+{
+  BOOST_ASSERT(!other.isPropagated() && !other.isPropagateFail());
+}
+
+PropagatedEntry&
+PropagatedEntry::setSigningIdentity(const Name& identity)
+{
+  m_signingIdentity = identity;
+  return *this;
+}
+
+const Name&
+PropagatedEntry::getSigningIdentity() const
+{
+  return m_signingIdentity;
+}
+
+void
+PropagatedEntry::startPropagation()
+{
+  m_propagationStatus = PropagationStatus::PROPAGATING;
+}
+
+void
+PropagatedEntry::succeed(const scheduler::EventId& event)
+{
+  m_propagationStatus = PropagationStatus::PROPAGATED;
+  m_rePropagateEvent = event;
+}
+
+void
+PropagatedEntry::fail(const scheduler::EventId& event)
+{
+  m_propagationStatus = PropagationStatus::PROPAGATE_FAIL;
+  m_rePropagateEvent = event;
+}
+
+void
+PropagatedEntry::initialize()
+{
+  m_propagationStatus = PropagationStatus::NEW;
+  m_rePropagateEvent.cancel();
+}
+
+bool
+PropagatedEntry::isNew() const
+{
+  return PropagationStatus::NEW == m_propagationStatus;
+}
+
+bool
+PropagatedEntry::isPropagating() const
+{
+  return PropagationStatus::PROPAGATING == m_propagationStatus;
+}
+
+bool
+PropagatedEntry::isPropagated() const
+{
+  return PropagationStatus::PROPAGATED == m_propagationStatus;
+}
+
+bool
+PropagatedEntry::isPropagateFail() const
+{
+  return PropagationStatus::PROPAGATE_FAIL == m_propagationStatus;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/rib/propagated-entry.hpp b/rib/propagated-entry.hpp
new file mode 100644
index 0000000..f4e61dd
--- /dev/null
+++ b/rib/propagated-entry.hpp
@@ -0,0 +1,158 @@
+/* -*- 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_RIB_PROPAGATED_ENTRY_HPP
+#define NFD_RIB_PROPAGATED_ENTRY_HPP
+
+#include "core/scheduler.hpp"
+
+namespace nfd {
+namespace rib {
+
+enum class PropagationStatus {
+  /// initial status
+  NEW,
+  /// is being propagated
+  PROPAGATING,
+  /// has been propagated successfully
+  PROPAGATED,
+  /// has failed in propagation
+  PROPAGATE_FAIL
+};
+
+void
+operator<<(std::ostream& out, PropagationStatus status);
+
+/**
+ * @brief represents an entry for prefix propagation.
+ * @sa http://redmine.named-data.net/issues/3211
+ *
+ * it consists of a PropagationStatus indicates current state of the state machine, as
+ * well as an event scheduled for refresh or retry (i.e., the RefreshTimer and the RetryTimer of
+ * the state machine respectively). Besides, it stores a copy of signing identity for this entry.
+ */
+class PropagatedEntry
+{
+public:
+  PropagatedEntry();
+
+  /**
+   * @pre other is not in PROPAGATED or PROPAGATE_FAIL state
+   */
+  PropagatedEntry(const PropagatedEntry& other);
+
+  PropagatedEntry&
+  operator=(const PropagatedEntry& other) = delete;
+
+  /**
+   * @brief set the signing identity
+   */
+  PropagatedEntry&
+  setSigningIdentity(const Name& identity);
+
+  /**
+   * @brief get the signing identity
+   *
+   * @return the signing identity
+   */
+  const Name&
+  getSigningIdentity() const;
+
+  /**
+   * @brief switch the propagation status to PROPAGATING.
+   *
+   * this is called before start the propagation process of this entry.
+   */
+  void
+  startPropagation();
+
+  /**
+   * @brief switch the propagation status to PROPAGATED, and set the
+   *        rePropagateEvent to @p event for refresh.
+   *
+   * this is called just after this entry is successfully propagated.
+   */
+  void
+  succeed(const scheduler::EventId& event);
+
+  /**
+   * @brief switch the propagation status to PROPAGATE_FAIL, and then set the
+   *        rePropagateEvent to @p event for retry.
+   *
+   * this is called just after propagation for this entry fails.
+   */
+  void
+  fail(const scheduler::EventId& event);
+
+  /**
+   * @brief cancel the events of re-sending propagation commands.
+   *
+   * switch the propagation status to NEW.
+   */
+  void
+  initialize();
+
+  /**
+   * @brief check whether this entry is a new entry.
+   *
+   * @return true if current status is NEW.
+   */
+  bool
+  isNew() const;
+
+  /**
+   * @brief check whether this entry is being propagated.
+   *
+   * @return true if current status is PROPAGATING.
+   */
+  bool
+  isPropagating() const;
+
+  /**
+   * @brief check whether this entry has been successfully propagated.
+   *
+   * @return true if current status is PROPAGATED.
+   */
+  bool
+  isPropagated() const;
+
+  /**
+   * @brief check whether this entry has failed in propagating.
+   *
+   * @return true if current status is PROPAGATE_FAIL.
+   */
+  bool
+  isPropagateFail() const;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  Name m_signingIdentity;
+  scheduler::ScopedEventId m_rePropagateEvent;
+  PropagationStatus m_propagationStatus;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_RIB_PROPAGATED_ENTRY_HPP
diff --git a/rib/remote-registrator.cpp b/rib/remote-registrator.cpp
deleted file mode 100644
index d33ba1b..0000000
--- a/rib/remote-registrator.cpp
+++ /dev/null
@@ -1,446 +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 "remote-registrator.hpp"
-#include "core/logger.hpp"
-#include "core/scheduler.hpp"
-#include <ndn-cxx/security/signing-helpers.hpp>
-
-namespace nfd {
-namespace rib {
-
-NFD_LOG_INIT("RemoteRegistrator");
-
-using ndn::nfd::ControlParameters;
-using ndn::nfd::CommandOptions;
-
-const Name RemoteRegistrator::LOCAL_REGISTRATION_PREFIX = "/localhost";
-const Name RemoteRegistrator::REMOTE_HUB_PREFIX = "/localhop/nfd";
-const name::Component RemoteRegistrator::IGNORE_COMMPONENT("rib");
-
-RemoteRegistrator::RemoteRegistrator(ndn::nfd::Controller& controller,
-                                     ndn::KeyChain& keyChain,
-                                     Rib& rib)
-  : m_nfdController(controller)
-  , m_keyChain(keyChain)
-  , m_rib(rib)
-  , m_refreshInterval(time::seconds(25))
-  , m_hasConnectedHub(false)
-  , m_nRetries(0)
-{
-}
-
-RemoteRegistrator::~RemoteRegistrator()
-{
-  // cancel all periodically refresh events.
-  for (auto&& entry : m_regEntries)
-    {
-      scheduler::cancel(entry.second);
-    }
-}
-
-void
-RemoteRegistrator::loadConfig(const ConfigSection& configSection)
-{
-  size_t cost = 15, timeout = 10000;
-  size_t retry = 0;
-  size_t interval = 0;
-  const size_t intervalDef = 25, intervalMax = 600;
-
-  NFD_LOG_INFO("Load remote_register section in rib section");
-  for (auto&& i : configSection)
-    {
-      if (i.first == "cost")
-        {
-          cost = i.second.get_value<size_t>();
-        }
-      else if (i.first == "timeout")
-        {
-          timeout = i.second.get_value<size_t>();
-        }
-      else if (i.first == "retry")
-        {
-          retry = i.second.get_value<size_t>();
-        }
-      else if (i.first == "refresh_interval")
-        {
-          interval = i.second.get_value<size_t>();
-        }
-      else
-        {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i.first +
-                                                  "\" in \"remote-registrator\" section"));
-        }
-    }
-
-   m_controlParameters
-     .setCost(cost)
-     .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)// set origin to client.
-     .setFaceId(0);// the remote hub will take the input face as the faceId.
-
-   m_commandOptions
-     .setPrefix(REMOTE_HUB_PREFIX)
-     .setTimeout(time::milliseconds(timeout));
-
-   m_nRetries = retry;
-
-   if (interval == 0)
-     {
-       interval = intervalDef;
-     }
-
-   interval = std::min(interval, intervalMax);
-
-   m_refreshInterval = time::seconds(interval);
-}
-
-void
-RemoteRegistrator::enable()
-{
-  // do remote registration after an entry is inserted into the RIB.
-  m_afterInsertConnection =
-    m_rib.afterInsertEntry.connect([this] (const Name& prefix) {
-        registerPrefix(prefix);
-      });
-
-  // do remote unregistration after an entry is erased from the RIB.
-  m_afterEraseConnection =
-    m_rib.afterEraseEntry.connect([this] (const Name& prefix) {
-        unregisterPrefix(prefix);
-      });
-}
-
-void
-RemoteRegistrator::disable()
-{
-  m_afterInsertConnection.disconnect();
-  m_afterEraseConnection.disconnect();
-}
-
-void
-RemoteRegistrator::registerPrefix(const Name& prefix)
-{
-  if (LOCAL_REGISTRATION_PREFIX.isPrefixOf(prefix))
-    {
-      NFD_LOG_INFO("local registration only for " << prefix);
-      return;
-    }
-
-  bool isHubPrefix = prefix == REMOTE_HUB_PREFIX;
-
-  if (isHubPrefix)
-    {
-      NFD_LOG_INFO("this is a prefix registered by some hub: " << prefix);
-
-      m_hasConnectedHub = true;
-
-      redoRegistration();
-      return;
-    }
-
-  if (!m_hasConnectedHub)
-    {
-      NFD_LOG_INFO("no hub connected when registering " << prefix);
-      return;
-    }
-
-  std::pair<Name, size_t> identity = findIdentityForRegistration(prefix);
-
-  if (0 == identity.second)
-    {
-      NFD_LOG_INFO("no proper identity found for registering " << prefix);
-      return;
-    }
-
-  Name prefixForRegistration;
-  if (identity.first.size() == identity.second)
-    {
-      prefixForRegistration = identity.first;
-    }
-  else
-    {
-      prefixForRegistration = identity.first.getPrefix(-1);
-    }
-
-  if (m_regEntries.find(prefixForRegistration) != m_regEntries.end())
-    {
-      NFD_LOG_INFO("registration already in process for " << prefix);
-      return;
-    }
-
-  // make copies of m_controlParameters and m_commandOptions to
-  // avoid unreasonable overwriting during concurrent registration
-  // and unregistration.
-  ControlParameters parameters = m_controlParameters;
-  CommandOptions    options    = m_commandOptions;
-
-  startRegistration(parameters.setName(prefixForRegistration),
-                    options.setSigningInfo(signingByIdentity(identity.first)),
-                    m_nRetries);
-}
-
-void
-RemoteRegistrator::unregisterPrefix(const Name& prefix)
-{
-  if (prefix == REMOTE_HUB_PREFIX)
-    {
-      NFD_LOG_INFO("disconnected to hub with prefix: " << prefix);
-
-      // for phase 1: suppose there is at most one hub connected.
-      // if the hub prefix has been unregistered locally, there may
-      // be no connected hub.
-      m_hasConnectedHub = false;
-
-      clearRefreshEvents();
-      return;
-    }
-
-  if (!m_hasConnectedHub)
-    {
-      NFD_LOG_INFO("no hub connected when unregistering " << prefix);
-      return;
-    }
-
-  std::pair<Name, size_t> identity = findIdentityForRegistration(prefix);
-
-  if (0 == identity.second)
-    {
-      NFD_LOG_INFO("no proper identity found for unregistering " << prefix);
-      return;
-    }
-
-  Name prefixForRegistration;
-  if (identity.first.size() == identity.second)
-    {
-      prefixForRegistration = identity.first;
-    }
-  else
-    {
-      prefixForRegistration = identity.first.getPrefix(-1);
-    }
-
-  RegisteredEntryIt iRegEntry = m_regEntries.find(prefixForRegistration);
-  if (m_regEntries.end() == iRegEntry)
-    {
-      NFD_LOG_INFO("no existing entry found when unregistering " << prefix);
-      return;
-    }
-
-  for (auto&& entry : m_rib)
-    {
-      if (prefixForRegistration.isPrefixOf(entry.first) &&
-          findIdentityForRegistration(entry.first) == identity)
-        {
-          NFD_LOG_INFO("this identity should be kept for other rib entry: "
-                       << entry.first);
-          return;
-        }
-    }
-
-  scheduler::cancel(iRegEntry->second);
-  m_regEntries.erase(iRegEntry);
-
-  // make copies of m_controlParameters and m_commandOptions to
-  // avoid unreasonable overwriting during concurrent registration
-  // and unregistration.
-  ControlParameters parameters = m_controlParameters;
-  CommandOptions    options    = m_commandOptions;
-
-  startUnregistration(parameters.setName(prefixForRegistration).unsetCost(),
-                      options.setSigningInfo(signingByIdentity(identity.first)),
-                      m_nRetries);
-}
-
-std::pair<Name, size_t>
-RemoteRegistrator::findIdentityForRegistration(const Name& prefix)
-{
-  std::pair<Name, size_t> candidateIdentity;
-  std::vector<Name> identities;
-  bool isPrefix = false;
-  size_t maxLength = 0, curLength = 0;
-
-  // get all identies from the key-cahin except the default one.
-  m_keyChain.getAllIdentities(identities, false);
-
-  // get the default identity.
-  identities.push_back(m_keyChain.getDefaultIdentity());
-
-  // longest prefix matching to all indenties.
-  for (auto&& i : identities)
-    {
-      if (!i.empty() && IGNORE_COMMPONENT == i.at(-1))
-        {
-          isPrefix = i.getPrefix(-1).isPrefixOf(prefix);
-          curLength = i.size() - 1;
-        }
-      else
-        {
-          isPrefix = i.isPrefixOf(prefix);
-          curLength = i.size();
-        }
-
-      if (isPrefix && curLength > maxLength)
-        {
-          candidateIdentity.first = i;
-          maxLength = curLength;
-        }
-    }
-
-  candidateIdentity.second = maxLength;
-
-  return candidateIdentity;
-}
-
-void
-RemoteRegistrator::startRegistration(const ControlParameters& parameters,
-                                     const CommandOptions& options,
-                                     int nRetries)
-{
-  NFD_LOG_INFO("start register " << parameters.getName());
-
-  m_nfdController.start<ndn::nfd::RibRegisterCommand>(
-     parameters,
-     bind(&RemoteRegistrator::onRegSuccess,
-          this, parameters, options),
-     bind(&RemoteRegistrator::onRegFailure,
-          this, _1, _2, parameters, options, nRetries),
-     options);
-}
-
-void
-RemoteRegistrator::startUnregistration(const ControlParameters& parameters,
-                                       const CommandOptions& options,
-                                       int nRetries)
-{
-  NFD_LOG_INFO("start unregister " << parameters.getName());
-
-  m_nfdController.start<ndn::nfd::RibUnregisterCommand>(
-     parameters,
-     bind(&RemoteRegistrator::onUnregSuccess,
-          this, parameters, options),
-     bind(&RemoteRegistrator::onUnregFailure,
-          this, _1, _2, parameters, options, nRetries),
-     options);
-}
-
-void
-RemoteRegistrator::onRegSuccess(const ControlParameters& parameters,
-                                const CommandOptions& options)
-{
-  NFD_LOG_INFO("success to register " << parameters.getName());
-
-  RegisteredEntryIt iRegEntry = m_regEntries.find(parameters.getName());
-
-  if (m_regEntries.end() != iRegEntry)
-    {
-      NFD_LOG_DEBUG("Existing Entry: (" << iRegEntry->first
-                                        << ", " << iRegEntry->second
-                                        << ")");
-
-      scheduler::cancel(iRegEntry->second);
-      iRegEntry->second = scheduler::schedule(
-                            m_refreshInterval,
-                            bind(&RemoteRegistrator::startRegistration,
-                                 this, parameters, options, m_nRetries));
-    }
-  else
-    {
-      NFD_LOG_DEBUG("New Entry");
-      m_regEntries.insert(RegisteredEntry(
-                              parameters.getName(),
-                              scheduler::schedule(
-                                m_refreshInterval,
-                                bind(&RemoteRegistrator::startRegistration,
-                                     this, parameters, options, m_nRetries))));
-    }
-}
-
-void
-RemoteRegistrator::onRegFailure(uint32_t code, const std::string& reason,
-                                const ControlParameters& parameters,
-                                const CommandOptions& options,
-                                int nRetries)
-{
-  NFD_LOG_INFO("fail to register " << parameters.getName()
-                                   << "\n\t reason:" << reason
-                                   << "\n\t remain retries:" << nRetries);
-
-  if (nRetries > 0)
-    {
-      startRegistration(parameters, options, nRetries - 1);
-    }
-}
-
-void
-RemoteRegistrator::onUnregSuccess(const ControlParameters& parameters,
-                                  const CommandOptions& options)
-{
-  NFD_LOG_INFO("success to unregister " << parameters.getName());
-}
-
-void
-RemoteRegistrator::onUnregFailure(uint32_t code, const std::string& reason,
-                                  const ControlParameters& parameters,
-                                  const CommandOptions& options,
-                                  int nRetries)
-{
-  NFD_LOG_INFO("fail to unregister " << parameters.getName()
-                                     << "\n\t reason:" << reason
-                                     << "\n\t remain retries:" << nRetries);
-
-  if (nRetries > 0)
-    {
-      startUnregistration(parameters, options, nRetries - 1);
-    }
-}
-
-void
-RemoteRegistrator::redoRegistration()
-{
-  NFD_LOG_INFO("redo " << m_regEntries.size()
-                       << " registration when new Hub connection is built.");
-
-  for (auto&& entry : m_regEntries)
-    {
-      // make copies to avoid unreasonable overwrite.
-      ControlParameters parameters = m_controlParameters;
-      CommandOptions    options    = m_commandOptions;
-      startRegistration(parameters.setName(entry.first),
-                        options.setSigningInfo(signingByIdentity(entry.first)),
-                        m_nRetries);
-    }
-}
-
-void
-RemoteRegistrator::clearRefreshEvents()
-{
-  for (auto&& entry : m_regEntries)
-    {
-      scheduler::cancel(entry.second);
-    }
-}
-
-} // namespace rib
-} // namespace nfd
diff --git a/rib/remote-registrator.hpp b/rib/remote-registrator.hpp
deleted file mode 100644
index 2eea754..0000000
--- a/rib/remote-registrator.hpp
+++ /dev/null
@@ -1,250 +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_RIB_REMOTE_REGISTRATOR_HPP
-#define NFD_RIB_REMOTE_REGISTRATOR_HPP
-
-#include "rib.hpp"
-#include "core/config-file.hpp"
-#include "rib-status-publisher.hpp"
-
-#include <unordered_map>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/management/nfd-controller.hpp>
-#include <ndn-cxx/management/nfd-control-command.hpp>
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
-#include <ndn-cxx/management/nfd-command-options.hpp>
-#include <ndn-cxx/util/signal.hpp>
-
-namespace nfd {
-namespace rib {
-
-/**
- * @brief define the RemoteRegistrator class, which handles
- *        the registration/unregistration to remote hub(s).
- */
-class RemoteRegistrator : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  RemoteRegistrator(ndn::nfd::Controller& controller,
-                    ndn::KeyChain& keyChain,
-                    Rib& rib);
-
-  ~RemoteRegistrator();
-
-  /**
-   * @brief load the "remote_register" section from config file
-   *
-   * @param configSection the sub section in "rib" section.
-   */
-  void
-  loadConfig(const ConfigSection& configSection);
-
-  /**
-   * @brief enable remote registration/unregistration.
-   *
-   */
-  void
-  enable();
-
-  /**
-   * @brief disable remote registration/unregistration.
-   *
-   */
-  void
-  disable();
-
-  /**
-   * @brief register a prefix to remote hub(s).
-   *
-   * For the input prefix, we find the longest identity
-   * in the key-chain that can sign it, and then
-   * register this identity to remote hub(s).
-   *
-   * @param prefix the prefix being registered in local RIB.
-   */
-  void
-  registerPrefix(const Name& prefix);
-
-  /**
-   * @brief unregister a prefix from remote hub(s).
-   *
-   * For the input prefix, if the longest identity can sign it
-   * is already registered remotely, that identity should be
-   * unregistered from remote hub(s).
-   *
-   * @param prefix the prefix being unregistered in local RIB.
-   */
-  void
-  unregisterPrefix(const Name& prefix);
-
-private:
-  /**
-   * @brief find the most proper identity that can sign the
-   *        registration/unregistration command for the input prefix.
-   *
-   * @return the identity and the length of the longest match to the
-   *         input prefix.
-   *
-   * @retval { ignored, 0 } no matching identity
-   */
-  std::pair<Name, size_t>
-  findIdentityForRegistration(const Name& prefix);
-
-  /**
-   * @brief make and send the remote registration command.
-   *
-   * @param nRetries remaining number of retries.
-   */
-  void
-  startRegistration(const ndn::nfd::ControlParameters& parameters,
-                    const ndn::nfd::CommandOptions& options,
-                    int nRetries);
-
-  /**
-   * @brief make and send the remote unregistration command.
-   *
-   * @param nRetries remaining number of retries.
-   */
-  void
-  startUnregistration(const ndn::nfd::ControlParameters& parameters,
-                      const ndn::nfd::CommandOptions& options,
-                      int nRetries);
-  /**
-   * @brief refresh the remotely registered entry if registration
-   *        successes by re-sending the registration command.
-   *
-   * The interval of sending refresh command is defined in the
-   * "remote_register" section of the config file.
-   *
-   * @param parameters the same paremeters from startRegistration.
-   * @param options the same options as in startRegistration.
-   */
-  void
-  onRegSuccess(const ndn::nfd::ControlParameters& parameters,
-               const ndn::nfd::CommandOptions& options);
-
-  /**
-   * @brief retry to send registration command if registration fails.
-   *
-   * the number of retries is defined in the "remote_register"
-   * section of the config file.
-   *
-   * @param code error code.
-   * @param reason error reason in string.
-   * @param parameters the same paremeters from startRegistration.
-   * @param options the same options from startRegistration.
-   * @param nRetries remaining number of retries.
-   */
-  void
-  onRegFailure(uint32_t code, const std::string& reason,
-               const ndn::nfd::ControlParameters& parameters,
-               const ndn::nfd::CommandOptions& options,
-               int nRetries);
-
-  void
-  onUnregSuccess(const ndn::nfd::ControlParameters& parameters,
-                 const ndn::nfd::CommandOptions& options);
-
-  /**
-   * @brief retry to send unregistration command if registration fails.
-   *
-   * the number of retries is defined in the "remote_register"
-   * section of the config file.
-   *
-   * @param code error code.
-   * @param reason error reason in string.
-   * @param parameters the same paremeters as in startRegistration.
-   * @param options the same options as in startRegistration.
-   * @param nRetries remaining number of retries.
-   */
-  void
-  onUnregFailure(uint32_t code, const std::string& reason,
-                 const ndn::nfd::ControlParameters& parameters,
-                 const ndn::nfd::CommandOptions& options,
-                 int nRetries);
-
-  /**
-   * @brief re-register all prefixes
-   *
-   * This is called when a HUB connection is established.
-   */
-  void
-  redoRegistration();
-
-  /**
-   * @brief clear all refresh events
-   *
-   * This is called when all HUB connections are lost.
-   */
-  void
-  clearRefreshEvents();
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  /**
-   * When a locally registered prefix triggles remote
-   * registration, we actually register the longest
-   * identity that can sign this prefix to remote hub(s).
-   *
-   * Thus, the remotely reigstered prefix does not equal
-   * to Route Name. So it needs seperate sotrage instead
-   * of storing within the RIB.
-   */
-  typedef std::unordered_map<Name, scheduler::EventId> RegisteredList;
-  typedef RegisteredList::iterator RegisteredEntryIt;
-  typedef RegisteredList::value_type RegisteredEntry;
-  RegisteredList m_regEntries;
-
-private:
-  ndn::nfd::Controller& m_nfdController;
-  ndn::KeyChain& m_keyChain;
-  Rib& m_rib;
-  ndn::util::signal::ScopedConnection m_afterInsertConnection;
-  ndn::util::signal::ScopedConnection m_afterEraseConnection;
-  ndn::nfd::ControlParameters m_controlParameters;
-  ndn::nfd::CommandOptions m_commandOptions;
-  time::seconds m_refreshInterval;
-  bool m_hasConnectedHub;
-  int m_nRetries;
-
-  static const Name LOCAL_REGISTRATION_PREFIX; // /localhost
-  static const Name REMOTE_HUB_PREFIX; // /localhop/nfd
-  static const name::Component IGNORE_COMMPONENT; // rib
-};
-
-} // namespace rib
-} // namespace nfd
-
-#endif // NFD_RIB_REMOTE_REGISTRATOR_HPP
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index 91f0eda..33d1622 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -81,7 +81,7 @@
   , m_localhopValidator(m_face)
   , m_faceMonitor(m_face)
   , m_isLocalhopEnabled(false)
-  , m_remoteRegistrator(m_nfdController, m_keyChain, m_managedRib)
+  , 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,
@@ -145,7 +145,7 @@
                      bool isDryRun,
                      const std::string& filename)
 {
-  bool isRemoteRegisterEnabled = false;
+  bool isAutoPrefixPropagatorEnabled = false;
 
   for (const auto& item : configSection) {
     if (item.first == "localhost_security") {
@@ -155,24 +155,24 @@
       m_localhopValidator.load(item.second, filename);
       m_isLocalhopEnabled = true;
     }
-    else if (item.first == "remote_register") {
-      m_remoteRegistrator.loadConfig(item.second);
-      isRemoteRegisterEnabled = true;
+    else if (item.first == "auto_prefix_propagate") {
+      m_prefixPropagator.loadConfig(item.second);
+      isAutoPrefixPropagatorEnabled = true;
 
       // Avoid other actions when isDryRun == true
       if (isDryRun) {
         continue;
       }
 
-      m_remoteRegistrator.enable();
+      m_prefixPropagator.enable();
     }
     else {
       BOOST_THROW_EXCEPTION(Error("Unrecognized rib property: " + item.first));
     }
   }
 
-  if (!isRemoteRegisterEnabled) {
-    m_remoteRegistrator.disable();
+  if (!isAutoPrefixPropagatorEnabled) {
+    m_prefixPropagator.disable();
   }
 }
 
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index e38ee3c..d7c6819 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -29,7 +29,7 @@
 #include "rib.hpp"
 #include "core/config-file.hpp"
 #include "rib-status-publisher.hpp"
-#include "remote-registrator.hpp"
+#include "auto-prefix-propagator.hpp"
 #include "fib-updater.hpp"
 
 #include <ndn-cxx/security/validator-config.hpp>
@@ -207,7 +207,7 @@
   ndn::ValidatorConfig m_localhopValidator;
   ndn::nfd::FaceMonitor m_faceMonitor;
   bool m_isLocalhopEnabled;
-  RemoteRegistrator m_remoteRegistrator;
+  AutoPrefixPropagator m_prefixPropagator;
 
   RibStatusPublisher m_ribStatusPublisher;
 
diff --git a/tests/rib/auto-prefix-propagator.t.cpp b/tests/rib/auto-prefix-propagator.t.cpp
new file mode 100644
index 0000000..67e7b1b
--- /dev/null
+++ b/tests/rib/auto-prefix-propagator.t.cpp
@@ -0,0 +1,671 @@
+/* -*- 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 "rib/auto-prefix-propagator.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/identity-management-fixture.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace nfd {
+namespace rib {
+namespace tests {
+
+NFD_LOG_INIT("AutoPrefixPropagatorTest");
+
+const Name TEST_LINK_LOCAL_NFD_PREFIX("/localhop/nfd");
+const time::milliseconds TEST_PREFIX_PROPAGATION_TIMEOUT(1000);
+
+class AutoPrefixPropagatorFixture : public nfd::tests::IdentityManagementFixture
+                                  , public nfd::tests::UnitTestTimeFixture
+{
+public:
+  AutoPrefixPropagatorFixture()
+    : m_face(ndn::util::makeDummyClientFace(nfd::tests::UnitTestTimeFixture::g_io, {true, true}))
+    , m_controller(*m_face, m_keyChain)
+    , m_propagator(m_controller, m_keyChain, m_rib)
+    , m_requests(m_face->sentInterests)
+    , m_entries(m_propagator.m_propagatedEntries)
+  {
+    m_propagator.enable();
+    m_propagator.m_controlParameters
+      .setCost(15)
+      .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)// set origin to client.
+      .setFaceId(0);// the remote hub will take the input face as the faceId.
+    m_propagator.m_commandOptions
+      .setPrefix(TEST_LINK_LOCAL_NFD_PREFIX)
+      .setTimeout(TEST_PREFIX_PROPAGATION_TIMEOUT);
+  }
+
+public: // helpers for test
+  bool
+  insertEntryToRib(const Name& name, const uint64_t& faceId = 0)
+  {
+    if (m_rib.find(name) != m_rib.end()) {
+      NFD_LOG_INFO("RIB entry already exists: " << name);
+      return false;
+    }
+
+    Route route;
+    route.faceId = faceId;
+    m_rib.insert(name, route);
+    advanceClocks(time::milliseconds(1));
+
+    return m_rib.find(name) != m_rib.end(); // return whether afterInserEntry will be triggered
+  }
+
+  bool
+  eraseEntryFromRib(const Name& name)
+  {
+    if (m_rib.find(name) == m_rib.end()) {
+      NFD_LOG_INFO("RIB entry does not exist: " << name);
+      return false;
+    }
+
+    std::vector<Route> routeList;
+    std::copy(m_rib.find(name)->second->begin(), m_rib.find(name)->second->end(),
+              std::back_inserter(routeList));
+    for (auto&& route : routeList) {
+      m_rib.erase(name, route);
+    }
+    advanceClocks(time::milliseconds(1));
+
+    return m_rib.find(name) == m_rib.end(); // return whether afterEraseEntry will be triggered
+  }
+
+  void
+  connectToHub()
+  {
+    insertEntryToRib("/localhop/nfd");
+  }
+
+  void
+  disconnectFromHub()
+  {
+    eraseEntryFromRib("/localhop/nfd");
+  }
+
+public: // helpers for check
+  enum class CheckRequestResult {
+    OK,
+    OUT_OF_BOUNDARY,
+    INVALID_N_COMPONENTS,
+    WRONG_COMMAND_PREFIX,
+    WRONG_VERB,
+    INVALID_PARAMETERS,
+    WRONG_REGISTERING_PREFIX
+  };
+
+  /**
+   * @brief check a request at specified index
+   *
+   * @param idx the index of the specified request in m_requests
+   * @param verb the expected verb of request
+   * @param registeringPrefix the expected registering prefix of request
+
+   * @retval OK the specified request has a valid name, the right verb, a valid ControlParameters
+   *            and the right registering prefix
+   * @retval OUT_OF_BOUNDARY the specified index out of boundary
+   * @retval INVALID_N_COMPONENTS the number of components of the request name is invalid
+   * @retval WRONG_COMMAND_PREFIX the command prefix of the request is wrong
+   * @retval WRONG_VERB the command verb of the request is wrong
+   * @retval INVALID_PARAMETERS no valid parameters can be decoded from the request's name
+   * @retval WRONG_REGISTERING_PREFIX the registering prefix of the request is wrong
+   */
+  CheckRequestResult
+  checkRequest(size_t idx, const std::string& verb, const Name& registeringPrefix)
+  {
+    Name requestName;
+    try {
+      requestName = m_requests.at(idx).getName();
+    }
+    catch (const std::out_of_range&) {
+      return CheckRequestResult::OUT_OF_BOUNDARY;
+    }
+
+    if (requestName.size() < 5) {
+      return CheckRequestResult::INVALID_N_COMPONENTS;
+    }
+
+    if (requestName.getPrefix(2) != TEST_LINK_LOCAL_NFD_PREFIX) {
+      return CheckRequestResult::WRONG_COMMAND_PREFIX;
+    }
+
+    if (requestName.get(3) != Name::Component(verb)) {
+      return CheckRequestResult::WRONG_VERB;
+    }
+
+    ControlParameters parameters;
+    try {
+      parameters.wireDecode(requestName.get(4).blockFromValue());
+    }
+    catch (const tlv::Error&) {
+      return CheckRequestResult::INVALID_PARAMETERS;
+    }
+
+    if (parameters.getName() != registeringPrefix) {
+      return CheckRequestResult::WRONG_REGISTERING_PREFIX;
+    }
+
+    return CheckRequestResult::OK;
+  }
+
+protected:
+  shared_ptr<ndn::util::DummyClientFace>     m_face;
+  ndn::nfd::Controller                       m_controller;
+  Rib                                        m_rib;
+  AutoPrefixPropagator                       m_propagator;
+  std::vector<Interest>&                     m_requests; // store sent out requests
+  AutoPrefixPropagator::PropagatedEntryList& m_entries; // store propagated entries
+};
+
+std::ostream&
+operator<<(std::ostream &os, const AutoPrefixPropagatorFixture::CheckRequestResult& result)
+{
+  switch (result) {
+  case AutoPrefixPropagatorFixture::CheckRequestResult::OK:
+    os << "OK";
+    break;
+  case AutoPrefixPropagatorFixture::CheckRequestResult::OUT_OF_BOUNDARY:
+    os << "OUT_OF_BOUNDARY";
+    break;
+  case AutoPrefixPropagatorFixture::CheckRequestResult::INVALID_N_COMPONENTS:
+    os << "INVALID_N_COMPONENTS";
+    break;
+  case AutoPrefixPropagatorFixture::CheckRequestResult::WRONG_COMMAND_PREFIX:
+    os << "WRONG_COMMAND_PREFIX";
+    break;
+  case AutoPrefixPropagatorFixture::CheckRequestResult::WRONG_VERB:
+    os << "WRONG_VERB";
+    break;
+  case AutoPrefixPropagatorFixture::CheckRequestResult::INVALID_PARAMETERS:
+    os << "INVALID_PARAMETERS";
+    break;
+  case AutoPrefixPropagatorFixture::CheckRequestResult::WRONG_REGISTERING_PREFIX:
+    os << "WRONG_REGISTERING_PREFIX";
+    break;
+  default:
+    break;
+  }
+
+  return os;
+}
+
+BOOST_AUTO_TEST_SUITE(Rib)
+
+BOOST_FIXTURE_TEST_SUITE(TestAutoPrefixPropagator, AutoPrefixPropagatorFixture)
+
+BOOST_AUTO_TEST_CASE(EnableDisable)
+{
+  connectToHub();
+  BOOST_REQUIRE(addIdentity("/test/A"));
+
+  auto testPropagateRevokeBasic = [this] () -> bool {
+    m_propagator.m_propagatedEntries.clear();
+
+    if (!insertEntryToRib("/test/A/app")) {
+      return false;
+    }
+    m_entries["/test/A"].succeed(nullptr);
+    if (!eraseEntryFromRib("/test/A/app")) {
+      return false;
+    }
+    return true;
+  };
+
+  m_propagator.disable();
+  BOOST_REQUIRE(testPropagateRevokeBasic());
+  BOOST_CHECK(m_requests.empty());
+
+  m_propagator.enable();
+  BOOST_REQUIRE(testPropagateRevokeBasic());
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 2);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(1, "unregister", "/test/A"), CheckRequestResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(LoadConfiguration)
+{
+  ConfigFile config;
+  config.addSectionHandler("auto_prefix_propagate",
+                           bind(&AutoPrefixPropagator::loadConfig, &m_propagator, _1));
+
+  const std::string CONFIG_STRING =
+    "auto_prefix_propagate\n"
+    "{\n"
+    "  cost 11\n"
+    "  timeout 22\n"
+    "  refresh_interval 33\n"
+    "  base_retry_wait 44\n"
+    "  max_retry_wait 55\n"
+    "}";
+  config.parse(CONFIG_STRING, true, "test-auto-prefix-propagator");
+
+  BOOST_CHECK_EQUAL(m_propagator.m_controlParameters.getCost(), 11);
+  BOOST_CHECK_EQUAL(m_propagator.m_controlParameters.getOrigin(), ndn::nfd::ROUTE_ORIGIN_CLIENT);
+  BOOST_CHECK_EQUAL(m_propagator.m_controlParameters.getFaceId(), 0);
+
+  BOOST_CHECK_EQUAL(m_propagator.m_commandOptions.getPrefix(), TEST_LINK_LOCAL_NFD_PREFIX);
+  BOOST_CHECK_EQUAL(m_propagator.m_commandOptions.getTimeout(), time::milliseconds(22));
+
+  BOOST_CHECK_EQUAL(m_propagator.m_refreshInterval, time::seconds(33));
+  BOOST_CHECK_EQUAL(m_propagator.m_baseRetryWait, time::seconds(44));
+  BOOST_CHECK_EQUAL(m_propagator.m_maxRetryWait, time::seconds(55));
+}
+
+BOOST_AUTO_TEST_SUITE(Helpers)
+
+BOOST_AUTO_TEST_CASE(GetPrefixPropagationParameters)
+{
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(addIdentity("/test/A/B"));
+  BOOST_REQUIRE(addIdentity("/test/C/nrd"));
+
+  auto parameters1 = m_propagator.getPrefixPropagationParameters("/none/A/B/app");
+  auto parameters2 = m_propagator.getPrefixPropagationParameters("/test/A/B/app");
+  auto parameters3 = m_propagator.getPrefixPropagationParameters("/test/C/D/app");
+
+  BOOST_CHECK(!parameters1.isValid);
+
+  BOOST_CHECK(parameters2.isValid);
+  BOOST_CHECK_EQUAL(parameters2.parameters.getName(), "/test/A");
+  BOOST_CHECK_EQUAL(parameters2.options.getSigningInfo().getSignerName(), "/test/A");
+
+  BOOST_CHECK(parameters3.isValid);
+  BOOST_CHECK_EQUAL(parameters3.parameters.getName(), "/test/C");
+  BOOST_CHECK_EQUAL(parameters3.options.getSigningInfo().getSignerName(), "/test/C/nrd");
+}
+
+BOOST_AUTO_TEST_CASE(CheckCurrentPropagatedPrefix)
+{
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(addIdentity("/test/B/nrd"));
+  BOOST_REQUIRE(addIdentity("/test/A/B"));
+
+  BOOST_CHECK(!m_propagator.doesCurrentPropagatedPrefixWork("/test/E")); // does not exist
+  BOOST_CHECK(!m_propagator.doesCurrentPropagatedPrefixWork("/test/A/B")); // has a better option
+  BOOST_CHECK(m_propagator.doesCurrentPropagatedPrefixWork("/test/A"));
+  BOOST_CHECK(m_propagator.doesCurrentPropagatedPrefixWork("/test/B"));
+}
+
+BOOST_AUTO_TEST_CASE(RedoPropagation)
+{
+  connectToHub();
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(addIdentity("/test/B"));
+  BOOST_REQUIRE(addIdentity("/test/B/C"));
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app"));
+  BOOST_REQUIRE(insertEntryToRib("/test/B/C/app"));
+  BOOST_REQUIRE(insertEntryToRib("/test/B/D/app"));
+
+  auto testRedoPropagation = [this] (const Name& signingIdentity) {
+    m_requests.clear();
+
+    m_entries[signingIdentity].setSigningIdentity(signingIdentity);
+
+    auto parameters = m_propagator.m_controlParameters;
+    auto options = m_propagator.m_commandOptions;
+    ndn::security::SigningInfo info(ndn::security::SigningInfo::SIGNER_TYPE_ID, signingIdentity);
+    m_propagator.redoPropagation(m_entries.find(signingIdentity),
+                                  parameters.setName(signingIdentity),
+                                  options.setSigningInfo(info),
+                                  time::seconds(0));
+    advanceClocks(time::milliseconds(1));
+  };
+
+  testRedoPropagation("/test/A"); // current propagated prefix still works
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+  BOOST_CHECK(m_entries.find("test/A") != m_entries.end());
+
+  BOOST_CHECK_NO_THROW(m_keyChain.deleteIdentity("/test/B"));
+  testRedoPropagation("/test/B"); // signingIdentity no longer exists
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/B/C"), CheckRequestResult::OK);
+  BOOST_CHECK(m_entries.find("/test/B") == m_entries.end());
+  BOOST_CHECK(m_entries.find("/test/B/C") != m_entries.end());
+
+  testRedoPropagation("/test/B"); // no alternative identity
+  BOOST_CHECK(m_requests.empty());
+  BOOST_CHECK(m_entries.find("/test/B") == m_entries.end());
+
+  m_entries["/test/B/C"].succeed(nullptr);
+  testRedoPropagation("/test/B"); // alternative identity has been propagated
+  BOOST_CHECK(m_requests.empty());
+  BOOST_CHECK(m_entries.find("/test/B") == m_entries.end());
+
+  BOOST_REQUIRE(addIdentity("/test/B/"));
+  testRedoPropagation("/test/B/C"); // better option exists: /test/B
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/B"), CheckRequestResult::OK);
+  BOOST_CHECK(m_entries.find("test/B/C") == m_entries.end());
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Helpers
+
+BOOST_AUTO_TEST_SUITE(PropagateRevokeSemantics)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  connectToHub(); // ensure connectivity to the hub
+  BOOST_REQUIRE(addIdentity("/test/A"));
+
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app")); // ensure afterInsertEntry signal emitted
+  m_entries["/test/A"].succeed(nullptr); // ensure there is a valid entry inserted
+  BOOST_REQUIRE(eraseEntryFromRib("/test/A/app")); // ensure afterEraseEntry signal emitted
+
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 2);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(1, "unregister", "/test/A"), CheckRequestResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(LocalPrefix)
+{
+  connectToHub();
+  BOOST_REQUIRE(addIdentity("/localhost/A"));
+
+  BOOST_REQUIRE(insertEntryToRib("/localhost/A/app"));
+  BOOST_CHECK(m_requests.empty());
+
+  m_propagator.m_propagatedEntries["/localhost/A"].succeed(nullptr);
+  BOOST_REQUIRE(eraseEntryFromRib("/localhost/A/app"));
+  BOOST_CHECK(m_requests.empty());
+}
+
+BOOST_AUTO_TEST_CASE(InvalidPropagationParameters)
+{
+  connectToHub();
+
+  // no identity can be found
+  BOOST_CHECK(!m_propagator.getPrefixPropagationParameters("/test/A/app").isValid);
+
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app"));
+  BOOST_CHECK(m_requests.empty());
+
+  m_entries["/test/A"].succeed(nullptr);
+  BOOST_REQUIRE(eraseEntryFromRib("/test/A/app"));
+  BOOST_CHECK(m_requests.empty());
+}
+
+BOOST_AUTO_TEST_CASE(NoHubConnectivity)
+{
+  BOOST_REQUIRE(addIdentity("/test/A"));
+
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app"));
+  BOOST_CHECK(m_requests.empty());
+
+  m_entries["/test/A"].succeed(nullptr);
+  BOOST_REQUIRE(eraseEntryFromRib("/test/A/app"));
+  BOOST_CHECK(m_requests.empty());
+}
+
+BOOST_AUTO_TEST_CASE(PropagatedEntryExists)
+{
+  connectToHub();
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app1"));
+
+  m_requests.clear();
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app2")); // /test/A has been propagated by /test/A/app1
+  BOOST_CHECK(m_requests.empty());
+}
+
+BOOST_AUTO_TEST_CASE(PropagatedEntryShouldKeep)
+{
+  connectToHub();
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app1"));
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app2"));
+
+  m_requests.clear();
+  BOOST_REQUIRE(eraseEntryFromRib("/test/A/app2")); // /test/A should be kept for /test/A/app1
+  BOOST_CHECK(m_requests.empty());
+}
+
+BOOST_AUTO_TEST_CASE(BackOffRetryPolicy)
+{
+  m_propagator.m_commandOptions.setTimeout(time::milliseconds(1));
+  m_propagator.m_baseRetryWait = time::seconds(1);
+  m_propagator.m_maxRetryWait = time::seconds(2);
+
+  connectToHub();
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app"));
+
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+
+  advanceClocks(time::milliseconds(1), 1050); // wait for the 1st retry
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 2);
+  BOOST_CHECK_EQUAL(checkRequest(1, "register", "/test/A"), CheckRequestResult::OK);
+
+  advanceClocks(time::milliseconds(1), 2050); // wait for the 2nd retry, 2 times
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 3);
+  BOOST_CHECK_EQUAL(checkRequest(2, "register", "/test/A"), CheckRequestResult::OK);
+
+  advanceClocks(time::milliseconds(1), 2050); // wait for the 3rd retry, reach the upper bound
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 4);
+  BOOST_CHECK_EQUAL(checkRequest(3, "register", "/test/A"), CheckRequestResult::OK);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // PropagateRevokeSemantics
+
+BOOST_AUTO_TEST_SUITE(PropagatedEntryStateChanges)
+
+BOOST_AUTO_TEST_CASE(AfterRibInsert)
+{
+  BOOST_REQUIRE(addIdentity("/test/A"));
+
+  auto testAfterRibInsert = [this] (const Name& ribEntryPrefix) {
+    m_requests.clear();
+    m_propagator.m_propagatedEntries.clear(); // ensure entry does not exist
+
+    auto propagateParameters = m_propagator.getPrefixPropagationParameters(ribEntryPrefix);
+    m_propagator.afterRibInsert(propagateParameters.parameters, propagateParameters.options);
+    advanceClocks(time::milliseconds(1));
+  };
+
+  testAfterRibInsert("/test/A/app1");
+  BOOST_CHECK(m_requests.empty()); // no connectivity now
+  BOOST_CHECK(m_entries.find("/test/A") != m_entries.end());
+
+  connectToHub();
+  testAfterRibInsert("/test/A/app2");
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+  BOOST_CHECK(m_entries.find("/test/A") != m_entries.end());
+}
+
+BOOST_AUTO_TEST_CASE(AfterRibErase)
+{
+  BOOST_REQUIRE(addIdentity("/test/A"));
+
+  auto testAfterRibInsert = [this] (const Name& localUnregPrefix) {
+    m_requests.clear();
+
+    auto propagateParameters = m_propagator.getPrefixPropagationParameters(localUnregPrefix);
+    m_propagator.afterRibErase(propagateParameters.parameters.unsetCost(),
+                               propagateParameters.options);
+    advanceClocks(time::milliseconds(1));
+  };
+
+  m_entries["/test/A"].succeed(nullptr);
+  testAfterRibInsert("/test/A/app");
+  BOOST_CHECK(m_requests.empty()); // no connectivity
+  BOOST_CHECK(m_entries.find("/test/A") == m_entries.end()); // has been erased
+
+  connectToHub();
+  m_entries["/test/A"].fail(nullptr);
+  testAfterRibInsert("/test/A/app");
+  BOOST_CHECK(m_requests.empty()); // previous propagation has not succeeded
+  BOOST_CHECK(m_entries.find("/test/A") == m_entries.end()); // has been erased
+
+  m_entries["/test/A"].succeed(nullptr);
+  testAfterRibInsert("/test/A/app");
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "unregister", "/test/A"), CheckRequestResult::OK);
+  BOOST_CHECK(m_entries.find("/test/A") == m_entries.end()); // has been erased
+}
+
+BOOST_AUTO_TEST_CASE(AfterHubConnectDisconnect)
+{
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  BOOST_REQUIRE(addIdentity("/test/B"));
+  BOOST_REQUIRE(addIdentity("/test/C"));
+  BOOST_REQUIRE(insertEntryToRib("/test/A/app"));
+  BOOST_REQUIRE(insertEntryToRib("/test/B/app"));
+
+  // recorder the prefixes that will be propagated in order
+  std::vector<Name> propagatedPrefixes;
+
+  BOOST_CHECK(m_requests.empty()); // no request because there is no connectivity to the hub now
+  BOOST_REQUIRE_EQUAL(m_entries.size(), 2); // valid entries will be kept
+
+  connectToHub(); // 2 cached entries will be processed
+  for (auto&& entry : m_entries) {
+    propagatedPrefixes.push_back(entry.first);
+  }
+
+  BOOST_REQUIRE(insertEntryToRib("/test/C/app")); // will be processed directly
+  propagatedPrefixes.push_back("/test/C");
+  BOOST_REQUIRE_EQUAL(m_entries.size(), 3);
+
+  BOOST_REQUIRE(m_entries["/test/A"].isPropagating());
+  BOOST_REQUIRE(m_entries["/test/B"].isPropagating());
+  BOOST_REQUIRE(m_entries["/test/C"].isPropagating());
+
+  disconnectFromHub(); // all 3 entries are initialized
+  BOOST_CHECK(m_entries["/test/A"].isNew());
+  BOOST_CHECK(m_entries["/test/B"].isNew());
+  BOOST_CHECK(m_entries["/test/C"].isNew());
+
+  connectToHub(); // all 3 entries will be processed
+  for (auto&& entry : m_entries) {
+    propagatedPrefixes.push_back(entry.first);
+  }
+
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 6);
+  BOOST_REQUIRE_EQUAL(propagatedPrefixes.size(), 6);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", propagatedPrefixes[0]), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(1, "register", propagatedPrefixes[1]), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(2, "register", propagatedPrefixes[2]), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(3, "register", propagatedPrefixes[3]), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(4, "register", propagatedPrefixes[4]), CheckRequestResult::OK);
+  BOOST_CHECK_EQUAL(checkRequest(5, "register", propagatedPrefixes[5]), CheckRequestResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(AfterPropagateSucceed)
+{
+  bool wasRefreshEventTriggered = false;
+  auto testAfterPropagateSucceed = [&] (const Name& ribEntryPrefix) {
+    m_requests.clear();
+    wasRefreshEventTriggered = false;
+
+    auto propagateParameters = m_propagator.getPrefixPropagationParameters(ribEntryPrefix);
+    m_propagator.afterPropagateSucceed(propagateParameters.parameters, propagateParameters.options,
+                                       [&]{ wasRefreshEventTriggered = true; });
+    advanceClocks(time::milliseconds(1));
+  };
+
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  m_propagator.m_refreshInterval = time::seconds(0); // event will be executed at once
+  m_entries["/test/A"].startPropagation(); // set to be in PROPAGATING state
+
+  testAfterPropagateSucceed("/test/A/app"); // will trigger refresh event
+  BOOST_CHECK(wasRefreshEventTriggered);
+  BOOST_CHECK(m_requests.empty());
+
+  m_entries.erase(m_entries.find("/test/A")); // set to be in RELEASED state
+  testAfterPropagateSucceed("/test/A/app"); // will call startRevocation
+  BOOST_CHECK(!wasRefreshEventTriggered);
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "unregister", "/test/A"), CheckRequestResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(AfterPropagateFail)
+{
+  bool wasRetryEventTriggered = false;
+  auto testAfterPropagateFail = [&] (const Name& ribEntryPrefix) {
+    m_requests.clear();
+    wasRetryEventTriggered = false;
+
+    auto propagateParameters = m_propagator.getPrefixPropagationParameters(ribEntryPrefix);
+    m_propagator.afterPropagateFail(400, "test", propagateParameters.parameters, propagateParameters.options,
+                                     time::seconds(0), [&]{ wasRetryEventTriggered = true; });
+    advanceClocks(time::milliseconds(1));
+  };
+
+  BOOST_REQUIRE(addIdentity("/test/A"));
+  m_entries["/test/A"].startPropagation(); // set to be in PROPAGATING state
+
+  testAfterPropagateFail("/test/A/app"); // will trigger retry event
+  BOOST_CHECK(wasRetryEventTriggered);
+  BOOST_CHECK(m_requests.empty());
+
+  m_entries.erase(m_entries.find("/test/A")); // set to be in RELEASED state
+  testAfterPropagateFail("/test/A/app"); // will do nothing
+  BOOST_CHECK(!wasRetryEventTriggered);
+  BOOST_CHECK(m_requests.empty());
+}
+
+BOOST_AUTO_TEST_CASE(AfterRevokeSucceed)
+{
+  auto testAfterRevokeSucceed = [&] (const Name& ribEntryPrefix) {
+    m_requests.clear();
+    auto propagateParameters = m_propagator.getPrefixPropagationParameters(ribEntryPrefix);
+    m_propagator.afterRevokeSucceed(propagateParameters.parameters,
+                                    propagateParameters.options,
+                                    time::seconds(0));
+    advanceClocks(time::milliseconds(1));
+  };
+
+  BOOST_REQUIRE(addIdentity("/test/A"));
+
+  testAfterRevokeSucceed("/test/A/app"); // in RELEASED state
+  BOOST_CHECK(m_requests.empty());
+
+  m_entries["/test/A"].fail(nullptr); // in PROPAGATE_FAIL state
+  testAfterRevokeSucceed("/test/A/app");
+  BOOST_CHECK(m_requests.empty());
+
+  m_entries["/test/A"].succeed(nullptr); // in PROPAGATED state
+  testAfterRevokeSucceed("/test/A/app");
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+
+  m_entries["/test/A"].startPropagation(); // in PROPAGATING state
+  testAfterRevokeSucceed("/test/A/app");
+  BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
+  BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // PropagatedEntryStateChanges
+
+BOOST_AUTO_TEST_SUITE_END() // TestAutoPrefixPropagator
+BOOST_AUTO_TEST_SUITE_END() // Rib
+
+} // namespace tests
+} // namespace rib
+} // namespace nfd
diff --git a/tests/rib/propagated-entry.t.cpp b/tests/rib/propagated-entry.t.cpp
new file mode 100644
index 0000000..8c8b1d2
--- /dev/null
+++ b/tests/rib/propagated-entry.t.cpp
@@ -0,0 +1,88 @@
+/* -*- 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 "rib/propagated-entry.hpp"
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace rib {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(Rib)
+
+BOOST_FIXTURE_TEST_SUITE(TestPropagatedEntry, nfd::tests::BaseFixture)
+
+BOOST_AUTO_TEST_CASE(Identity)
+{
+  PropagatedEntry entry;
+  BOOST_CHECK(entry.m_signingIdentity.empty());
+
+  entry.setSigningIdentity("/test");
+  BOOST_CHECK_EQUAL(entry.m_signingIdentity, "/test");
+  BOOST_CHECK_EQUAL(entry.getSigningIdentity(), "/test");
+}
+
+BOOST_AUTO_TEST_CASE(Start)
+{
+  PropagatedEntry entry;
+  BOOST_CHECK(!entry.isPropagating());
+
+  entry.startPropagation();
+  BOOST_CHECK_EQUAL(PropagationStatus::PROPAGATING, entry.m_propagationStatus);
+  BOOST_CHECK(entry.isPropagating());
+}
+
+BOOST_AUTO_TEST_CASE(Succeed)
+{
+  PropagatedEntry entry;
+  entry.succeed(nullptr);
+  BOOST_CHECK_EQUAL(PropagationStatus::PROPAGATED, entry.m_propagationStatus);
+  BOOST_CHECK(entry.isPropagated());
+}
+
+BOOST_AUTO_TEST_CASE(Fail)
+{
+  PropagatedEntry entry;
+  entry.fail(nullptr);
+  BOOST_CHECK_EQUAL(PropagationStatus::PROPAGATE_FAIL, entry.m_propagationStatus);
+  BOOST_CHECK(entry.isPropagateFail());
+}
+
+BOOST_AUTO_TEST_CASE(Initialize)
+{
+  PropagatedEntry entry;
+  entry.startPropagation();
+  BOOST_CHECK_EQUAL(PropagationStatus::PROPAGATING, entry.m_propagationStatus);
+
+  entry.initialize();
+  BOOST_CHECK_EQUAL(PropagationStatus::NEW, entry.m_propagationStatus);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestPropagatedEntry
+BOOST_AUTO_TEST_SUITE_END() // Rib
+
+} // namespace tests
+} // namespace rib
+} // namespace nfd
diff --git a/tests/rib/remote-registrator.t.cpp b/tests/rib/remote-registrator.t.cpp
deleted file mode 100644
index dc41cda..0000000
--- a/tests/rib/remote-registrator.t.cpp
+++ /dev/null
@@ -1,520 +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 "rib/remote-registrator.hpp"
-
-#include "tests/limited-io.hpp"
-#include "tests/identity-management-fixture.hpp"
-#include <ndn-cxx/util/dummy-client-face.hpp>
-
-namespace nfd {
-namespace rib {
-namespace tests {
-
-class RemoteRegistratorFixture : public nfd::tests::IdentityManagementFixture
-                               , public nfd::tests::UnitTestTimeFixture
-{
-public:
-  RemoteRegistratorFixture()
-    : face(ndn::util::makeDummyClientFace(getGlobalIoService()))
-    , controller(make_shared<ndn::nfd::Controller>(std::ref(*face), m_keyChain))
-    , remoteRegistrator(make_shared<RemoteRegistrator>(std::ref(*controller),
-                                                       m_keyChain,
-                                                       rib))
-    , COMMAND_PREFIX("/localhop/nfd/rib")
-    , REGISTER_VERB("register")
-    , UNREGISTER_VERB("unregister")
-  {
-    readConfig();
-
-    remoteRegistrator->enable();
-
-    advanceClocks(time::milliseconds(1));
-    face->sentInterests.clear();
-  }
-
-  void
-  readConfig(bool isSetRetry = false)
-  {
-    ConfigFile config;
-    config.addSectionHandler("remote_register",
-                             bind(&RemoteRegistrator::loadConfig, remoteRegistrator, _1));
-
-
-    if (isSetRetry) {
-      const std::string CONFIG_STRING =
-      "remote_register\n"
-      "{\n"
-      "  cost 15\n"
-      "  timeout 1000\n"
-      "  retry 1\n"
-      "  refresh_interval 5\n"
-      "}";
-
-      config.parse(CONFIG_STRING, true, "test-remote-register");
-    }
-    else {
-      const std::string CONFIG_STRING =
-      "remote_register\n"
-      "{\n"
-      "  cost 15\n"
-      "  timeout 100000\n"
-      "  retry 0\n"
-      "  refresh_interval 5\n"
-      "}";
-
-      config.parse(CONFIG_STRING, true, "test-remote-register");
-    }
-  }
-
-  void
-  waitForTimeout()
-  {
-    advanceClocks(time::milliseconds(100), time::seconds(1));
-  }
-
-  void
-  insertEntryWithIdentity(Name identity,
-                          name::Component appName = DEFAULT_APP_NAME,
-                          uint64_t faceId = 0)
-  {
-    BOOST_CHECK_EQUAL(addIdentity(identity), true);
-
-    Route route;
-    route.faceId = faceId;
-
-    rib.insert(identity.append(appName), route);
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  insertEntryWithoutIdentity(Name identity,
-                             name::Component appName = DEFAULT_APP_NAME,
-                             uint64_t faceId = 0)
-  {
-    Route route;
-    route.faceId = faceId;
-
-    rib.insert(identity.append(appName), route);
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  eraseEntryWithIdentity(Name identity,
-                         name::Component appName = DEFAULT_APP_NAME,
-                         uint64_t faceId = 0)
-  {
-    BOOST_CHECK_EQUAL(addIdentity(identity), true);
-
-    Route route;
-    route.faceId = faceId;
-
-    rib.erase(identity.append(appName), route);
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  eraseEntryWithoutIdentity(Name identity,
-                            name::Component appName = DEFAULT_APP_NAME,
-                            uint64_t faceId = 0)
-  {
-    Route route;
-    route.faceId = faceId;
-
-    rib.erase(identity.append(appName), route);
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  eraseFace(uint64_t faceId)
-  {
-    for (const Rib::NameAndRoute& item : rib.findRoutesWithFaceId(faceId)) {
-      rib.erase(item.first, item.second);
-    }
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  connectToHub()
-  {
-    rib.insert(Name("/localhop/nfd"), Route());
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  disconnectToHub()
-  {
-    rib.erase(Name("/localhop/nfd"), Route());
-
-    advanceClocks(time::milliseconds(1));
-  }
-
-  void
-  extractParameters(Interest& interest, Name::Component& verb,
-                    ndn::nfd::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);
-  }
-
-public:
-  Rib rib;
-  shared_ptr<ndn::util::DummyClientFace> face;
-  shared_ptr<ndn::nfd::Controller> controller;
-  shared_ptr<RemoteRegistrator> remoteRegistrator;
-
-  const Name COMMAND_PREFIX;
-  const name::Component REGISTER_VERB;
-  const name::Component UNREGISTER_VERB;
-
-  static const name::Component DEFAULT_APP_NAME;
-};
-
-const name::Component RemoteRegistratorFixture::DEFAULT_APP_NAME("app");
-
-BOOST_FIXTURE_TEST_SUITE(TestRemoteRegistrator, RemoteRegistratorFixture)
-
-BOOST_FIXTURE_TEST_CASE(AutoTest, RemoteRegistratorFixture)
-{
-  BOOST_REQUIRE_EQUAL(1, 1);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterWithoutConnection, RemoteRegistratorFixture)
-{
-  insertEntryWithIdentity("/remote/register");
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterWithoutIdentity, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  insertEntryWithoutIdentity("/remote/register");
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterWithHubPrefix, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterWithLocalPrefix, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  insertEntryWithIdentity("/localhost/prefix");
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterBasic, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identity("/remote/register");
-  insertEntryWithIdentity(identity);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
-
-  Interest& request = face->sentInterests[0];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterAdvanced, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identity("/remote/register");
-  Name identityAddRib("/remote/register/rib");
-  insertEntryWithIdentity(identityAddRib);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
-
-  Interest& request = face->sentInterests[0];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterWithRedundantCallback, RemoteRegistratorFixture)
-{
-  remoteRegistrator->enable();
-
-  connectToHub();
-
-  Name identity("/remote/register");
-  insertEntryWithIdentity(identity);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
-
-  Interest& request = face->sentInterests[0];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(RegisterRetry, RemoteRegistratorFixture)
-{
-  // setRetry
-  readConfig(true);
-
-  connectToHub();
-
-  Name identity("/remote/register");
-  insertEntryWithIdentity(identity);
-
-  waitForTimeout();
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
-
-  Interest& requestFirst  = face->sentInterests[0];
-  Interest& requestSecond = face->sentInterests[1];
-
-  ndn::nfd::ControlParameters extractedParametersFirst, extractedParametersSecond;
-  Name::Component verbFirst, verbSecond;
-  extractParameters(requestFirst,  verbFirst,  extractedParametersFirst);
-  extractParameters(requestSecond, verbSecond, extractedParametersSecond);
-
-  BOOST_CHECK_EQUAL(verbFirst,  REGISTER_VERB);
-  BOOST_CHECK_EQUAL(verbSecond, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParametersFirst.getName(),  identity);
-  BOOST_CHECK_EQUAL(extractedParametersSecond.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(UnregisterWithoutInsert, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  eraseEntryWithIdentity("/remote/register");
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(UnregisterWithoutConnection, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  disconnectToHub();
-
-  Name indentity("/remote/register");
-  remoteRegistrator->m_regEntries.insert(
-            nfd::rib::RemoteRegistrator::RegisteredEntry(indentity, scheduler::EventId()));
-
-  eraseEntryWithIdentity(indentity);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(UnregisterWithoutSuccessfullRegistration,
-                        RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identity("/remote/register");
-
-  insertEntryWithIdentity(identity);
-
-  eraseEntryWithIdentity(identity);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
-
-  Interest& request = face->sentInterests[0];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(UnregisterBasic, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identity("/remote/register");
-
-  insertEntryWithIdentity(identity);
-
-  scheduler::EventId event;
-
-  remoteRegistrator->m_regEntries.insert(
-          nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
-
-  eraseEntryWithIdentity(identity);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
-
-  Interest& request = face->sentInterests[1];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(UnregisterAdvanced, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identityShort("/remote/register");
-  Name identityLong("/remote/register/long");
-
-  scheduler::EventId eventShort;
-  scheduler::EventId eventLong;
-
-  insertEntryWithIdentity(identityShort, name::Component("appA"));
-
-  remoteRegistrator->m_regEntries.insert(
-          nfd::rib::RemoteRegistrator::RegisteredEntry(identityShort,
-                                                       eventShort));
-
-  insertEntryWithIdentity(identityShort, name::Component("appB"));
-
-  insertEntryWithIdentity(identityLong);
-
-  remoteRegistrator->m_regEntries.insert(
-          nfd::rib::RemoteRegistrator::RegisteredEntry(identityLong,
-                                                       eventLong));
-
-  // two registration commands are generated for identityShort and identityLong
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
-
-  eraseEntryWithIdentity(identityShort, name::Component("appA"));
-
-  // no unregistration command is generated as appB also exists
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
-
-  eraseEntryWithIdentity(identityShort, name::Component("appB"));
-
-  // one unregistration command is generated for identityShort
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 3);
-
-  Interest& request = face->sentInterests[2];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identityShort);
-}
-
-BOOST_FIXTURE_TEST_CASE(EraseFace, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identity("/remote/register");
-  uint64_t faceId = 517;
-
-  insertEntryWithIdentity(identity, DEFAULT_APP_NAME, faceId);
-
-  scheduler::EventId event;
-
-  remoteRegistrator->m_regEntries.insert(
-          nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
-
-  eraseFace(faceId);
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
-
-  Interest& request = face->sentInterests[1];
-
-  ndn::nfd::ControlParameters extractedParameters;
-  Name::Component verb;
-  extractParameters(request, verb, extractedParameters);
-
-  BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
-}
-
-BOOST_FIXTURE_TEST_CASE(RebuildConnection, RemoteRegistratorFixture)
-{
-  connectToHub();
-
-  Name identity("/remote/register");
-
-  insertEntryWithIdentity(identity);
-
-  scheduler::EventId event;
-
-  remoteRegistrator->m_regEntries.insert(
-          nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
-
-  disconnectToHub();
-
-  connectToHub();
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
-
-  Interest& request1 = face->sentInterests[0];
-  Interest& request2 = face->sentInterests[1];
-
-  ndn::nfd::ControlParameters extractedParameters1, extractedParameters2;
-  Name::Component verb1, verb2;
-  extractParameters(request1, verb1, extractedParameters1);
-  extractParameters(request2, verb2, extractedParameters2);
-
-  BOOST_CHECK_EQUAL(verb1, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(verb2, REGISTER_VERB);
-  BOOST_CHECK_EQUAL(extractedParameters1.getName(),
-                    extractedParameters2.getName());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace rib
-} // namespace nfd
