diff --git a/rib/.waf-tools/flags.py b/rib/.waf-tools/flags.py
deleted file mode 100644
index dea80b8..0000000
--- a/rib/.waf-tools/flags.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-from waflib import Logs, Configure
-
-def configure(conf):
-    areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
-    if conf.options.debug:
-        conf.define('_DEBUG', 1)
-        defaultFlags = ['-O0', '-g3',
-                        '-Werror',
-                        '-Wall',
-                        '-fcolor-diagnostics', # only clang supports
-
-                        # # to disable known warnings
-                        # '-Wno-unused-variable', # cryptopp
-                        # '-Wno-unused-function',
-                        # '-Wno-deprecated-declarations',
-                        ]
-
-        if areCustomCxxflagsPresent:
-            missingFlags = [x for x in defaultFlags if x not in conf.env.CXXFLAGS]
-            if len(missingFlags) > 0:
-                Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'"
-                           % " ".join(conf.env.CXXFLAGS))
-                Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags))
-        else:
-            conf.add_supported_cxxflags(cxxflags=defaultFlags)
-    else:
-        defaultFlags = ['-O2', '-g', '-Wall',
-
-                        # # to disable known warnings
-                        # '-Wno-unused-variable', # cryptopp
-                        # '-Wno-unused-function',
-                        # '-Wno-deprecated-declarations',
-                        ]
-        if not areCustomCxxflagsPresent:
-            conf.add_supported_cxxflags(cxxflags=defaultFlags)
-
-@Configure.conf
-def add_supported_cxxflags(self, cxxflags):
-    """
-    Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
-    """
-    self.start_msg('Checking allowed flags for c++ compiler')
-
-    supportedFlags = []
-    for flag in cxxflags:
-        if self.check_cxx (cxxflags=[flag], mandatory=False):
-            supportedFlags += [flag]
-
-    self.end_msg (' '.join (supportedFlags))
-    self.env.CXXFLAGS += supportedFlags
diff --git a/rib/INSTALL.md b/rib/INSTALL.md
deleted file mode 100644
index 868a8d1..0000000
--- a/rib/INSTALL.md
+++ /dev/null
@@ -1,16 +0,0 @@
-## Prerequisites
-
-* Boost libraries >= 1.48
-* [NDN-CPP-dev library](https://github.com/named-data/ndn-cpp-dev)
-* `pkg-config`
-
-## Build
-
-The following commands should be used to build NRD:
-
-    ./waf configure
-    ./waf
-
-If NRD needs to be installed
-
-    sudo ./waf install
diff --git a/rib/README.md b/rib/README.md
deleted file mode 100644
index fbbe11a..0000000
--- a/rib/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-NRD (NDN Routing Daemon)
-========================
-NRD works in parallel with NFD and provides services for prefix registration.
-
-For installation details please see INSTALL.md.
-
-## Default Paths
-
-This README uses `SYSCONFDIR` when referring to the default locations of
-various configuration files.  By default, `SYSCONFDIR` is set to
-`/usr/local/etc`.  If you override just `PREFIX`, then `SYSCONFDIR` will
-default to `PREFIX/etc`.
-
-You may override `SYSCONFDIR` and/or `PREFIX` by specifying their
-corresponding options during configuration:
-
-    ./waf configure --prefix <path/for/prefix> --sysconfdir <some/other/path>
-
-## Running and Configuring NRD
-
-NRD's runtime settings may be modified via configuration file.  After
-installation, a working sample configuration is provided at
-`SYSCONFDIR/ndn/nrd.conf.sample`. At startup, NRD will attempt to
-read the default configuration file from following location:
-`SYSCONFDIR/ndn/nrd.conf`.
-
-You may also specify an alternative configuration file location
-by running NRD with:
-
-    nrd --config </path/to/nrd.conf>
-
-Currently, nrd.conf contains only a security section, which is well documented
-in the sample configuration file.
-
-## Starting experiments
-
-1. Build, install and setup NFD by following the directions provided in
-README.md in NFD root folder.
-
-2. Create certificates by following the instructions in NFD's README.md
-
-3. Build and install NRD by following the directions in INSTALL.md
-
-4. Create nrd.conf file. You can simply copy the provided sample file in
-`SYSCONFDIR/ndn/nrd.conf`.
-
-5. Setup the trust-anchors in nrd.conf. Ideally, the prefix registration
-Interest should be signed by application/user key, and this application/user
-key should be used as trust-anchor. However, currently the default certificate
-is used to sign the registration Interests. Therefore, for initial testing the
-default certificate should be set as the trust-anchor. For doing so, the default
-certificate should be copied in the same folder where the nrd.conf is.
-Secondly, the trust-anchor should point to the copied certificate in nrd.conf.
-To know the id of default certificate you can use:
-
-    ~$ ndnsec-get-default
-
-6. Start NFD (assuming the NFD's conf file exist in `SYSCONFDIR/ndn/nfd.conf`):
-
-    ~$ nfd
-
-7. Start NRD (assuming the conf file exist in `SYSCONFDIR/ndn/nrd.conf`):
-
-    ~$ nrd
-
-8. Try to connect any application to NFD. For example, producer application that is provided
-ndn-cpp-dev examples.
diff --git a/rib/main.cpp b/rib/main.cpp
new file mode 100644
index 0000000..7eddfdd
--- /dev/null
+++ b/rib/main.cpp
@@ -0,0 +1,257 @@
+/* -*- 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 <getopt.h>
+
+#include "common.hpp"
+#include "rib-manager.hpp"
+#include "core/config-file.hpp"
+#include "core/logger.hpp"
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT("nrd.Main");
+
+struct ProgramOptions
+{
+  bool showUsage;
+  bool showModules;
+  std::string config;
+};
+
+class Nrd : noncopyable
+{
+public:
+  void
+  initialize(const std::string& configFile)
+  {
+    initializeLogging(configFile);
+
+    m_ribManager = make_shared<RibManager>();
+
+    ConfigFile config;
+    m_ribManager->setConfigFile(config);
+    config.addSectionHandler("log", bind(std::plus<int>(), 0, 0)); // no-op
+
+    // parse config file
+    config.parse(configFile, true);
+    config.parse(configFile, false);
+
+    m_ribManager->registerWithNfd();
+    m_ribManager->enableLocalControlHeader();
+  }
+
+  void
+  initializeLogging(const std::string& configFile)
+  {
+    ConfigFile config;
+    LoggerFactory::getInstance().setConfigFile(config);
+
+    for (size_t i = 0; i < N_SUPPORTED_CONFIG_SECTIONS; ++i)
+      {
+        if (SUPPORTED_CONFIG_SECTIONS[i] != "log")
+          {
+            config.addSectionHandler(SUPPORTED_CONFIG_SECTIONS[i],
+                                     bind(std::plus<int>(), 0, 0)); // no-op.
+          }
+      }
+
+    config.parse(configFile, true);
+    config.parse(configFile, false);
+  }
+
+  boost::asio::io_service&
+  getIoService()
+  {
+    return m_ribManager->getIoService();
+  }
+
+  static void
+  printUsage(std::ostream& os, const std::string& programName)
+  {
+    os << "Usage: \n"
+       << "  " << programName << " [options]\n"
+       << "\n"
+       << "Run NRD daemon\n"
+       << "\n"
+       << "Options:\n"
+       << "  [--help]   - print this help message\n"
+       << "  [--config /path/to/nrd.conf] - path to configuration file "
+       << "(default: " << DEFAULT_CONFIG_FILE << ")\n"
+      ;
+  }
+
+  static void
+  printModules(std::ostream& os)
+  {
+    using namespace std;
+
+    os << "Available logging modules: \n";
+
+    list<string> modules(LoggerFactory::getInstance().getModules());
+    for (list<string>::const_iterator i = modules.begin(); i != modules.end(); ++i)
+      {
+        os << *i << "\n";
+      }
+  }
+
+  static bool
+  parseCommandLine(int argc, char** argv, ProgramOptions& options)
+  {
+    options.showUsage = false;
+    options.config = DEFAULT_CONFIG_FILE;
+
+    while (true) {
+      int optionIndex = 0;
+      static ::option longOptions[] = {
+        { "help"   , no_argument      , 0, 0 },
+        { "config" , required_argument, 0, 0 },
+        { 0        , 0                , 0, 0 }
+      };
+      int c = getopt_long_only(argc, argv, "", longOptions, &optionIndex);
+      if (c == -1)
+        break;
+
+      switch (c) {
+      case 0:
+        switch (optionIndex) {
+        case 0: // help
+          options.showUsage = true;
+          break;
+        case 1: // config
+          options.config = ::optarg;
+          break;
+        default:
+          return false;
+        }
+        break;
+      }
+    }
+    return true;
+  }
+
+
+  void
+  terminate(const boost::system::error_code& error,
+            int signalNo,
+            boost::asio::signal_set& signalSet)
+  {
+    if (error)
+      return;
+
+    if (signalNo == SIGINT ||
+        signalNo == SIGTERM)
+      {
+        getIoService().stop();
+        std::cout << "Caught signal '" << strsignal(signalNo) << "', exiting..." << std::endl;
+      }
+    else
+      {
+        /// \todo May be try to reload config file (at least security section)
+        signalSet.async_wait(bind(&Nrd::terminate, this, _1, _2,
+                                  boost::ref(signalSet)));
+      }
+  }
+
+private:
+  shared_ptr<RibManager> m_ribManager;
+
+  static const std::string SUPPORTED_CONFIG_SECTIONS[];
+  static const size_t      N_SUPPORTED_CONFIG_SECTIONS;
+};
+
+const std::string Nrd::SUPPORTED_CONFIG_SECTIONS[] =
+  {
+    "log",
+    "security",
+  };
+
+const size_t Nrd::N_SUPPORTED_CONFIG_SECTIONS =
+  sizeof(SUPPORTED_CONFIG_SECTIONS) / sizeof(std::string);
+
+} // namespace rib
+} // namespace nfd
+
+int
+main(int argc, char** argv)
+{
+  using namespace nfd::rib;
+
+  ProgramOptions options;
+  bool isCommandLineValid = Nrd::parseCommandLine(argc, argv, options);
+  if (!isCommandLineValid) {
+    Nrd::printUsage(std::cerr, argv[0]);
+    return 1;
+  }
+  if (options.showUsage) {
+    Nrd::printUsage(std::cout, argv[0]);
+    return 0;
+  }
+
+  if (options.showModules) {
+    Nrd::printModules(std::cout);
+    return 0;
+  }
+
+  Nrd nrdInstance;
+
+  try {
+    nrdInstance.initialize(options.config);
+  }
+  catch (boost::filesystem::filesystem_error& e) {
+    if (e.code() == boost::system::errc::permission_denied) {
+      NFD_LOG_FATAL("Permissions denied for " << e.path1() << ". " <<
+                    argv[0] << " should be run as superuser");
+    }
+    else {
+      NFD_LOG_FATAL(e.what());
+    }
+    return 1;
+  }
+  catch (const std::exception& e) {
+    NFD_LOG_FATAL(e.what());
+    return 2;
+  }
+
+  boost::asio::signal_set signalSet(nrdInstance.getIoService());
+  signalSet.add(SIGINT);
+  signalSet.add(SIGTERM);
+  signalSet.add(SIGHUP);
+  signalSet.add(SIGUSR1);
+  signalSet.add(SIGUSR2);
+  signalSet.async_wait(bind(&Nrd::terminate, &nrdInstance, _1, _2,
+                            boost::ref(signalSet)));
+
+  try {
+    nrdInstance.getIoService().run();
+  }
+  catch (std::exception& e) {
+    NFD_LOG_FATAL(e.what());
+    return 3;
+  }
+
+  return 0;
+}
diff --git a/rib/nrd.conf.sample b/rib/nrd.conf.sample
deleted file mode 100644
index 35b162f..0000000
--- a/rib/nrd.conf.sample
+++ /dev/null
@@ -1,70 +0,0 @@
-security
-{
-  ; Security section defines the trust model that NRD should use. It consists of rules and
-  ; trust-anchors, which are briefly defined in this file. For more details please see the
-  ; following wiki:
-  ; http://redmine.named-data.net/projects/ndn-cpp-dev/wiki/CommandValidatorConf
-  ;
-  ; A trust-anchor is a pre-trusted certificate. It is usually stored in a file in the
-  ; same directory as this config file. You can download the NDN testbed root certificate as the
-  ; trust anchor, or you can dump an existing certificate from your system as a trust anchor:
-  ;   $ ndnsec cert-dump /example/certificate/name > trust-anchor.cert
-  ; or you can generate a self-signed certificate as a trust anchor:
-  ;   $ ndnsec key-gen /example/identity/name > trust-anchor.cert
-  ; See comments in trust-anchor section for configuration details.
-  ;
-  ; A rule defines conditions a valid packet MUST have. A packet must satisfy one of the rules defined
-  ; here. A rule can be broken into two parts: matching & checking. A packet will be matched against
-  ; rules from the first to the last until a matched rule is encountered. The matched rule will be
-  ; used to check the packet. If a packet does not match any rule, it will be treated as invalid.
-  ; The matching part of a rule consists of `for` and `filter` sections. They collectively define
-  ; which packets can be checked with this rule. `for` defines packet type (data or interest),
-  ; while `filter` defines conditions on other properties of a packet. Right now, you can only
-  ; define conditions on packet name, and you can only specify ONLY ONE filter for packet name.
-  ; The checking part of a rule consists of `checker`, which defines the conditions that a VALID
-  ; packet MUST have. See comments in checker section for more details.
-
-  rule
-  {
-    id "NRD Prefix Registration Command Rule" ; rule id
-    for interest                              ; this rule is used to validate interests
-    filter
-    {
-      type name                               ; condition on interest name (w/o signature)
-      regex ^[<localhop><localhost>]<nrd>[<register><unregister>]<>{3}$
-    }
-    checker
-    {
-      type customized
-      sig-type rsa-sha256                     ; interest must have a rsa-sha256 signature
-      key-locator
-      {
-        type name                             ; key locator must be the certificate name of
-                                              ; the signing key
-        regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$
-      }
-    }
-  }
-  rule
-  {
-    id "Testbed Hierarchy Rule"               ; rule id
-    for data                                  ; this rule is used to validate data
-    filter
-    {
-      type name                               ; condition on data name
-      regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$
-    }
-    checker
-    {
-      type hierarchical                       ; the certificate name of the signing key and
-                                              ; the data name must follow the hierarchical model
-      sig-type rsa-sha256                     ; data must have a rsa-sha256 signature
-    }
-  }
-  trust-anchor
-  {
-    type file                     ; trust anchor is stored in a file
-    file-name "trust-anchor.cert" ; the file name, by default this file should be placed in the
-                                  ; same folder as this config file.
-  }
-}
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
new file mode 100644
index 0000000..1a3e41f
--- /dev/null
+++ b/rib/rib-manager.cpp
@@ -0,0 +1,341 @@
+/* -*- 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 "rib-manager.hpp"
+
+namespace nfd {
+namespace rib {
+
+const Name RibManager::COMMAND_PREFIX = "/localhost/nrd";
+const Name RibManager::REMOTE_COMMAND_PREFIX = "/localhop/nrd";
+
+const size_t RibManager::COMMAND_UNSIGNED_NCOMPS =
+  RibManager::COMMAND_PREFIX.size() +
+  1 + // verb
+  1;  // verb options
+
+const size_t RibManager::COMMAND_SIGNED_NCOMPS =
+  RibManager::COMMAND_UNSIGNED_NCOMPS +
+  4; // (timestamp, nonce, signed info tlv, signature tlv)
+
+const RibManager::VerbAndProcessor RibManager::COMMAND_VERBS[] =
+  {
+    VerbAndProcessor(
+                     Name::Component("register"),
+                     &RibManager::insertEntry
+                     ),
+
+    VerbAndProcessor(
+                     Name::Component("unregister"),
+                     &RibManager::deleteEntry
+                     ),
+  };
+
+RibManager::RibManager()
+  : m_face(new ndn::Face())
+  , m_nfdController(new ndn::nfd::Controller(*m_face))
+  , m_validator(m_face)
+  , m_faceMonitor(*m_face)
+  , m_verbDispatch(COMMAND_VERBS,
+                   COMMAND_VERBS + (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
+{
+}
+
+void
+RibManager::registerWithNfd()
+{
+  //check whether the components of localhop and localhost prefixes are same
+  BOOST_ASSERT(COMMAND_PREFIX.size() == REMOTE_COMMAND_PREFIX.size());
+
+  std::cerr << "Setting interest filter on: " << COMMAND_PREFIX.toUri() << std::endl;
+  m_face->setController(m_nfdController);
+  m_face->setInterestFilter(COMMAND_PREFIX.toUri(),
+                            bind(&RibManager::onRibRequest, this, _2),
+                            bind(&RibManager::setInterestFilterFailed, this, _1, _2));
+
+  std::cerr << "Setting interest filter on: " << REMOTE_COMMAND_PREFIX.toUri() << std::endl;
+  m_face->setInterestFilter(REMOTE_COMMAND_PREFIX.toUri(),
+                            bind(&RibManager::onRibRequest, this, _2),
+                            bind(&RibManager::setInterestFilterFailed, this, _1, _2));
+
+  std::cerr << "Monitoring faces" << std::endl;
+  m_faceMonitor.addSubscriber(boost::bind(&RibManager::onNotification, this, _1));
+  m_faceMonitor.startNotifications();
+}
+
+void
+RibManager::setConfigFile(ConfigFile& configFile)
+{
+  configFile.addSectionHandler("security",
+                               bind(&RibManager::onConfig, this, _1, _2, _3));
+}
+
+void
+RibManager::onConfig(const ConfigSection& configSection,
+                      bool isDryRun,
+                      const std::string& filename)
+{
+  /// \todo remove check after validator-conf replaces settings on each load
+  if (!isDryRun)
+    m_validator.load(configSection, filename);
+}
+
+void
+RibManager::setInterestFilterFailed(const Name& name, const std::string& msg)
+{
+  std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
+  m_face->shutdown();
+}
+
+void
+RibManager::sendResponse(const Name& name,
+                         const ControlResponse& response)
+{
+  const Block& encodedControl = response.wireEncode();
+
+  Data responseData(name);
+  responseData.setContent(encodedControl);
+
+  m_keyChain.sign(responseData);
+  m_face->put(responseData);
+}
+
+void
+RibManager::sendResponse(const Name& name,
+                         uint32_t code,
+                         const std::string& text)
+{
+  ControlResponse response(code, text);
+  sendResponse(name, response);
+}
+
+void
+RibManager::onRibRequest(const Interest& request)
+{
+  m_validator.validate(request,
+                       bind(&RibManager::onRibRequestValidated, this, _1),
+                       bind(&RibManager::onRibRequestValidationFailed, this, _1, _2));
+}
+
+void
+RibManager::onRibRequestValidated(const shared_ptr<const Interest>& request)
+{
+  const Name& command = request->getName();
+
+  //REMOTE_COMMAND_PREFIX number of componenets are same as
+  // NRD_COMMAND_PREFIX's so no extra checks are required.
+  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
+  VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find(verb);
+
+  if (verbProcessor != m_verbDispatch.end())
+    {
+      PrefixRegOptions options;
+      if (!extractOptions(*request, options))
+        {
+          sendResponse(command, 400, "Malformed command");
+          return;
+        }
+
+      /// \todo authorize command
+      if (false)
+        {
+          sendResponse(request->getName(), 403, "Unauthorized command");
+          return;
+        }
+
+      // \todo add proper log support
+      std::cout << "Received options (name, faceid, cost): " << options.getName() <<
+        ", " << options.getFaceId() << ", "  << options.getCost() << std::endl;
+
+      ControlResponse response;
+      (verbProcessor->second)(this, *request, options);
+    }
+  else
+    {
+      sendResponse(request->getName(), 501, "Unsupported command");
+    }
+}
+
+void
+RibManager::onRibRequestValidationFailed(const shared_ptr<const Interest>& request,
+                                         const std::string& failureInfo)
+{
+  sendResponse(request->getName(), 403, failureInfo);
+}
+
+bool
+RibManager::extractOptions(const Interest& request,
+                           PrefixRegOptions& extractedOptions)
+{
+  // const Name& command = request.getName();
+  //REMOTE_COMMAND_PREFIX is same in size of NRD_COMMAND_PREFIX
+  //so no extra processing is required.
+  const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
+
+  try
+    {
+      Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
+      extractedOptions.wireDecode(rawOptions);
+    }
+  catch (const ndn::Tlv::Error& e)
+    {
+      return false;
+    }
+
+  if (extractedOptions.getFaceId() == 0)
+    {
+      std::cout <<"IncomingFaceId: " << request.getIncomingFaceId() << std::endl;
+      extractedOptions.setFaceId(request.getIncomingFaceId());
+    }
+  return true;
+}
+
+void
+RibManager::onCommandError(uint32_t code, const std::string& error,
+                           const Interest& request,
+                           const PrefixRegOptions& options)
+{
+  std::cout << "NFD Error: " << error << " (code: " << code << ")" << std::endl;
+
+  ControlResponse response;
+
+  if (code == 404)
+    {
+      response.setCode(code);
+      response.setText(error);
+    }
+  else
+    {
+      response.setCode(533);
+      std::ostringstream os;
+      os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
+      response.setText(os.str());
+    }
+
+  sendResponse(request.getName(), response);
+  m_managedRib.erase(options);
+}
+
+void
+RibManager::onUnRegSuccess(const Interest& request, const PrefixRegOptions& options)
+{
+  ControlResponse response;
+
+  response.setCode(200);
+  response.setText("Success");
+  response.setBody(options.wireEncode());
+
+  std::cout << "Success: Name unregistered (" <<
+    options.getName() << ", " <<
+    options.getFaceId() << ")" << std::endl;
+  sendResponse(request.getName(), response);
+  m_managedRib.erase(options);
+}
+
+void
+RibManager::onRegSuccess(const Interest& request, const PrefixRegOptions& options)
+{
+  ControlResponse response;
+
+  response.setCode(200);
+  response.setText("Success");
+  response.setBody(options.wireEncode());
+
+  std::cout << "Success: Name registered (" << options.getName() << ", " <<
+    options.getFaceId() << ")" << std::endl;
+  sendResponse(request.getName(), response);
+}
+
+void
+RibManager::insertEntry(const Interest& request, const PrefixRegOptions& options)
+{
+  // For right now, just pass the options to fib as it is,
+  // without processing flags. Later options will be first added to
+  // Rib tree, then nrd will generate fib updates based on flags and then
+  // will add next hops one by one..
+  m_managedRib.insert(options);
+  m_nfdController->start<ndn::nfd::FibAddNextHopCommand>(
+    ControlParameters()
+      .setName(options.getName())
+      .setFaceId(options.getFaceId())
+      .setCost(options.getCost()),
+    bind(&RibManager::onRegSuccess, this, request, options),
+    bind(&RibManager::onCommandError, this, _1, _2, request, options));
+}
+
+void
+RibManager::deleteEntry(const Interest& request, const PrefixRegOptions& options)
+{
+  m_nfdController->start<ndn::nfd::FibRemoveNextHopCommand>(
+    ControlParameters()
+      .setName(options.getName())
+      .setFaceId(options.getFaceId()),
+    bind(&RibManager::onUnRegSuccess, this, request, options),
+    bind(&RibManager::onCommandError, this, _1, _2, request, options));
+}
+
+boost::asio::io_service&
+RibManager::getIoService()
+{
+  /// \todo Switch face to use global io service (needs library update)
+  return *m_face->ioService();
+}
+
+void
+RibManager::onControlHeaderSuccess()
+{
+  std::cout << "Local control header enabled" << std::endl;
+}
+
+void
+RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
+{
+  std::cout << "Error: couldn't enable local control header "
+            << "(code: " << code << ", info: " << reason << ")" << std::endl;
+  m_face->shutdown();
+}
+
+void
+RibManager::enableLocalControlHeader()
+{
+  m_nfdController->start<ndn::nfd::FaceEnableLocalControlCommand>(
+    ControlParameters()
+      .setLocalControlFeature(ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
+    bind(&RibManager::onControlHeaderSuccess, this),
+    bind(&RibManager::onControlHeaderError, this, _1, _2));
+}
+
+void
+RibManager::onNotification(const FaceEventNotification& notification)
+{
+  /// \todo A notification can be missed, in this case check Facelist
+  std::cerr << "Notification Rcvd: " << notification << std::endl;
+  if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) { //face destroyed
+    m_managedRib.erase(notification.getFaceId());
+  }
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
new file mode 100644
index 0000000..9479291
--- /dev/null
+++ b/rib/rib-manager.hpp
@@ -0,0 +1,157 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology,
+ *                     The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_RIB_RIB_MANAGER_HPP
+#define NFD_RIB_RIB_MANAGER_HPP
+
+#include "rib.hpp"
+#include "face-monitor.hpp"
+#include "core/config-file.hpp"
+
+#include <ndn-cpp-dev/security/validator-config.hpp>
+#include <ndn-cpp-dev/management/nfd-controller.hpp>
+#include <ndn-cpp-dev/management/nfd-control-command.hpp>
+#include <ndn-cpp-dev/management/nfd-control-response.hpp>
+#include <ndn-cpp-dev/management/nfd-control-parameters.hpp>
+
+namespace nfd {
+namespace rib {
+
+using ndn::nfd::ControlCommand;
+using ndn::nfd::ControlResponse;
+using ndn::nfd::ControlParameters;
+
+class RibManager : noncopyable
+{
+public:
+  RibManager();
+
+  void
+  onRibRequest(const Interest& request);
+
+  void
+  registerWithNfd();
+
+  void
+  enableLocalControlHeader();
+
+  boost::asio::io_service&
+  getIoService();
+
+  void
+  setConfigFile(ConfigFile& configFile);
+
+private:
+  void
+  onConfig(const ConfigSection& configSection,
+           bool isDryRun,
+           const std::string& filename);
+
+  void
+  sendResponse(const Name& name,
+               const ControlResponse& response);
+
+  void
+  sendResponse(const Name& name,
+               uint32_t code,
+               const std::string& text);
+
+  void
+  onRibRequestValidated(const shared_ptr<const Interest>& request);
+
+  void
+  onRibRequestValidationFailed(const shared_ptr<const Interest>& request,
+                               const std::string& failureInfo);
+
+  void
+  onCommandError(uint32_t code, const std::string& error,
+                 const ndn::Interest& interest,
+                 const PrefixRegOptions& options);
+
+  void
+  onRegSuccess(const ndn::Interest& interest, const PrefixRegOptions& options);
+
+  void
+  onUnRegSuccess(const ndn::Interest& interest, const PrefixRegOptions& options);
+
+  void
+  onControlHeaderSuccess();
+
+  void
+  onControlHeaderError(uint32_t code, const std::string& reason);
+
+  void
+  setInterestFilterFailed(const Name& name, const std::string& msg);
+
+  void
+  insertEntry(const Interest& request, const PrefixRegOptions& options);
+
+  void
+  deleteEntry(const Interest& request, const PrefixRegOptions& options);
+
+  bool
+  extractOptions(const Interest& request,
+                 PrefixRegOptions& extractedOptions);
+
+  void
+  onNotification(const FaceEventNotification& notification);
+
+private:
+  Rib m_managedRib;
+  ndn::shared_ptr<ndn::Face> m_face;
+  ndn::shared_ptr<ndn::nfd::Controller> m_nfdController;
+  ndn::KeyChain m_keyChain;
+  ndn::ValidatorConfig m_validator;
+  FaceMonitor m_faceMonitor;
+
+  typedef boost::function<void(RibManager*,
+                               const Interest&,
+                               const PrefixRegOptions&)> VerbProcessor;
+
+  typedef std::map<name::Component, VerbProcessor> VerbDispatchTable;
+
+  typedef std::pair<name::Component, VerbProcessor> VerbAndProcessor;
+
+
+  const VerbDispatchTable m_verbDispatch;
+
+  static const Name COMMAND_PREFIX; // /localhost/nrd
+  static const Name REMOTE_COMMAND_PREFIX; // /localhop/nrd
+
+  // number of components in an invalid, but not malformed, unsigned command.
+  // (/localhost/nrd + verb + options) = 4
+  static const size_t COMMAND_UNSIGNED_NCOMPS;
+
+  // number of components in a valid signed Interest.
+  // 8 with signed Interest support.
+  static const size_t COMMAND_SIGNED_NCOMPS;
+
+  static const VerbAndProcessor COMMAND_VERBS[];
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_RIB_RIB_MANAGER_HPP
diff --git a/rib/rib.cpp b/rib/rib.cpp
new file mode 100644
index 0000000..8ad5ec6
--- /dev/null
+++ b/rib/rib.cpp
@@ -0,0 +1,109 @@
+/* -*- 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 "rib.hpp"
+
+namespace nfd {
+namespace rib {
+
+Rib::Rib()
+{
+}
+
+
+Rib::~Rib()
+{
+}
+
+static inline bool
+compareNameFaceProtocol(const PrefixRegOptions& opt1, const PrefixRegOptions& opt2)
+{
+  return (opt1.getName() == opt2.getName() &&
+          opt1.getFaceId() == opt2.getFaceId() &&
+          opt1.getProtocol() == opt2.getProtocol());
+}
+
+
+Rib::const_iterator
+Rib::find(const PrefixRegOptions& options) const
+{
+  RibTable::const_iterator it = std::find_if(m_rib.begin(), m_rib.end(),
+                                             bind(&compareNameFaceProtocol, _1, options));
+  if (it == m_rib.end())
+    {
+      return end();
+    }
+  else
+    return it;
+}
+
+
+void
+Rib::insert(const PrefixRegOptions& options)
+{
+  RibTable::iterator it = std::find_if(m_rib.begin(), m_rib.end(),
+                                       bind(&compareNameFaceProtocol, _1, options));
+  if (it == m_rib.end())
+    {
+      m_rib.push_front(options);
+    }
+  else
+    {
+      //entry exist, update other fields
+      it->setFlags(options.getFlags());
+      it->setCost(options.getCost());
+      it->setExpirationPeriod(options.getExpirationPeriod());
+      it->setProtocol(options.getProtocol());
+    }
+}
+
+
+void
+Rib::erase(const PrefixRegOptions& options)
+{
+  RibTable::iterator it = std::find_if(m_rib.begin(), m_rib.end(),
+                                       bind(&compareNameFaceProtocol, _1, options));
+  if (it != m_rib.end())
+    {
+      m_rib.erase(it);
+    }
+}
+
+void
+Rib::erase(uint64_t faceId)
+{
+  //Keep it simple for now, with Trie this will be changed.
+  RibTable::iterator it = m_rib.begin();
+  while (it != m_rib.end())
+  {
+    if (it->getFaceId() == faceId)
+      it = m_rib.erase(it);
+    else
+      ++it;
+  }
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/rib/rib.hpp b/rib/rib.hpp
new file mode 100644
index 0000000..745a760
--- /dev/null
+++ b/rib/rib.hpp
@@ -0,0 +1,108 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  Regents of the University of California,
+ *                     Arizona Board of Regents,
+ *                     Colorado State University,
+ *                     University Pierre & Marie Curie, Sorbonne University,
+ *                     Washington University in St. Louis,
+ *                     Beijing Institute of Technology,
+ *                     The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NFD_RIB_RIB_HPP
+#define NFD_RIB_RIB_HPP
+
+#include "common.hpp"
+
+#include <ndn-cpp-dev/management/nrd-prefix-reg-options.hpp>
+
+namespace nfd {
+namespace rib {
+
+using ndn::nrd::PrefixRegOptions;
+namespace tlv = ndn::tlv;
+
+/** \brief represents the RIB
+ */
+class Rib
+{
+public:
+  typedef std::list<PrefixRegOptions> RibTable;
+  typedef RibTable::const_iterator const_iterator;
+
+  Rib();
+
+  ~Rib();
+
+  const_iterator
+  find(const PrefixRegOptions& options) const;
+
+  void
+  insert(const PrefixRegOptions& options);
+
+  void
+  erase(const PrefixRegOptions& options);
+
+  void
+  erase(uint64_t faceId);
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  size_t
+  size() const;
+
+  size_t
+  empty() const;
+
+private:
+  // Note: Taking a list right now. A Trie will be used later to store
+  // prefixes
+  RibTable m_rib;
+};
+
+inline Rib::const_iterator
+Rib::begin() const
+{
+  return m_rib.begin();
+}
+
+inline Rib::const_iterator
+Rib::end() const
+{
+  return m_rib.end();
+}
+
+inline size_t
+Rib::size() const
+{
+  return m_rib.size();
+}
+
+inline size_t
+Rib::empty() const
+{
+  return m_rib.empty();
+}
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_RIB_RIB_HPP
diff --git a/rib/src/common.hpp b/rib/src/common.hpp
deleted file mode 100644
index f520828..0000000
--- a/rib/src/common.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NRD_COMMON_HPP
-#define NRD_COMMON_HPP
-
-#include <iostream>
-#include <list>
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/security/validator-config.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include <ndn-cpp-dev/management/nfd-controller.hpp>
-#include <ndn-cpp-dev/management/nfd-control-response.hpp>
-#include <ndn-cpp-dev/management/nrd-prefix-reg-options.hpp>
-
-#include <boost/lexical_cast.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/regex_find_format.hpp>
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/info_parser.hpp>
-
-#include "../build/src/config.hpp"
-
-namespace ndn {
-namespace nrd {
-
-class Error : public std::runtime_error
-{
-public:
-  explicit
-  Error(const std::string& what)
-    : std::runtime_error(what)
-  {
-  }
-};
-
-} //namespace nrd
-} //namespace ndn
-#endif // NRD_COMMON_HPP
diff --git a/rib/src/face-monitor.cpp b/rib/src/face-monitor.cpp
deleted file mode 100644
index f434523..0000000
--- a/rib/src/face-monitor.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2014 Regents of the University of California.
- * See COPYING for copyright and distribution information.
- */
-
-#include "common.hpp"
-#include "face-monitor.hpp"
-#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
-
-
-namespace ndn {
-
-using namespace nfd;
-
-FaceMonitor::FaceMonitor(Face& face)
-  : m_face(face)
-  , m_isStopped(true)
-{
-}
-
-FaceMonitor::~FaceMonitor()
-{
-}
-
-void
-FaceMonitor::removeAllSubscribers()
-{
-  m_notificationCallbacks.clear();
-  m_timeoutCallbacks.clear();
-  stopNotifications();
-}
-
-void
-FaceMonitor::stopNotifications()
-{
-  if (static_cast<bool>(m_lastInterestId))
-    m_face.removePendingInterest(m_lastInterestId);
-  m_isStopped = true;
-}
-
-void
-FaceMonitor::startNotifications()
-{
-  if (m_isStopped == false)
-    return; // Notifications cycle has been started.
-  m_isStopped = false;
-
-  Interest interest("/localhost/nfd/faces/events");
-  interest
-    .setMustBeFresh(true)
-    .setChildSelector(1)
-    .setInterestLifetime(time::seconds(60))
-  ;
-
-  //todo: add logging support.
-  std::cout << "startNotification: Interest Sent: " << interest << std::endl;
-
-  m_lastInterestId = m_face.expressInterest(interest,
-                                            bind(&FaceMonitor::onNotification, this, _2),
-                                            bind(&FaceMonitor::onTimeout, this));
-}
-
-void
-FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback)
-{
-  addSubscriber(notificationCallback, TimeoutCallback());
-}
-
-void
-FaceMonitor::addSubscriber(const NotificationCallback& notificationCallback,
-                           const TimeoutCallback&  timeoutCallback)
-{
-  if (static_cast<bool>(notificationCallback))
-    m_notificationCallbacks.push_back(notificationCallback);
-
-  if (static_cast<bool>(timeoutCallback))
-    m_timeoutCallbacks.push_back(timeoutCallback);
-}
-
-void
-FaceMonitor::onTimeout()
-{
-  if (m_isStopped)
-    return;
-
-  std::vector<TimeoutCallback>::iterator it;
-  for (it = m_timeoutCallbacks.begin();
-       it != m_timeoutCallbacks.end(); ++it) {
-    (*it)();
-    //One of the registered callbacks has cleared the vector,
-    //return now as the iterator has been invalidated and
-    //the vector is empty.
-    if (m_timeoutCallbacks.empty()) {
-       return;
-    }
-  }
-
-  Interest newInterest("/localhost/nfd/faces/events");
-  newInterest
-    .setMustBeFresh(true)
-    .setChildSelector(1)
-    .setInterestLifetime(time::seconds(60))
-    ;
-
-  //todo: add logging support.
-  std::cout << "In onTimeout, sending interest: " << newInterest << std::endl;
-
-  m_lastInterestId = m_face.expressInterest(newInterest,
-                                            bind(&FaceMonitor::onNotification, this, _2),
-                                            bind(&FaceMonitor::onTimeout, this));
-}
-
-void
-FaceMonitor::onNotification(const Data& data)
-{
-  if (m_isStopped)
-    return;
-
-  m_lastSequence = data.getName().get(-1).toSegment();
-  ndn::nfd::FaceEventNotification notification(data.getContent().blockFromValue());
-
-  std::vector<NotificationCallback>::iterator it;
-  for (it = m_notificationCallbacks.begin();
-       it != m_notificationCallbacks.end(); ++it) {
-    (*it)(notification);
-    if (m_notificationCallbacks.empty()) {
-      //One of the registered callbacks has cleared the vector.
-      //return back, as no one is interested in notifications anymore.
-      return;
-    }
-  }
-
-  //Setting up next notification
-  Name nextNotification("/localhost/nfd/faces/events");
-  nextNotification.appendSegment(m_lastSequence + 1);
-
-  Interest interest(nextNotification);
-  interest.setInterestLifetime(time::seconds(60));
-
-  //todo: add logging support.
-  std::cout << "onNotification: Interest sent: " <<  interest << std::endl;
-
-  m_lastInterestId = m_face.expressInterest(interest,
-                                            bind(&FaceMonitor::onNotification, this, _2),
-                                            bind(&FaceMonitor::onTimeout, this));
-}
-
-}//namespace ndn
diff --git a/rib/src/face-monitor.hpp b/rib/src/face-monitor.hpp
deleted file mode 100644
index e0eeaa6..0000000
--- a/rib/src/face-monitor.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2014 Regents of the University of California.
- * See COPYING for copyright and distribution information.
- */
-#ifndef FACE_MONITOR_HPP
-#define FACE_MONITOR_HPP
-
-#include "common.hpp"
-#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
-#include <ndn-cpp-dev/management/nrd-controller.hpp>
-
-namespace ndn {
-
-class FaceMonitor
-{
-public:
-  typedef function<void(const nfd::FaceEventNotification&)> NotificationCallback;
-  typedef function<void()> TimeoutCallback;
-
-  typedef std::vector<NotificationCallback> NotificationCallbacks;
-  typedef std::vector<TimeoutCallback> TimeoutCallbacks;
-
-  explicit
-  FaceMonitor(Face& face);
-
-  ~FaceMonitor();
-
-  /** \brief Stops all notifications. This method  doesn't remove registered callbacks.
-   */
-  void
-  stopNotifications();
-
-  /** \brief Resumes notifications for added subscribers.
-   */
-  void
-  startNotifications();
-
-  /** \brief Removes all notification subscribers.
-   */
-  void
-  removeAllSubscribers();
-
-  /** \brief Adds a notification subscriber. This method doesn't return on timeouts.
-   */
-  void
-  addSubscriber(const NotificationCallback& notificationCallback);
-
-  /** \brief Adds a notification subscriber.
-   */
-  void
-  addSubscriber(const NotificationCallback& notificationCallback,
-                const TimeoutCallback&  timeoutCallback);
-
-private:
-  void
-  onTimeout();
-
-  void
-  onNotification(const Data& data);
-
-private:
-  Face& m_face;
-  uint64_t m_lastSequence;
-  bool m_isStopped;
-  NotificationCallbacks m_notificationCallbacks;
-  TimeoutCallbacks m_timeoutCallbacks;
-  const PendingInterestId* m_lastInterestId;
-};
-
-}//namespace ndn
-#endif //FACE_MONITOR_HPP
diff --git a/rib/src/main.cpp b/rib/src/main.cpp
deleted file mode 100644
index 5d0e5ed..0000000
--- a/rib/src/main.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#include "common.hpp"
-#include "nrd.hpp"
-#include "nrd-config.hpp"
-#include <getopt.h>
-
-struct ProgramOptions
-{
-  bool showUsage;
-  std::string config;
-};
-
-static void
-printUsage(std::ostream& os, const std::string& programName)
-{
-  os << "Usage: \n"
-    << "  " << programName << " [options]\n"
-    << "\n"
-    << "Run NRD daemon\n"
-    << "\n"
-    << "Options:\n"
-    << "  [--help]   - print this help message\n"
-    << "  [--config /path/to/nrd.conf] - path to configuration file "
-    << "(default: " << DEFAULT_CONFIG_FILE << ")\n"
-    ;
-}
-
-static bool
-parseCommandLine(int argc, char** argv, ProgramOptions& options)
-{
-  options.showUsage = false;
-  options.config = DEFAULT_CONFIG_FILE;
-
-  while (true) {
-    int optionIndex = 0;
-    static ::option longOptions[] = {
-      { "help"   , no_argument      , 0, 0 },
-      { "config" , required_argument, 0, 0 },
-      { 0        , 0                , 0, 0 }
-    };
-    int c = getopt_long_only(argc, argv, "", longOptions, &optionIndex);
-    if (c == -1)
-      break;
-
-    switch (c) {
-      case 0:
-        switch (optionIndex) {
-          case 0: // help
-            options.showUsage = true;
-            break;
-          case 1: // config
-            options.config = ::optarg;
-            break;
-          default:
-            return false;
-        }
-        break;
-    }
-  }
-  return true;
-}
-
-int
-main(int argc, char** argv)
-{
-  //processing command line arguments, if available
-  ProgramOptions options;
-  bool isCommandLineValid = parseCommandLine(argc, argv, options);
-  if (!isCommandLineValid) {
-    printUsage(std::cerr, argv[0]);
-    return 1;
-  }
-  if (options.showUsage) {
-    printUsage(std::cout, argv[0]);
-    return 0;
-  }
-
-  //Now read the config file and pass the security section to validator
-  try {
-    std::string configFilename(options.config);
-
-    ndn::nrd::NrdConfig config;
-    config.load(configFilename);
-    ndn::nrd::ConfigSection securitySection = config.getSecuritySection();
-
-    ndn::nrd::Nrd nrd(securitySection, configFilename);
-    nrd.enableLocalControlHeader();
-    nrd.listen();
-  }
-  catch (std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-  }
-
-  return 0;
-}
diff --git a/rib/src/nrd-config.cpp b/rib/src/nrd-config.cpp
deleted file mode 100644
index c6181f9..0000000
--- a/rib/src/nrd-config.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "nrd-config.hpp"
-
-namespace ndn {
-namespace nrd {
-
-NrdConfig::NrdConfig()
-  : m_isSecuritySectionDefined(false)
-{
-}
-
-void
-NrdConfig::load(const std::string& filename)
-{
-  std::ifstream inputFile;
-  inputFile.open(filename.c_str());
-  if (!inputFile.good() || !inputFile.is_open())
-  {
-    std::string msg = "Failed to read configuration file: ";
-    msg += filename;
-    std::cerr << filename << std::endl;
-    throw Error(msg);
-  }
-  load(inputFile, filename);
-  inputFile.close();
-}
-
-void
-NrdConfig::load(const std::string& input, const std::string& filename)
-{
-  std::istringstream inputStream(input);
-  load(inputStream, filename);
-}
-
-void
-NrdConfig::load(std::istream& input, const std::string& filename)
-{
-  BOOST_ASSERT(!filename.empty());
-
-  ConfigSection ptree;
-  try
-  {
-    boost::property_tree::read_info(input, ptree);
-  }
-  catch (const boost::property_tree::info_parser_error& error)
-  {
-    std::stringstream msg;
-    msg << "Failed to parse configuration file";
-    msg << " " << filename;
-    msg << " " << error.message() << " line " << error.line();
-    throw Error(msg.str());
-  }
-  process(ptree, filename);
-}
-
-void
-NrdConfig::process(const ConfigSection& configSection,
-                   const std::string& filename)
-{
-  BOOST_ASSERT(!filename.empty());
-
-  if (configSection.begin() == configSection.end())
-    {
-      std::string msg = "Error processing configuration file";
-      msg += ": ";
-      msg += filename;
-      msg += " no data";
-      throw Error(msg);
-    }
-
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end(); ++i)
-    {
-      const std::string& sectionName = i->first;
-      const ConfigSection& section = i->second;
-
-      if (boost::iequals(sectionName, "security"))
-        {
-          onSectionSecurity(section, filename);
-        }
-      //Add more sections here as needed
-      //else if (boost::iequals(sectionName, "another-section"))
-        //{
-          //onSectionAnotherSection(section, filename);
-        //}
-      else
-        {
-          std::string msg = "Error processing configuration file";
-          msg += " ";
-          msg += filename;
-          msg += " unrecognized section: " + sectionName;
-          throw Error(msg);
-        }
-    }
-}
-
-void
-NrdConfig::onSectionSecurity(const ConfigSection& section,
-                             const std::string& filename)
-{
-  if (!m_isSecuritySectionDefined) {
-    //setSecturitySection(section);
-    m_securitySection = section;
-    m_filename = filename;
-    m_isSecuritySectionDefined = true;
-  }
-  else {
-    std::string msg = "Error processing configuration file";
-    msg += " ";
-    msg += filename;
-    msg += " security section can appear only once";
-    throw Error(msg);
-  }
-}
-
-} //namespace nrd
-} //namespace ndn
diff --git a/rib/src/nrd-config.hpp b/rib/src/nrd-config.hpp
deleted file mode 100644
index ee119f6..0000000
--- a/rib/src/nrd-config.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef NRD_CONFIG_HPP
-#define NRD_CONFIG_HPP
-
-#include "common.hpp"
-
-namespace ndn {
-namespace nrd {
-
-typedef boost::property_tree::ptree ConfigSection;
-
-class NrdConfig
-{
-
-public:
-  NrdConfig();
-
-  virtual
-  ~NrdConfig()
-  {
-  }
-
-  void
-  load(const std::string& filename);
-
-  void
-  load(const std::string& input, const std::string& filename);
-
-  void
-  load(std::istream& input, const std::string& filename);
-
-  const ConfigSection&
-  getSecuritySection() const
-  {
-    return m_securitySection;
-  }
-
-private:
-  void
-  process(const ConfigSection& configSection,
-          const std::string& filename);
-
-  void
-  onSectionSecurity(const ConfigSection& section,
-                    const std::string& filename);
-
-  const void
-  setSecturitySection(const ConfigSection& securitySection)
-  {
-    m_securitySection = securitySection;
-  }
-
-private:
-  bool m_isSecuritySectionDefined;
-  ConfigSection m_securitySection;
-  std::string m_filename;
-};
-
-}//namespace nrd
-}//namespace ndn
-
-#endif // NRD_CONFIG_HPP
diff --git a/rib/src/nrd.cpp b/rib/src/nrd.cpp
deleted file mode 100644
index 492f9c2..0000000
--- a/rib/src/nrd.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#include "nrd.hpp"
-
-namespace ndn {
-namespace nrd {
-
-const Name Nrd::COMMAND_PREFIX = "/localhost/nrd";
-const Name Nrd::REMOTE_COMMAND_PREFIX = "/localhop/nrd";
-
-const size_t Nrd::COMMAND_UNSIGNED_NCOMPS =
-  Nrd::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb options
-
-const size_t Nrd::COMMAND_SIGNED_NCOMPS =
-  Nrd::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const Nrd::VerbAndProcessor Nrd::COMMAND_VERBS[] =
-  {
-    VerbAndProcessor(
-                     Name::Component("register"),
-                     &Nrd::insertEntry
-                     ),
-
-    VerbAndProcessor(
-                     Name::Component("unregister"),
-                     &Nrd::deleteEntry
-                     ),
-  };
-
-Nrd::Nrd(const ndn::nrd::ConfigSection& securitySection,
-         const std::string& validatorConfig)
-  : m_face(new Face())
-  , m_nfdController(new nfd::Controller(*m_face))
-  , m_validator(m_face)
-  , m_faceMonitor(*m_face)
-  , m_verbDispatch(COMMAND_VERBS,
-                   COMMAND_VERBS + (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
-{
-  //check whether the components of localhop and localhost prefixes are same
-  BOOST_ASSERT(COMMAND_PREFIX.size() == REMOTE_COMMAND_PREFIX.size());
-
-  //m_validator.load(validatorConfig);
-  m_validator.load(securitySection, validatorConfig);
-
-  std::cerr << "Setting interest filter on: " << COMMAND_PREFIX.toUri() << std::endl;
-  m_face->setController(m_nfdController);
-  m_face->setInterestFilter(COMMAND_PREFIX.toUri(),
-                            bind(&Nrd::onRibRequest, this, _2),
-                            bind(&Nrd::setInterestFilterFailed, this, _1, _2));
-
-  std::cerr << "Setting interest filter on: " << REMOTE_COMMAND_PREFIX.toUri() << std::endl;
-  m_face->setInterestFilter(REMOTE_COMMAND_PREFIX.toUri(),
-                            bind(&Nrd::onRibRequest, this, _2),
-                            bind(&Nrd::setInterestFilterFailed, this, _1, _2));
-
-  std::cerr << "Monitoring faces" << std::endl;
-  m_faceMonitor.addSubscriber(boost::bind(&Nrd::onNotification, this, _1));
-  m_faceMonitor.startNotifications();
-}
-
-void
-Nrd::setInterestFilterFailed(const Name& name, const std::string& msg)
-{
-  std::cerr << "Error in setting interest filter (" << name << "): " << msg << std::endl;
-  m_face->shutdown();
-}
-
-void
-Nrd::sendResponse(const Name& name,
-                  const nfd::ControlResponse& response)
-{
-  const Block& encodedControl = response.wireEncode();
-
-  Data responseData(name);
-  responseData.setContent(encodedControl);
-
-  m_keyChain.sign(responseData);
-  m_face->put(responseData);
-}
-
-void
-Nrd::sendResponse(const Name& name,
-                  uint32_t code,
-                  const std::string& text)
-{
-  nfd::ControlResponse response(code, text);
-  sendResponse(name, response);
-}
-
-void
-Nrd::onRibRequest(const Interest& request)
-{
-  m_validator.validate(request,
-                       bind(&Nrd::onRibRequestValidated, this, _1),
-                       bind(&Nrd::onRibRequestValidationFailed, this, _1, _2));
-}
-
-void
-Nrd::onRibRequestValidated(const shared_ptr<const Interest>& request)
-{
-  const Name& command = request->getName();
-
-  //REMOTE_COMMAND_PREFIX number of componenets are same as
-  // NRD_COMMAND_PREFIX's so no extra checks are required.
-  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
-  VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find(verb);
-
-  if (verbProcessor != m_verbDispatch.end())
-    {
-      PrefixRegOptions options;
-      if (!extractOptions(*request, options))
-        {
-          sendResponse(command, 400, "Malformed command");
-          return;
-        }
-
-      /// \todo authorize command
-      if (false)
-        {
-          sendResponse(request->getName(), 403, "Unauthorized command");
-          return;
-        }
-
-      // \todo add proper log support
-      std::cout << "Received options (name, faceid, cost): " << options.getName() <<
-        ", " << options.getFaceId() << ", "  << options.getCost() << std::endl;
-
-      nfd::ControlResponse response;
-      (verbProcessor->second)(this, *request, options);
-    }
-  else
-    {
-      sendResponse(request->getName(), 501, "Unsupported command");
-    }
-}
-
-void
-Nrd::onRibRequestValidationFailed(const shared_ptr<const Interest>& request,
-                                  const std::string& failureInfo)
-{
-  sendResponse(request->getName(), 403, failureInfo);
-}
-
-bool
-Nrd::extractOptions(const Interest& request,
-                    PrefixRegOptions& extractedOptions)
-{
-  // const Name& command = request.getName();
-  //REMOTE_COMMAND_PREFIX is same in size of NRD_COMMAND_PREFIX
-  //so no extra processing is required.
-  const size_t optionCompIndex = COMMAND_PREFIX.size() + 1;
-
-  try
-    {
-      Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
-      extractedOptions.wireDecode(rawOptions);
-    }
-  catch (const ndn::Tlv::Error& e)
-    {
-      return false;
-    }
-
-  if (extractedOptions.getFaceId() == 0)
-    {
-      std::cout <<"IncomingFaceId: " << request.getIncomingFaceId() << std::endl;
-      extractedOptions.setFaceId(request.getIncomingFaceId());
-    }
-  return true;
-}
-
-void
-Nrd::onCommandError(uint32_t code, const std::string& error,
-                    const Interest& request,
-                    const PrefixRegOptions& options)
-{
-  std::cout << "NFD Error: " << error << " (code: " << code << ")" << std::endl;
-
-  nfd::ControlResponse response;
-
-  if (code == 404)
-    {
-      response.setCode(code);
-      response.setText(error);
-    }
-  else
-    {
-      response.setCode(533);
-      std::ostringstream os;
-      os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
-      response.setText(os.str());
-    }
-
-  sendResponse(request.getName(), response);
-  m_managedRib.erase(options);
-}
-
-void
-Nrd::onUnRegSuccess(const Interest& request, const PrefixRegOptions& options)
-{
-  nfd::ControlResponse response;
-
-  response.setCode(200);
-  response.setText("Success");
-  response.setBody(options.wireEncode());
-
-  std::cout << "Success: Name unregistered (" <<
-    options.getName() << ", " <<
-    options.getFaceId() << ")" << std::endl;
-  sendResponse(request.getName(), response);
-  m_managedRib.erase(options);
-}
-
-void
-Nrd::onRegSuccess(const Interest& request, const PrefixRegOptions& options)
-{
-  nfd::ControlResponse response;
-
-  response.setCode(200);
-  response.setText("Success");
-  response.setBody(options.wireEncode());
-
-  std::cout << "Success: Name registered (" << options.getName() << ", " <<
-    options.getFaceId() << ")" << std::endl;
-  sendResponse(request.getName(), response);
-}
-
-void
-Nrd::insertEntry(const Interest& request, const PrefixRegOptions& options)
-{
-  // For right now, just pass the options to fib as it is,
-  // without processing flags. Later options will be first added to
-  // Rib tree, then nrd will generate fib updates based on flags and then
-  // will add next hops one by one..
-  m_managedRib.insert(options);
-  m_nfdController->start<nfd::FibAddNextHopCommand>(
-    nfd::ControlParameters()
-      .setName(options.getName())
-      .setFaceId(options.getFaceId())
-      .setCost(options.getCost()),
-    bind(&Nrd::onRegSuccess, this, request, options),
-    bind(&Nrd::onCommandError, this, _1, _2, request, options));
-}
-
-void
-Nrd::deleteEntry(const Interest& request, const PrefixRegOptions& options)
-{
-  m_nfdController->start<nfd::FibRemoveNextHopCommand>(
-    nfd::ControlParameters()
-      .setName(options.getName())
-      .setFaceId(options.getFaceId()),
-    bind(&Nrd::onUnRegSuccess, this, request, options),
-    bind(&Nrd::onCommandError, this, _1, _2, request, options));
-}
-
-void
-Nrd::listen()
-{
-  std::cout << "NRD started: listening for incoming interests" << std::endl;
-  m_face->processEvents();
-}
-
-void
-Nrd::onControlHeaderSuccess()
-{
-  std::cout << "Local control header enabled" << std::endl;
-}
-
-void
-Nrd::onControlHeaderError(uint32_t code, const std::string& reason)
-{
-  std::cout << "Error: couldn't enable local control header "
-            << "(code: " << code << ", info: " << reason << ")" << std::endl;
-  m_face->shutdown();
-}
-
-void
-Nrd::enableLocalControlHeader()
-{
-  m_nfdController->start<nfd::FaceEnableLocalControlCommand>(
-    nfd::ControlParameters()
-      .setLocalControlFeature(nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
-    bind(&Nrd::onControlHeaderSuccess, this),
-    bind(&Nrd::onControlHeaderError, this, _1, _2));
-}
-
-void
-Nrd::onNotification(const nfd::FaceEventNotification& notification)
-{
-  /// \todo A notification can be missed, in this case check Facelist
-  std::cerr << "Notification Rcvd: " << notification << std::endl;
-  if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) { //face destroyed
-    m_managedRib.erase(notification.getFaceId());
-  }
-}
-
-} // namespace nrd
-} // namespace ndn
diff --git a/rib/src/nrd.hpp b/rib/src/nrd.hpp
deleted file mode 100644
index d6007d7..0000000
--- a/rib/src/nrd.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NRD_HPP
-#define NRD_HPP
-
-#include "rib.hpp"
-#include "face-monitor.hpp"
-#include "nrd-config.hpp"
-
-namespace ndn {
-namespace nrd {
-
-class Nrd : noncopyable
-{
-public:
-  Nrd(const ndn::nrd::ConfigSection& securitySection,
-      const std::string& validatorConfig);
-
-  void
-  onRibRequest(const Interest& request);
-
-  void
-  enableLocalControlHeader();
-
-  void
-  listen();
-
-private:
-  void
-  sendResponse(const Name& name,
-               const nfd::ControlResponse& response);
-
-  void
-  sendResponse(const Name& name,
-               uint32_t code,
-               const std::string& text);
-
-  void
-  onRibRequestValidated(const shared_ptr<const Interest>& request);
-
-  void
-  onRibRequestValidationFailed(const shared_ptr<const Interest>& request,
-                               const std::string& failureInfo);
-
-  void
-  onCommandError(uint32_t code, const std::string& error,
-                 const ndn::Interest& interest,
-                 const PrefixRegOptions& options);
-
-  void
-  onRegSuccess(const ndn::Interest& interest, const PrefixRegOptions& options);
-
-  void
-  onUnRegSuccess(const ndn::Interest& interest, const PrefixRegOptions& options);
-
-  void
-  onControlHeaderSuccess();
-
-  void
-  onControlHeaderError(uint32_t code, const std::string& reason);
-
-  void
-  setInterestFilterFailed(const Name& name, const std::string& msg);
-
-  void
-  insertEntry(const Interest& request, const PrefixRegOptions& options);
-
-  void
-  deleteEntry(const Interest& request, const PrefixRegOptions& options);
-
-  bool
-  extractOptions(const Interest& request,
-                 PrefixRegOptions& extractedOptions);
-
-  void
-  onNotification(const nfd::FaceEventNotification& notification);
-
-private:
-  Rib m_managedRib;
-  ndn::shared_ptr<ndn::Face> m_face;
-  ndn::shared_ptr<nfd::Controller> m_nfdController;
-  ndn::KeyChain m_keyChain;
-  ndn::ValidatorConfig m_validator;
-  ndn::FaceMonitor m_faceMonitor;
-
-  typedef boost::function<void(Nrd*,
-                               const Interest&,
-                               const PrefixRegOptions&)> VerbProcessor;
-
-  typedef std::map<Name::Component, VerbProcessor> VerbDispatchTable;
-
-  typedef std::pair<Name::Component, VerbProcessor> VerbAndProcessor;
-
-
-  const VerbDispatchTable m_verbDispatch;
-
-  static const Name COMMAND_PREFIX; // /localhost/nrd
-  static const Name REMOTE_COMMAND_PREFIX; // /localhop/nrd
-
-  // number of components in an invalid, but not malformed, unsigned command.
-  // (/localhost/nrd + verb + options) = 4
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed Interest.
-  // 5 in mock (see UNSIGNED_NCOMPS), 8 with signed Interest support.
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const VerbAndProcessor COMMAND_VERBS[];
-};
-
-} // namespace nrd
-} // namespace ndn
-
-#endif // NRD_HPP
diff --git a/rib/src/rib.cpp b/rib/src/rib.cpp
deleted file mode 100644
index 4f1387b..0000000
--- a/rib/src/rib.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#include "rib.hpp"
-
-namespace ndn {
-namespace nrd {
-
-Rib::Rib()
-{
-}
-
-
-Rib::~Rib()
-{
-}
-
-static inline bool
-compareNameFaceProtocol(const PrefixRegOptions& opt1, const PrefixRegOptions& opt2)
-{
-  return (opt1.getName() == opt2.getName() &&
-          opt1.getFaceId() == opt2.getFaceId() &&
-          opt1.getProtocol() == opt2.getProtocol());
-}
-
-
-Rib::const_iterator
-Rib::find(const PrefixRegOptions& options) const
-{
-  RibTable::const_iterator it = std::find_if(m_rib.begin(), m_rib.end(),
-                                             bind(&compareNameFaceProtocol, _1, options));
-  if (it == m_rib.end())
-    {
-      return end();
-    }
-  else
-    return it;
-}
-
-
-void
-Rib::insert(const PrefixRegOptions& options)
-{
-  RibTable::iterator it = std::find_if(m_rib.begin(), m_rib.end(),
-                                       bind(&compareNameFaceProtocol, _1, options));
-  if (it == m_rib.end())
-    {
-      m_rib.push_front(options);
-    }
-  else
-    {
-      //entry exist, update other fields
-      it->setFlags(options.getFlags());
-      it->setCost(options.getCost());
-      it->setExpirationPeriod(options.getExpirationPeriod());
-      it->setProtocol(options.getProtocol());
-    }
-}
-
-
-void
-Rib::erase(const PrefixRegOptions& options)
-{
-  RibTable::iterator it = std::find_if(m_rib.begin(), m_rib.end(),
-                                       bind(&compareNameFaceProtocol, _1, options));
-  if (it != m_rib.end())
-    {
-      m_rib.erase(it);
-    }
-}
-
-void
-Rib::erase(uint64_t faceId)
-{
-  //Keep it simple for now, with Trie this will be changed.
-  RibTable::iterator it = m_rib.begin();
-  while (it != m_rib.end())
-  {
-    if (it->getFaceId() == faceId)
-      it = m_rib.erase(it);
-    else
-      ++it;
-  }
-}
-
-} // namespace nrd
-} // namespace ndn
diff --git a/rib/src/rib.hpp b/rib/src/rib.hpp
deleted file mode 100644
index 3196817..0000000
--- a/rib/src/rib.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NRD_RIB_HPP
-#define NRD_RIB_HPP
-
-#include "common.hpp"
-
-namespace ndn {
-namespace nrd {
-
-/** \brief represents the RIB
- */
-class Rib
-{
-public:
-  typedef std::list<PrefixRegOptions> RibTable;
-  typedef RibTable::const_iterator const_iterator;
-
-  Rib();
-
-  ~Rib();
-
-  const_iterator
-  find(const PrefixRegOptions& options) const;
-
-  void
-  insert(const PrefixRegOptions& options);
-
-  void
-  erase(const PrefixRegOptions& options);
-
-  void
-  erase(uint64_t faceId);
-
-  const_iterator
-  begin() const;
-
-  const_iterator
-  end() const;
-
-  size_t
-  size() const;
-
-  size_t
-  empty() const;
-
-private:
-  // Note: Taking a list right now. A Trie will be used later to store
-  // prefixes
-  RibTable m_rib;
-};
-
-inline Rib::const_iterator
-Rib::begin() const
-{
-  return m_rib.begin();
-}
-
-inline Rib::const_iterator
-Rib::end() const
-{
-  return m_rib.end();
-}
-
-inline size_t
-Rib::size() const
-{
-  return m_rib.size();
-}
-
-inline size_t
-Rib::empty() const
-{
-  return m_rib.empty();
-}
-
-} // namespace nrd
-} // namespace ndn
-
-#endif // NRD_RIB_HPP
diff --git a/rib/tests/main.cpp b/rib/tests/main.cpp
deleted file mode 100644
index a7e827d..0000000
--- a/rib/tests/main.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#define BOOST_TEST_MAIN 1
-#define BOOST_TEST_DYN_LINK 1
-
-#include <boost/test/unit_test.hpp>
diff --git a/rib/tests/test-rib.cpp b/rib/tests/test-rib.cpp
deleted file mode 100644
index 920c606..0000000
--- a/rib/tests/test-rib.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Named Data Networking Project
- * See COPYING for copyright and distribution information.
- */
-
-#include "rib.hpp"
-
-#include <boost/test/unit_test.hpp>
-
-namespace ndn {
-namespace nrd {
-namespace tests {
-
-BOOST_AUTO_TEST_SUITE(TestRib)
-
-BOOST_AUTO_TEST_CASE(Basic)
-{
-  Rib rib;
-
-  PrefixRegOptions options1;
-  options1.setName("/hello/world");
-  options1.setFlags(tlv::nrd::NDN_FORW_CHILD_INHERIT | tlv::nrd::NDN_FORW_CAPTURE);
-  options1.setCost(10);
-  options1.setExpirationPeriod(time::milliseconds(1500));
-  options1.setFaceId(1);
-
-  rib.insert(options1);
-  BOOST_CHECK_EQUAL(rib.size(), 1);
-
-  PrefixRegOptions options2;
-  options2.setName("/hello/world");
-  options2.setFlags(tlv::nrd::NDN_FORW_CHILD_INHERIT);
-  options2.setExpirationPeriod(time::seconds(0));
-  options2.setFaceId(1);
-  options2.setCost(100);
-
-  rib.insert(options2);
-  BOOST_CHECK_EQUAL(rib.size(), 1);
-
-  options2.setFaceId(2);
-  rib.insert(options2);
-  BOOST_CHECK_EQUAL(rib.size(), 2);
-
-  options2.setName("/foo/bar");
-  rib.insert(options2);
-  BOOST_CHECK_EQUAL(rib.size(), 3);
-
-  rib.erase(options2);
-  BOOST_CHECK_EQUAL(rib.size(), 2);
-
-  options2.setName("/hello/world");
-  rib.erase(options2);
-  BOOST_CHECK_EQUAL(rib.size(), 1);
-
-  BOOST_CHECK(rib.find(options2) == rib.end());
-  BOOST_CHECK(rib.find(options1) != rib.end());
-
-  rib.erase(options1);
-  BOOST_CHECK(rib.empty());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nrd
-} // namespace ndn
diff --git a/rib/waf b/rib/waf
deleted file mode 100755
index 78a44f3..0000000
--- a/rib/waf
+++ /dev/null
Binary files differ
diff --git a/rib/wscript b/rib/wscript
deleted file mode 100644
index 1a7f82a..0000000
--- a/rib/wscript
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-from waflib import Logs
-
-def options(opt):
-    opt.load('compiler_cxx gnu_dirs')
-    opt.load('flags boost doxygen coverage', tooldir=['.waf-tools'])
-
-    nrdopt = opt.add_option_group('NRD Options')
-    nrdopt.add_option('--debug', action='store_true', default=False,
-                      dest='debug',
-                      help='''Compile library debugging mode without all optimizations (-O0)''')
-    nrdopt.add_option('--with-tests', action='store_true',
-                      default=False, dest='with_tests', help='''Build unit tests''')
-
-def configure(conf):
-    conf.load("compiler_cxx gnu_dirs boost flags")
-
-    conf.check_cfg(package='libndn-cpp-dev', args=['--cflags', '--libs'],
-                   uselib_store='NDN_CPP', mandatory=True)
-
-    boost_libs = 'system'
-    if conf.options.with_tests:
-        conf.env['WITH_TESTS'] = 1
-        conf.define('WITH_TESTS', 1);
-        boost_libs += ' unit_test_framework'
-
-    conf.check_boost(lib=boost_libs)
-    if conf.env.BOOST_VERSION_NUMBER < 104800:
-        Logs.error("Minimum required boost version is 1.48")
-        Logs.error("Please upgrade your distribution or install custom boost libraries" +
-                   " (http://redmine.named-data.net/projects/nfd/wiki/Boost_FAQ)")
-        return
-
-    # conf.load('coverage')
-
-    # try:
-    #     conf.load('doxygen')
-    # except:
-    #     pass
-
-    conf.define('DEFAULT_CONFIG_FILE', '%s/ndn/nrd.conf' % conf.env['SYSCONFDIR'])
-    conf.write_config_header('src/config.hpp')
-
-def build (bld):
-    bld(
-        features='cxx',
-        name='nrd-objects',
-        source=bld.path.ant_glob('src/*.cpp',
-                                 excl='src/main.cpp'),
-        use='NDN_CPP BOOST',
-        )
-
-    bld.program(
-        target='nrd',
-        source='src/main.cpp',
-        use='nrd-objects'
-        )
-
-    # Unit tests
-    if bld.env['WITH_TESTS']:
-        unit_tests = bld.program(
-            target='unit-tests',
-            features='cxx cxxprogram',
-            source=bld.path.ant_glob(['tests/**/*.cpp']),
-            use='nrd-objects',
-            includes=['.', 'src'],
-            install_prefix=None,
-            )
-
-    bld.install_files('${SYSCONFDIR}/ndn', 'nrd.conf.sample')
