diff --git a/rib/remote-registrator.cpp b/rib/remote-registrator.cpp
new file mode 100644
index 0000000..2a5a12d
--- /dev/null
+++ b/rib/remote-registrator.cpp
@@ -0,0 +1,423 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California,
+ *                      Arizona Board of Regents,
+ *                      Colorado State University,
+ *                      University Pierre & Marie Curie, Sorbonne University,
+ *                      Washington University in St. Louis,
+ *                      Beijing Institute of Technology,
+ *                      The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "remote-registrator.hpp"
+#include "core/logger.hpp"
+#include "core/scheduler.hpp"
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT("RemoteRegistrator");
+
+using ndn::nfd::ControlParameters;
+using ndn::nfd::CommandOptions;
+
+
+const Name RemoteRegistrator::RM_LOCAL_PREFIX = "/localhost";
+const Name RemoteRegistrator::RM_HUB_PREFIX = "/localhop/nfd";
+const name::Component RemoteRegistrator::RM_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
+        {
+          throw 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(RM_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::registerPrefix(const Name& prefix)
+{
+  if (RM_LOCAL_PREFIX.isPrefixOf(prefix))
+    {
+      NFD_LOG_INFO("local registration only for " << prefix);
+      return;
+    }
+
+  bool isHubPrefix = prefix == RM_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.setSigningIdentity(identity.first),
+                    m_nRetries);
+}
+
+void
+RemoteRegistrator::unregisterPrefix(const Name& prefix)
+{
+  if (prefix == RM_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.setSigningIdentity(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() && RM_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 unregister " << 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.setSigningIdentity(entry.first),
+                        m_nRetries);
+    }
+}
+
+void
+RemoteRegistrator::clearRefreshEvents()
+{
+  for (auto&& entry : m_regEntries)
+    {
+      scheduler::cancel(entry.second);
+    }
+}
+
+} // namespace rib
+} // namespace nfd
