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;
 
