diff --git a/src/management/controller.hpp b/src/management/controller.hpp
deleted file mode 100644
index 5c32b3b..0000000
--- a/src/management/controller.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_CONTROLLER_HPP
-#define NDN_MANAGEMENT_CONTROLLER_HPP
-
-#include "../common.hpp"
-#include "../name.hpp"
-#include "../interest.hpp"
-#include "../data.hpp"
-
-namespace ndn {
-
-class Name;
-class Face;
-class IdentityCertificate;
-
-class Controller
-{
-public:
-  typedef function<void()>                   SuccessCallback;
-  typedef function<void(const std::string&)> FailCallback;
-
-  virtual
-  ~Controller()
-  {
-  }
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail) = 0;
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const IdentityCertificate& certificate) = 0;
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const Name& identity) = 0;
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail) = 0;
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const IdentityCertificate& certificate) = 0;
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const Name& identity) = 0;
-};
-
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_CONTROLLER_HPP
diff --git a/src/management/ndnd-controller.cpp b/src/management/ndnd-controller.cpp
deleted file mode 100644
index 6e917b0..0000000
--- a/src/management/ndnd-controller.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#include "common.hpp"
-#include "ndnd-controller.hpp"
-
-#include "../face.hpp"
-#include "../security/identity-certificate.hpp"
-#include "../security/signature-sha256-with-rsa.hpp"
-#include "../util/random.hpp"
-
-#include "ndnd-forwarding-entry.hpp"
-#include "ndnd-face-instance.hpp"
-#include "ndnd-status-response.hpp"
-
-namespace ndn {
-namespace ndnd {
-
-Controller::Controller(Face& face)
-  : m_face(face)
-  , m_faceId(-1)
-{
-}
-
-void
-Controller::selfRegisterPrefix(const Name& prefixToRegister,
-                               const SuccessCallback& onSuccess,
-                               const FailCallback&    onFail)
-{
-  if (!m_ndndId.hasValue())
-    {
-      if (m_filterRequests.empty())
-        {
-          m_face.expressInterest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"),
-                                 bind(&Controller::onNdnidFetched, this, _1, _2),
-                                 bind(onFail, "NDNDID fetching timed out"));
-        }
-      m_filterRequests.push_back(FilterRequest(prefixToRegister, onSuccess, onFail));
-    }
-  else
-    startPrefixAction(ForwardingEntry("selfreg", prefixToRegister),
-                      bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
-                      onFail);
-}
-
-void
-Controller::selfDeregisterPrefix(const Name& prefixToRegister,
-                                 const SuccessCallback& onSuccess,
-                                 const FailCallback&    onFail)
-{
-  if (!m_ndndId.hasValue() || m_faceId == -1)
-    {
-      if (static_cast<bool>(onFail))
-        onFail("NDNID is not available (must have been present after a successful registration operation)");
-      return;
-    }
-
-  startPrefixAction(ForwardingEntry("unreg", prefixToRegister, m_faceId),
-                    bind(onSuccess), onFail);
-}
-
-
-void
-Controller::onNdnidFetched(const Interest& interest, Data& data)
-{
-  if (data.getName().size() > interest.getName().size())
-    {
-      m_ndndId = data.getName()[interest.getName().size()];
-
-      if (m_ndndId.value_size() < 6)
-        {
-          for (FilterRequestList::iterator i = m_filterRequests.begin();
-               i != m_filterRequests.end();
-               ++i)
-            {
-              if (static_cast<bool>(i->m_onFailure))
-                i->m_onFailure("Fetched unrecognized NDNID");
-            }
-
-          return;
-        }
-
-      for (FilterRequestList::iterator i = m_filterRequests.begin();
-           i != m_filterRequests.end();
-           ++i)
-        {
-          startPrefixAction(ForwardingEntry("selfreg", i->m_prefixToRegister),
-                            bind(&Controller::recordSelfRegisteredFaceId, this, _1, i->m_onSuccess),
-                            i->m_onFailure);
-        }
-    }
-  else
-    {
-      for (FilterRequestList::iterator i = m_filterRequests.begin();
-           i != m_filterRequests.end();
-           ++i)
-        {
-          if (static_cast<bool>(i->m_onFailure))
-              i->m_onFailure("NDNID cannot be fetched");
-        }
-    }
-  m_filterRequests.clear();
-}
-
-void
-Controller::recordSelfRegisteredFaceId(const ForwardingEntry& entry,
-                                       const SuccessCallback& onSuccess)
-{
-  m_faceId = entry.getFaceId();
-  if (static_cast<bool>(onSuccess))
-    onSuccess();
-}
-
-void
-Controller::startFaceAction(const FaceInstance& entry,
-                            const FaceOperationSucceedCallback& onSuccess,
-                            const FailCallback& onFail)
-{
-  // Set the ForwardingEntry as the content of a Data packet and sign.
-  Data data;
-  data.setName(Name().appendVersion(random::generateWord32()));
-  data.setContent(entry.wireEncode());
-
-  // Create an empty signature, since nobody going to verify it for now
-  // @todo In the future, we may require real signatures to do the registration
-  SignatureSha256WithRsa signature;
-  signature.setValue(Block(Tlv::SignatureValue));
-  data.setSignature(signature);
-
-  // Create an interest where the name has the encoded Data packet.
-  Name interestName;
-  interestName.append("ndnx");
-  interestName.append(m_ndndId.value_begin()+6, m_ndndId.value_end());
-  interestName.append(entry.getAction());
-  interestName.append(data.wireEncode());
-
-  Interest interest(interestName);
-  interest.setScope(1);
-  interest.setInterestLifetime(time::seconds(1));
-  interest.setMustBeFresh(true);
-
-  m_face.expressInterest(interest,
-                         bind(&Controller::processFaceActionResponse, this, _2, onSuccess, onFail),
-                         bind(onFail, "Command Interest failed"));
-}
-
-void
-Controller::startPrefixAction(const ForwardingEntry& entry,
-                              const PrefixOperationSucceedCallback& onSuccess,
-                              const FailCallback& onFail)
-{
-  // Set the ForwardingEntry as the content of a Data packet and sign.
-  Data data;
-  data.setName(Name().appendVersion(random::generateWord32()));
-  data.setContent(entry.wireEncode());
-
-  // Create an empty signature, since nobody going to verify it for now
-  // @todo In the future, we may require real signatures to do the registration
-  SignatureSha256WithRsa signature;
-  signature.setValue(Block(Tlv::SignatureValue));
-  data.setSignature(signature);
-
-  // Create an interest where the name has the encoded Data packet.
-  Name interestName;
-  interestName.append("ndnx");
-  interestName.append(m_ndndId.value_begin() + 6, m_ndndId.value_end());
-  interestName.append(entry.getAction());
-  interestName.append(data.wireEncode());
-
-  Interest interest(interestName);
-  interest.setScope(1);
-  interest.setInterestLifetime(time::seconds(1));
-  interest.setMustBeFresh(true);
-
-  m_face.expressInterest(interest,
-                         bind(&Controller::processPrefixActionResponse, this, _2, onSuccess, onFail),
-                         bind(onFail, "Command Interest timed out"));
-}
-
-void
-Controller::processFaceActionResponse(Data& data,
-                                      const FaceOperationSucceedCallback& onSuccess,
-                                      const FailCallback& onFail)
-{
-  Block content = data.getContent();
-  content.parse();
-
-  if (content.elements().empty())
-    {
-      if (static_cast<bool>(onFail))
-        onFail("Empty response");
-      return;
-    }
-
-  Block::element_const_iterator val = content.elements_begin();
-
-  switch (val->type())
-    {
-    case tlv::ndnd::FaceInstance:
-      {
-        FaceInstance entry;
-        entry.wireDecode(*val);
-
-        if (static_cast<bool>(onSuccess))
-          onSuccess(entry);
-        return;
-      }
-    case tlv::ndnd::StatusResponse:
-      {
-        StatusResponse resp;
-        resp.wireDecode(*val);
-
-        if (static_cast<bool>(onFail))
-          onFail(resp.getInfo());
-        return;
-      }
-    default:
-      {
-        if (static_cast<bool>(onFail))
-          onFail("Invalid response");
-        return;
-      }
-    }
-}
-
-void
-Controller::processPrefixActionResponse(Data& data,
-                                        const PrefixOperationSucceedCallback& onSuccess,
-                                        const FailCallback& onFail)
-{
-  Block content = data.getContent();
-  content.parse();
-
-  if (content.elements().empty())
-    {
-      if (static_cast<bool>(onFail))
-        onFail("Empty response");
-      return;
-    }
-
-  Block::element_const_iterator val = content.elements_begin();
-
-  switch (val->type())
-    {
-    case tlv::ndnd::ForwardingEntry:
-      {
-        ForwardingEntry entry;
-        entry.wireDecode(*val);
-
-        if (static_cast<bool>(onSuccess))
-          onSuccess(entry);
-        return;
-      }
-    case tlv::ndnd::StatusResponse:
-      {
-        StatusResponse resp;
-        resp.wireDecode(*val);
-
-        // std::cerr << "StatusReponse: " << resp << std::endl;
-
-        if (static_cast<bool>(onFail))
-          onFail(resp.getInfo());
-        return;
-      }
-    default:
-      {
-        if (static_cast<bool>(onFail))
-          onFail("Invalid response");
-        return;
-      }
-    }
-}
-
-} // namespace ndnd
-} // namespace ndn
diff --git a/src/management/ndnd-controller.hpp b/src/management/ndnd-controller.hpp
deleted file mode 100644
index f6de05f..0000000
--- a/src/management/ndnd-controller.hpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_NDND_CONTROLLER_HPP
-#define NDN_MANAGEMENT_NDND_CONTROLLER_HPP
-
-#include "controller.hpp"
-
-namespace ndn {
-namespace ndnd {
-
-class FaceInstance;
-class ForwardingEntry;
-
-/*
- * @brief Class implementing Face and Prefix management operations for ndnd-tlv
- *
- * ndnd::Control should be used when connecting to ndnd-tlv daemon
- */
-class Controller : public ndn::Controller
-{
-public:
-  typedef function<void(const ForwardingEntry&)> PrefixOperationSucceedCallback;
-  typedef function<void(const FaceInstance&)>    FaceOperationSucceedCallback;
-
-  /**
-   * @brief Construct ndnd::Control object
-   */
-  Controller(Face& face);
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail);
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const IdentityCertificate& certificate)
-  {
-    selfRegisterPrefix(prefixToRegister, onSuccess, onFail);
-  }
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const Name& identity)
-  {
-    selfRegisterPrefix(prefixToRegister, onSuccess, onFail);
-  }
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail);
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const IdentityCertificate& certificate)
-  {
-    selfDeregisterPrefix(prefixToRegister, onSuccess, onFail);
-  }
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const Name& identity)
-  {
-    selfDeregisterPrefix(prefixToRegister, onSuccess, onFail);
-  }
-
-protected:
-  void
-  startFaceAction(const FaceInstance& entry,
-                  const FaceOperationSucceedCallback& onSuccess,
-                  const FailCallback& onFailure);
-
-  void
-  startPrefixAction(const ForwardingEntry& entry,
-                    const PrefixOperationSucceedCallback& onSuccess,
-                    const FailCallback& onFailure);
-
-private:
-  void
-  onNdnidFetched(const Interest& interest, Data& data);
-
-  void
-  recordSelfRegisteredFaceId(const ForwardingEntry& entry,
-                             const SuccessCallback& onSuccess);
-
-  void
-  processFaceActionResponse(Data& data,
-                            const FaceOperationSucceedCallback& onSuccess,
-                            const FailCallback&    onFail);
-
-  void
-  processPrefixActionResponse(Data& data,
-                              const PrefixOperationSucceedCallback& onSuccess,
-                              const FailCallback&    onFail);
-
-private:
-  Face& m_face;
-  Block m_ndndId;
-  int64_t m_faceId; // internal face ID (needed for prefix de-registration)
-
-  struct FilterRequest
-  {
-    FilterRequest(const Name& prefixToRegister,
-                  const SuccessCallback& onSuccess,
-                  const FailCallback&    onFailure)
-      : m_prefixToRegister(prefixToRegister)
-      , m_onSuccess(onSuccess)
-      , m_onFailure(onFailure)
-    {
-    }
-
-    Name             m_prefixToRegister;
-    SuccessCallback  m_onSuccess;
-    FailCallback     m_onFailure;
-  };
-
-  typedef std::list<FilterRequest> FilterRequestList;
-  FilterRequestList m_filterRequests;
-};
-
-} // namespace ndnd
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NDND_CONTROLLER_HPP
diff --git a/src/management/ndnd-face-instance.hpp b/src/management/ndnd-face-instance.hpp
deleted file mode 100644
index 87f04ed..0000000
--- a/src/management/ndnd-face-instance.hpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_NDND_FACE_INSTANCE_HPP
-#define NDN_MANAGEMENT_NDND_FACE_INSTANCE_HPP
-
-#include "../encoding/tlv-ndnd.hpp"
-#include "../encoding/block.hpp"
-#include "../name.hpp"
-
-namespace ndn {
-namespace ndnd {
-
-/**
- * An FaceInstance holds an action and  Name prefix and other fields for an forwarding entry.
- */
-class FaceInstance
-{
-public:
-  FaceInstance(const std::string& action,
-               int64_t     faceId,
-               uint32_t    ipProto,
-               const std::string& host,
-               const std::string& port,
-               const std::string& multicastInterface,
-               uint32_t    multicastTtl,
-               const time::milliseconds& freshnessPeriod)
-    : action_(action)
-    , faceId_(faceId)
-    , ipProto_(ipProto)
-    , host_(host)
-    , port_(port)
-    , multicastInterface_(multicastInterface)
-    , multicastTtl_(multicastTtl)
-    , freshnessPeriod_(freshnessPeriod)
-  {
-  }
-
-  FaceInstance()
-    : faceId_(-1)
-    , ipProto_(-1)
-    , multicastTtl_(-1)
-    , freshnessPeriod_(time::milliseconds::min())
-  {
-  }
-
-  /**
-   * @brief Create from wire encoding
-   */
-  explicit
-  FaceInstance(const Block& wire)
-  {
-    wireDecode(wire);
-  }
-
-  // Action
-  const std::string&
-  getAction() const { return action_; }
-
-  void
-  setAction(const std::string& action) { action_ = action; wire_.reset(); }
-
-  // FaceID
-  int64_t
-  getFaceId() const { return faceId_; }
-
-  void
-  setFaceId(int64_t faceId) { faceId_ = faceId; wire_.reset(); }
-
-  // IPProto
-  int32_t
-  getIpProto() const { return ipProto_; }
-
-  void
-  setIpProto(int32_t ipProto) { ipProto_ = ipProto; wire_.reset(); }
-
-  // Host
-  const std::string&
-  getHost() const { return host_; }
-
-  void
-  setHost(const std::string& host) { host_ = host; wire_.reset(); }
-
-  // Port
-  const std::string&
-  getPort() const { return port_; }
-
-  void
-  setPort(const std::string& port) { port_ = port; wire_.reset(); }
-
-  // MulticastInterface
-  const std::string&
-  getMulticastInterface() const { return multicastInterface_; }
-
-  void
-  setMulticastInterface(const std::string& multicastInterface)
-  {
-    multicastInterface_ = multicastInterface; wire_.reset();
-  }
-
-  // MulticastTTL
-  int32_t
-  getMulticastTtl() const { return multicastTtl_; }
-
-  void
-  setMulticastTtl(int32_t multicastTtl) { multicastTtl_ = multicastTtl; wire_.reset(); }
-
-  // Freshness
-  const time::milliseconds&
-  getFreshnessPeriod() const { return freshnessPeriod_; }
-
-  void
-  setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
-  {
-    freshnessPeriod_ = freshnessPeriod; wire_.reset();
-  }
-
-  // Wire
-  inline const Block&
-  wireEncode() const;
-
-  inline void
-  wireDecode(const Block& wire);
-
-private:
-  std::string action_;
-  int64_t     faceId_;
-  int32_t     ipProto_;
-  std::string host_;
-  std::string port_;
-  std::string multicastInterface_;
-  int32_t     multicastTtl_;
-  time::milliseconds freshnessPeriod_;
-
-  mutable Block wire_;
-};
-
-inline const Block&
-FaceInstance::wireEncode() const
-{
-  if (wire_.hasWire())
-    return wire_;
-
-  // FaceInstance ::= FACE-INSTANCE-TYPE TLV-LENGTH
-  //                  Action?
-  //                  FaceID?
-  //                  IPProto?
-  //                  Host?
-  //                  Port?
-  //                  MulticastInterface?
-  //                  MulticastTTL?
-  //                  FreshnessPeriod?
-
-  wire_ = Block(tlv::ndnd::FaceInstance);
-
-  // Action
-  if (!action_.empty())
-    {
-      wire_.push_back
-        (dataBlock(tlv::ndnd::Action, action_.c_str(), action_.size()));
-    }
-
-  // FaceID
-  if (faceId_ >= 0)
-    {
-      wire_.push_back
-        (nonNegativeIntegerBlock(tlv::ndnd::FaceID, faceId_));
-    }
-
-  // IPProto
-  if (ipProto_ >= 0)
-    {
-      wire_.push_back
-        (nonNegativeIntegerBlock(tlv::ndnd::IPProto, ipProto_));
-    }
-
-  // Host
-  if (!host_.empty())
-    {
-      wire_.push_back
-        (dataBlock(tlv::ndnd::Host, host_.c_str(), host_.size()));
-    }
-
-  // Port
-  if (!port_.empty())
-    {
-      wire_.push_back
-        (dataBlock(tlv::ndnd::Port, port_.c_str(), port_.size()));
-    }
-
-  // MulticastInterface
-  if (!multicastInterface_.empty())
-    {
-      wire_.push_back
-        (dataBlock(tlv::ndnd::MulticastInterface, multicastInterface_.c_str(), multicastInterface_.size()));
-    }
-
-  // MulticastTTL
-  if (multicastTtl_ >= 0)
-    {
-      wire_.push_back
-        (nonNegativeIntegerBlock(tlv::ndnd::MulticastTTL, multicastTtl_));
-    }
-
-  // FreshnessPeriod
-  if (freshnessPeriod_ >= time::milliseconds::zero())
-    {
-      wire_.push_back
-        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_.count()));
-    }
-
-  wire_.encode();
-  return wire_;
-}
-
-inline void
-FaceInstance::wireDecode(const Block& wire)
-{
-  action_.clear();
-  faceId_ = -1;
-  ipProto_ = -1;
-  host_.clear();
-  port_.clear();
-  multicastInterface_.clear();
-  multicastTtl_ = -1;
-  freshnessPeriod_ = time::milliseconds::min();
-
-  wire_ = wire;
-  wire_.parse();
-
-  // FaceInstance ::= FACE-INSTANCE-TYPE TLV-LENGTH
-  //                  Action?
-  //                  FaceID?
-  //                  IPProto?
-  //                  Host?
-  //                  Port?
-  //                  MulticastInterface?
-  //                  MulticastTTL?
-  //                  FreshnessPeriod?
-
-  // Action
-  Block::element_const_iterator val = wire_.find(tlv::ndnd::Action);
-  if (val != wire_.elements_end())
-    {
-      action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
-    }
-
-  // FaceID
-  val = wire_.find(tlv::ndnd::FaceID);
-  if (val != wire_.elements_end())
-    {
-      faceId_ = readNonNegativeInteger(*val);
-    }
-
-  // IPProto
-  val = wire_.find(tlv::ndnd::IPProto);
-  if (val != wire_.elements_end())
-    {
-      ipProto_ = readNonNegativeInteger(*val);
-    }
-
-  // Host
-  val = wire_.find(tlv::ndnd::Host);
-  if (val != wire_.elements_end())
-    {
-      host_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
-    }
-
-  // Port
-  val = wire_.find(tlv::ndnd::Port);
-  if (val != wire_.elements_end())
-    {
-      port_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
-    }
-
-  // MulticastInterface
-  val = wire_.find(tlv::ndnd::MulticastInterface);
-  if (val != wire_.elements_end())
-    {
-      multicastInterface_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
-    }
-
-  // MulticastTTL
-  val = wire_.find(tlv::ndnd::MulticastTTL);
-  if (val != wire_.elements_end())
-    {
-      multicastTtl_ = readNonNegativeInteger(*val);
-    }
-
-  // FreshnessPeriod
-  val = wire_.find(Tlv::FreshnessPeriod);
-  if (val != wire_.elements_end())
-    {
-      freshnessPeriod_ = time::milliseconds(readNonNegativeInteger(*val));
-    }
-}
-
-inline std::ostream&
-operator << (std::ostream& os, const FaceInstance& entry)
-{
-  os << "FaceInstance(";
-
-  // Action
-  if (!entry.getAction().empty())
-    {
-      os << "Action:" << entry.getAction() << ", ";
-    }
-
-  // FaceID
-  if (entry.getFaceId() >= 0)
-    {
-      os << "FaceID:" << entry.getFaceId() << ", ";
-    }
-
-  // IPProto
-  if (entry.getIpProto() >= 0)
-    {
-      os << "IPProto:" << entry.getIpProto() << ", ";
-    }
-
-  // Host
-  if (!entry.getHost().empty())
-    {
-      os << "Host:" << entry.getHost() << ", ";
-    }
-
-  // Port
-  if (!entry.getPort().empty())
-    {
-      os << "Port:" << entry.getPort() << ", ";
-    }
-
-  // MulticastInterface
-  if (!entry.getMulticastInterface().empty())
-    {
-      os << "MulticastInterface:" << entry.getMulticastInterface() << ", ";
-    }
-
-  // MulticastTTL
-  if (entry.getMulticastTtl() >= 0)
-    {
-      os << "MulticastTTL:" << entry.getMulticastTtl() << ", ";
-    }
-
-  // FreshnessPeriod
-  if (entry.getFreshnessPeriod() >= time::milliseconds::zero())
-    {
-      os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
-    }
-
-  os << ")";
-  return os;
-}
-
-} // namespace ndnd
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NDND_FACE_INSTANCE_HPP
diff --git a/src/management/ndnd-forwarding-entry.hpp b/src/management/ndnd-forwarding-entry.hpp
deleted file mode 100644
index a27c88a..0000000
--- a/src/management/ndnd-forwarding-entry.hpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_NDND_FORWARDING_ENTRY_HPP
-#define NDN_MANAGEMENT_NDND_FORWARDING_ENTRY_HPP
-
-#include "../encoding/tlv-ndnd.hpp"
-#include "../name.hpp"
-#include "../encoding/block.hpp"
-
-#include "ndnd-forwarding-flags.hpp"
-
-namespace ndn {
-namespace ndnd {
-
-/**
- * An ForwardingEntry holds an action and  Name prefix and other fields for an forwarding entry.
- */
-class ForwardingEntry
-{
-public:
-  ForwardingEntry(const std::string& action,
-                  const Name& prefix,
-                  int faceId = -1,
-                  const ForwardingFlags& forwardingFlags = ForwardingFlags(),
-                  time::milliseconds freshnessPeriod = time::milliseconds::min())
-    : action_(action)
-    , prefix_(prefix)
-    , faceId_(faceId)
-    , forwardingFlags_(forwardingFlags)
-    , freshnessPeriod_(freshnessPeriod)
-  {
-  }
-
-  ForwardingEntry()
-  : faceId_(-1)
-  , freshnessPeriod_(time::milliseconds::min())
-  {
-  }
-
-  /**
-   * @brief Create from wire encoding
-   */
-  explicit
-  ForwardingEntry(const Block& wire)
-  {
-    wireDecode(wire);
-  }
-
-  const std::string&
-  getAction() const { return action_; }
-
-  void
-  setAction(const std::string& action) { action_ = action; wire_.reset(); }
-
-  const Name&
-  getPrefix() const { return prefix_; }
-
-  void
-  setPrefix(const Name& prefix) { prefix_ = prefix; wire_.reset(); }
-
-  int
-  getFaceId() const { return faceId_; }
-
-  void
-  setFaceId(int faceId) { faceId_ = faceId; wire_.reset(); }
-
-  const ForwardingFlags&
-  getForwardingFlags() const { return forwardingFlags_; }
-
-  void
-  setForwardingFlags(const ForwardingFlags& forwardingFlags) { forwardingFlags_ = forwardingFlags; wire_.reset(); }
-
-  const time::milliseconds&
-  getFreshnessPeriod() const { return freshnessPeriod_; }
-
-  void
-  setFreshnessPeriod(const time::milliseconds& freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
-
-  inline const Block&
-  wireEncode() const;
-
-  inline void
-  wireDecode(const Block& wire);
-
-private:
-  std::string action_;   /**< empty for none. */
-  Name prefix_;
-  int faceId_;           /**< -1 for none. */
-  ForwardingFlags forwardingFlags_;
-  time::milliseconds freshnessPeriod_; /**< time::milliseconds::min() for none. */
-
-  mutable Block wire_;
-};
-
-inline const Block&
-ForwardingEntry::wireEncode() const
-{
-  if (wire_.hasWire())
-    return wire_;
-
-  // ForwardingEntry ::= FORWARDING-ENTRY TLV-LENGTH
-  //                       Action?
-  //                       Name?
-  //                       FaceID?
-  //                       ForwardingFlags?
-  //                       FreshnessPeriod?
-
-  wire_ = Block(tlv::ndnd::ForwardingEntry);
-
-  // Action
-  if (!action_.empty())
-    {
-      wire_.push_back
-        (dataBlock(tlv::ndnd::Action, action_.c_str(), action_.size()));
-    }
-
-  // Name
-  wire_.push_back
-    (prefix_.wireEncode());
-
-  // FaceID
-  if (faceId_ >= 0)
-    {
-      wire_.push_back
-        (nonNegativeIntegerBlock(tlv::ndnd::FaceID, faceId_));
-    }
-
-  // ForwardingFlags
-  wire_.push_back
-    (forwardingFlags_.wireEncode());
-
-  // FreshnessPeriod
-  if (freshnessPeriod_ >= time::milliseconds::zero())
-    {
-      wire_.push_back
-        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_.count()));
-    }
-
-  wire_.encode();
-  return wire_;
-}
-
-inline void
-ForwardingEntry::wireDecode(const Block& wire)
-{
-  action_.clear();
-  prefix_.clear();
-  faceId_ = -1;
-  forwardingFlags_ = ForwardingFlags();
-  freshnessPeriod_ = time::milliseconds::min();
-
-  wire_ = wire;
-  wire_.parse();
-
-  // ForwardingEntry ::= FORWARDING-ENTRY TLV-LENGTH
-  //                       Action?
-  //                       Name?
-  //                       FaceID?
-  //                       ForwardingFlags?
-  //                       FreshnessPeriod?
-
-  // Action
-  Block::element_const_iterator val = wire_.find(tlv::ndnd::Action);
-  if (val != wire_.elements_end())
-    {
-      action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
-    }
-
-  // Name
-  val = wire_.find(Tlv::Name);
-  if (val != wire_.elements_end())
-    {
-      prefix_.wireDecode(*val);
-    }
-
-  // FaceID
-  val = wire_.find(tlv::ndnd::FaceID);
-  if (val != wire_.elements_end())
-    {
-      faceId_ = readNonNegativeInteger(*val);
-    }
-
-  // ForwardingFlags
-  val = wire_.find(tlv::ndnd::ForwardingFlags);
-  if (val != wire_.elements_end())
-    {
-      forwardingFlags_.wireDecode(*val);
-    }
-
-  // FreshnessPeriod
-  val = wire_.find(Tlv::FreshnessPeriod);
-  if (val != wire_.elements_end())
-    {
-      freshnessPeriod_ = time::milliseconds(readNonNegativeInteger(*val));
-    }
-}
-
-inline std::ostream&
-operator << (std::ostream& os, const ForwardingEntry& entry)
-{
-  os << "ForwardingEntry(";
-
-  // Action
-  if (!entry.getAction().empty())
-    {
-      os << "Action:" << entry.getAction() << ", ";
-    }
-
-  // Name
-  os << "Prefix:" << entry.getPrefix() << ", ";
-
-  // FaceID
-  if (entry.getFaceId() >= 0)
-    {
-      os << "FaceID:" << entry.getFaceId() << ", ";
-    }
-
-  // ForwardingFlags
-  os << "ForwardingFlags:" << entry.getForwardingFlags() << ", ";
-
-  // FreshnessPeriod
-  if (entry.getFreshnessPeriod() >= time::milliseconds::zero())
-    {
-      os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
-    }
-
-  os << ")";
-  return os;
-}
-
-} // namespace ndnd
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NDND_FORWARDING_ENTRY_HPP
diff --git a/src/management/ndnd-forwarding-flags.hpp b/src/management/ndnd-forwarding-flags.hpp
deleted file mode 100644
index 4096277..0000000
--- a/src/management/ndnd-forwarding-flags.hpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_FORWARDING_FLAGS_HPP
-#define NDN_FORWARDING_FLAGS_HPP
-
-#include "../encoding/block.hpp"
-#include "../encoding/tlv-ndnd.hpp"
-
-namespace ndn {
-namespace ndnd {
-
-/**
- * A ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
- * a registered prefix.  We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
- * bits are changed, amended or deprecated.
- */
-class ForwardingFlags
-{
-public:
-  /**
-   * Create a new ForwardingFlags with "active" and "childInherit" set and all other flags cleared.
-   */
-  ForwardingFlags()
-    : active_(true)
-    , childInherit_(true)
-    , advertise_(false)
-    , last_(false)
-    , capture_(false)
-    , local_(false)
-    , tap_(false)
-    , captureOk_(false)
-  {
-  }
-
-  /**
-   * @brief Create from wire encoding
-   */
-  explicit
-  ForwardingFlags(const Block& wire)
-  {
-    wireDecode(wire);
-  }
-
-  /**
-   * Get the value of the "active" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getActive() const { return active_; }
-
-  /**
-   * Get the value of the "childInherit" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getChildInherit() const { return childInherit_; }
-
-  /**
-   * Get the value of the "advertise" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getAdvertise() const { return advertise_; }
-
-  /**
-   * Get the value of the "last" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getLast() const { return last_; }
-
-  /**
-   * Get the value of the "capture" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getCapture() const { return capture_; }
-
-  /**
-   * Get the value of the "local" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getLocal() const { return local_; }
-
-  /**
-   * Get the value of the "tap" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getTap() const { return tap_; }
-
-  /**
-   * Get the value of the "captureOk" flag.
-   * @return true if the flag is set, false if it is cleared.
-   */
-  bool getCaptureOk() const { return captureOk_; }
-
-  /**
-   * Set the value of the "active" flag
-   * @param active true to set the flag, false to clear it.
-   */
-  void setActive(bool active) { this->active_ = active; wire_.reset(); }
-
-  /**
-   * Set the value of the "childInherit" flag
-   * @param childInherit true to set the flag, false to clear it.
-   */
-  void setChildInherit(bool childInherit) { this->childInherit_ = childInherit; wire_.reset(); }
-
-  /**
-   * Set the value of the "advertise" flag
-   * @param advertise true to set the flag, false to clear it.
-   */
-  void setAdvertise(bool advertise) { this->advertise_ = advertise; wire_.reset(); }
-
-  /**
-   * Set the value of the "last" flag
-   * @param last true to set the flag, false to clear it.
-   */
-  void setLast(bool last) { this->last_ = last; wire_.reset(); }
-
-  /**
-   * Set the value of the "capture" flag
-   * @param capture true to set the flag, false to clear it.
-   */
-  void setCapture(bool capture) { this->capture_ = capture; wire_.reset(); }
-
-  /**
-   * Set the value of the "local" flag
-   * @param local true to set the flag, false to clear it.
-   */
-  void setLocal(bool local) { this->local_ = local; wire_.reset(); }
-
-  /**
-   * Set the value of the "tap" flag
-   * @param tap true to set the flag, false to clear it.
-   */
-  void setTap(bool tap) { this->tap_ = tap; wire_.reset(); }
-
-  /**
-   * Set the value of the "captureOk" flag
-   * @param captureOk true to set the flag, false to clear it.
-   */
-  void setCaptureOk(bool captureOk) { this->captureOk_ = captureOk; wire_.reset(); }
-
-  inline const Block&
-  wireEncode() const;
-
-  inline void
-  wireDecode(const Block& block);
-
-private:
-  bool active_;
-  bool childInherit_;
-  bool advertise_;
-  bool last_;
-  bool capture_;
-  bool local_;
-  bool tap_;
-  bool captureOk_;
-
-  mutable Block wire_;
-};
-
-inline const Block&
-ForwardingFlags::wireEncode() const
-{
-  if (wire_.hasWire())
-    return wire_;
-
-  uint32_t result = 0;
-  if (active_)
-    result |= tlv::ndnd::FORW_ACTIVE;
-  if (childInherit_)
-    result |= tlv::ndnd::FORW_CHILD_INHERIT;
-  if (advertise_)
-    result |= tlv::ndnd::FORW_ADVERTISE;
-  if (last_)
-    result |= tlv::ndnd::FORW_LAST;
-  if (capture_)
-    result |= tlv::ndnd::FORW_CAPTURE;
-  if (local_)
-    result |= tlv::ndnd::FORW_LOCAL;
-  if (tap_)
-    result |= tlv::ndnd::FORW_TAP;
-  if (captureOk_)
-    result |= tlv::ndnd::FORW_CAPTURE_OK;
-
-  wire_ = nonNegativeIntegerBlock(tlv::ndnd::ForwardingFlags, result);
-
-  return wire_;
-}
-
-inline void
-ForwardingFlags::wireDecode(const Block& wire)
-{
-  wire_ = wire;
-
-  uint32_t flags = readNonNegativeInteger(wire_);
-
-  active_       = (flags & tlv::ndnd::FORW_ACTIVE)        ? true : false;
-  childInherit_ = (flags & tlv::ndnd::FORW_CHILD_INHERIT) ? true : false;
-  advertise_    = (flags & tlv::ndnd::FORW_ADVERTISE)     ? true : false;
-  last_         = (flags & tlv::ndnd::FORW_LAST)          ? true : false;
-  capture_      = (flags & tlv::ndnd::FORW_CAPTURE)       ? true : false;
-  local_        = (flags & tlv::ndnd::FORW_LOCAL)         ? true : false;
-  tap_          = (flags & tlv::ndnd::FORW_TAP)           ? true : false;
-  captureOk_    = (flags & tlv::ndnd::FORW_CAPTURE_OK)    ? true : false;
-}
-
-inline std::ostream&
-operator << (std::ostream& os, const ForwardingFlags& flags)
-{
-  if (flags.getActive())
-    os << "ACTIVE ";
-  if (flags.getChildInherit())
-    os << "CHILE_INHERIT ";
-  if (flags.getAdvertise())
-    os << "ADVERTISE ";
-  if (flags.getLast())
-    os << "LAST ";
-  if (flags.getCapture())
-    os << "CAPTURE ";
-  if (flags.getLocal())
-    os << "LOCAL ";
-  if (flags.getTap())
-    os << "TAP ";
-  if (flags.getCaptureOk())
-    os << "CAPTURE_OK ";
-
-  return os;
-}
-
-} // namespace ndnd
-} // namespace ndn
-
-#endif
diff --git a/src/management/ndnd-status-response.hpp b/src/management/ndnd-status-response.hpp
deleted file mode 100644
index a918be1..0000000
--- a/src/management/ndnd-status-response.hpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_NDND_STATUS_RESPONSE_HPP
-#define NDN_MANAGEMENT_NDND_STATUS_RESPONSE_HPP
-
-#include "../encoding/block.hpp"
-#include "../encoding/tlv-ndnd.hpp"
-
-namespace ndn {
-namespace ndnd {
-
-class StatusResponse
-{
-public:
-  StatusResponse()
-    : code_(0)
-  {
-  }
-
-  StatusResponse(uint32_t code, const std::string& info)
-    : code_(code)
-    , info_(info)
-  {
-  }
-
-  /**
-   * @brief Create from wire encoding
-   */
-  explicit
-  StatusResponse(const Block& wire)
-  {
-    wireDecode(wire);
-  }
-
-  inline uint32_t
-  getCode() const;
-
-  inline void
-  setCode(uint32_t code);
-
-  inline const std::string&
-  getInfo() const;
-
-  inline void
-  setInfo(const std::string& info);
-
-  inline const Block&
-  wireEncode() const;
-
-  inline void
-  wireDecode(const Block& block);
-
-private:
-  uint32_t code_;
-  std::string info_;
-
-  mutable Block wire_;
-};
-
-inline uint32_t
-StatusResponse::getCode() const
-{
-  return code_;
-}
-
-inline void
-StatusResponse::setCode(uint32_t code)
-{
-  code_ = code;
-  wire_.reset();
-}
-
-inline const std::string&
-StatusResponse::getInfo() const
-{
-  return info_;
-}
-
-inline void
-StatusResponse::setInfo(const std::string& info)
-{
-  info_ = info;
-  wire_.reset();
-}
-
-
-inline const Block&
-StatusResponse::wireEncode() const
-{
-  if (wire_.hasWire())
-    return wire_;
-
-  wire_ = Block(tlv::ndnd::StatusResponse);
-  wire_.push_back
-    (nonNegativeIntegerBlock(tlv::ndnd::StatusCode, code_));
-
-  if (!info_.empty())
-    {
-      wire_.push_back
-        (dataBlock(tlv::ndnd::StatusText, info_.c_str(), info_.size()));
-    }
-
-  wire_.encode();
-  return wire_;
-}
-
-inline void
-StatusResponse::wireDecode(const Block& wire)
-{
-  wire_ = wire;
-  wire_.parse();
-
-  code_ = readNonNegativeInteger(wire_.get(tlv::ndnd::StatusCode));
-
-  Block::element_const_iterator val = wire_.find(tlv::ndnd::StatusText);
-  if (val != wire_.elements_end())
-    {
-      info_.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
-    }
-}
-
-inline std::ostream&
-operator << (std::ostream& os, const StatusResponse& status)
-{
-  os << status.getCode() << " " << status.getInfo();
-  return os;
-}
-
-} // namespace ndnd
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NDND_STATUS_RESPONSE_HPP
diff --git a/src/management/nfd-controller.cpp b/src/management/nfd-controller.cpp
index 661b08a..25800ff 100644
--- a/src/management/nfd-controller.cpp
+++ b/src/management/nfd-controller.cpp
@@ -69,45 +69,10 @@
     return;
   }
 
-  onSuccess(parameters);
+  if (static_cast<bool>(onSuccess))
+    onSuccess(parameters);
 }
 
 
-void
-Controller::selfRegisterPrefix(const Name& prefixToRegister,
-                               const SuccessCallback& onSuccess,
-                               const FailCallback& onFail,
-                               const Sign& sign)
-{
-  const uint32_t selfFaceId = 0;
-
-  ControlParameters parameters;
-  parameters.setName(prefixToRegister)
-            .setFaceId(selfFaceId);
-
-  this->start<FibAddNextHopCommand>(parameters,
-                                    bind(onSuccess),
-                                    bind(onFail, _2),
-                                    sign);
-}
-
-void
-Controller::selfDeregisterPrefix(const Name& prefixToDeRegister,
-                                 const SuccessCallback& onSuccess,
-                                 const FailCallback& onFail,
-                                 const Sign& sign)
-{
-  const uint32_t selfFaceId = 0;
-
-  ControlParameters parameters;
-  parameters.setName(prefixToDeRegister)
-            .setFaceId(selfFaceId);
-
-  this->start<FibRemoveNextHopCommand>(parameters,
-                                       bind(onSuccess),
-                                       bind(onFail, _2),
-                                       sign);
-}
-
 } // namespace nfd
 } // namespace ndn
diff --git a/src/management/nfd-controller.hpp b/src/management/nfd-controller.hpp
index 081389e..52b37a6 100644
--- a/src/management/nfd-controller.hpp
+++ b/src/management/nfd-controller.hpp
@@ -13,17 +13,15 @@
 #ifndef NDN_MANAGEMENT_NFD_CONTROLLER_HPP
 #define NDN_MANAGEMENT_NFD_CONTROLLER_HPP
 
-#include "controller.hpp"
 #include "nfd-control-command.hpp"
 #include "../face.hpp"
 
-
 namespace ndn {
 namespace nfd {
 
 /** \brief NFD Management protocol - ControlCommand client
  */
-class Controller : public ndn::Controller
+class Controller : noncopyable
 {
 public:
   /** \brief a callback on command success
@@ -48,27 +46,12 @@
   start(const ControlParameters& parameters,
         const CommandSucceedCallback& onSuccess,
         const CommandFailCallback& onFailure,
+        const IdentityCertificate& certificate = IdentityCertificate(),
         const time::milliseconds& timeout = getDefaultCommandTimeout())
   {
     start<Command>(parameters, onSuccess, onFailure,
                    bind(&CommandInterestGenerator::generate,
-                        &m_commandInterestGenerator, _1,
-                        Name()),
-                   timeout);
-  }
-
-  template<typename Command>
-  void
-  start(const ControlParameters& parameters,
-        const CommandSucceedCallback& onSuccess,
-        const CommandFailCallback& onFailure,
-        const IdentityCertificate& certificate,
-        const time::milliseconds& timeout = getDefaultCommandTimeout())
-  {
-    start<Command>(parameters, onSuccess, onFailure,
-                   bind(&CommandInterestGenerator::generate,
-                        &m_commandInterestGenerator, _1,
-                        cref(certificate.getName())),
+                        &m_commandInterestGenerator, _1, cref(certificate.getName())),
                    timeout);
   }
 
@@ -82,83 +65,10 @@
   {
     start<Command>(parameters, onSuccess, onFailure,
                    bind(&CommandInterestGenerator::generateWithIdentity,
-                        &m_commandInterestGenerator, _1,
-                        cref(identity)),
+                        &m_commandInterestGenerator, _1, cref(identity)),
                    timeout);
   }
 
-public: // selfreg using FIB Management commands
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail)
-  {
-    this->selfRegisterPrefix(prefixToRegister, onSuccess, onFail,
-                             bind(&CommandInterestGenerator::generate,
-                                  &m_commandInterestGenerator, _1,
-                                  Name()));
-  }
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const IdentityCertificate& certificate)
-  {
-    this->selfRegisterPrefix(prefixToRegister, onSuccess, onFail,
-                             bind(&CommandInterestGenerator::generate,
-                                  &m_commandInterestGenerator, _1,
-                                  cref(certificate.getName())));
-  }
-
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const Name& identity)
-  {
-    this->selfRegisterPrefix(prefixToRegister, onSuccess, onFail,
-                             bind(&CommandInterestGenerator::generateWithIdentity,
-                                  &m_commandInterestGenerator, _1,
-                                  cref(identity)));
-  }
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToDeRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail)
-  {
-    this->selfDeregisterPrefix(prefixToDeRegister, onSuccess, onFail,
-                               bind(&CommandInterestGenerator::generate,
-                                    &m_commandInterestGenerator, _1,
-                                    Name()));
-  }
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToDeRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const IdentityCertificate& certificate)
-  {
-    this->selfDeregisterPrefix(prefixToDeRegister, onSuccess, onFail,
-                               bind(&CommandInterestGenerator::generate,
-                                    &m_commandInterestGenerator, _1,
-                                    cref(certificate.getName())));
-  }
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToDeRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const Name& identity)
-  {
-    this->selfDeregisterPrefix(prefixToDeRegister, onSuccess, onFail,
-                               bind(&CommandInterestGenerator::generateWithIdentity,
-                                    &m_commandInterestGenerator, _1,
-                                    cref(identity)));
-  }
-
-protected:
   template<typename Command>
   void
   start(const ControlParameters& parameters,
@@ -167,18 +77,6 @@
         const Sign& sign,
         const time::milliseconds& timeout = getDefaultCommandTimeout());
 
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const Sign& sign);
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToDeRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const Sign& sign);
-
 private:
   void
   processCommandResponse(const Data& data,
@@ -198,9 +96,8 @@
   CommandInterestGenerator m_commandInterestGenerator;
 };
 
-
 template<typename Command>
-void
+inline void
 Controller::start(const ControlParameters& parameters,
                   const CommandSucceedCallback& onSuccess,
                   const CommandFailCallback&    onFailure,
diff --git a/src/management/nrd-controller.cpp b/src/management/nrd-controller.cpp
deleted file mode 100644
index b023277..0000000
--- a/src/management/nrd-controller.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#include "nrd-controller.hpp"
-#include "nrd-prefix-reg-options.hpp"
-#include "nfd-control-response.hpp" // used in deprecated function only
-#include "../security/identity-certificate.hpp"
-
-
-namespace ndn {
-namespace nrd {
-
-using nfd::ControlParameters;
-using nfd::RibRegisterCommand;
-using nfd::RibUnregisterCommand;
-
-Controller::Controller(Face& face)
-  : nfd::Controller(face)
-{
-}
-
-void
-Controller::selfRegisterPrefix(const Name& prefixToRegister,
-                               const SuccessCallback& onSuccess,
-                               const FailCallback&    onFail,
-                               const Sign& sign)
-{
-  ControlParameters parameters;
-  parameters.setName(prefixToRegister);
-
-  this->start<RibRegisterCommand>(parameters,
-                                  bind(onSuccess),
-                                  bind(onFail, _2),
-                                  sign);
-}
-
-void
-Controller::selfDeregisterPrefix(const Name& prefixToRegister,
-                                 const SuccessCallback& onSuccess,
-                                 const FailCallback&    onFail,
-                                 const Sign& sign)
-{
-  ControlParameters parameters;
-  parameters.setName(prefixToRegister);
-
-  this->start<RibUnregisterCommand>(parameters,
-                                    bind(onSuccess),
-                                    bind(onFail, _2),
-                                    sign);
-}
-
-void
-Controller::registerPrefix(const PrefixRegOptions& options,
-                           const CommandSucceedCallback& onSuccess,
-                           const FailCallback& onFail)
-{
-  startCommand("register", options, onSuccess, onFail);
-}
-
-void
-Controller::unregisterPrefix(const PrefixRegOptions& options,
-                             const CommandSucceedCallback& onSuccess,
-                             const FailCallback& onFail)
-{
-  startCommand("unregister", options, onSuccess, onFail);
-}
-
-void
-Controller::advertisePrefix(const PrefixRegOptions& options,
-                            const CommandSucceedCallback& onSuccess,
-                            const FailCallback& onFail)
-{
-  startCommand("advertise", options, onSuccess, onFail);
-}
-
-void
-Controller::withdrawPrefix(const PrefixRegOptions& options,
-                            const CommandSucceedCallback& onSuccess,
-                            const FailCallback& onFail)
-{
-  startCommand("withdraw", options, onSuccess, onFail);
-}
-
-void
-Controller::startCommand(const std::string& command,
-                         const PrefixRegOptions& options,
-                         const CommandSucceedCallback& onSuccess,
-                         const FailCallback& onFail)
-{
-  Name commandInterestName("/localhost/nrd");
-  commandInterestName
-    .append(command)
-    .append(options.wireEncode());
-
-  Interest commandInterest(commandInterestName);
-  m_commandInterestGenerator.generate(commandInterest);
-
-  m_face.expressInterest(commandInterest,
-                         bind(&Controller::processCommandResponse, this, _2,
-                              onSuccess, onFail),
-                         bind(onFail, "Command Interest timed out"));
-}
-
-void
-Controller::processCommandResponse(Data& data,
-                                   const CommandSucceedCallback& onSuccess,
-                                   const FailCallback& onFail)
-{
-  /// \todo Add validation of incoming Data
-
-  try
-    {
-      nfd::ControlResponse response(data.getContent().blockFromValue());
-      if (response.getCode() != 200)
-        return onFail(response.getText());
-
-      PrefixRegOptions options(response.getBody());
-      return onSuccess(options);
-    }
-  catch (ndn::Tlv::Error& e)
-    {
-      if (static_cast<bool>(onFail))
-        return onFail(e.what());
-    }
-}
-
-} // namespace nrd
-} // namespace ndn
diff --git a/src/management/nrd-controller.hpp b/src/management/nrd-controller.hpp
deleted file mode 100644
index 1aba57f..0000000
--- a/src/management/nrd-controller.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_NRD_CONTROLLER_HPP
-#define NDN_MANAGEMENT_NRD_CONTROLLER_HPP
-
-#include "nfd-controller.hpp"
-
-namespace ndn {
-namespace nrd {
-
-/// \deprecated
-class PrefixRegOptions;
-
-class Controller : public nfd::Controller
-{
-public:
-  /** \brief a callback on signing command interest
-   */
-  typedef function<void(Interest&)> Sign;
-
-  /// \deprecated
-  typedef function<void(const PrefixRegOptions&)> CommandSucceedCallback;
-
-  explicit
-  Controller(Face& face);
-
-public:
-  /// \deprecated .start<RibRegisterCommand>
-  void
-  registerPrefix(const PrefixRegOptions& options,
-                 const CommandSucceedCallback& onSuccess,
-                 const FailCallback& onFail);
-
-  /// \deprecated .start<RibUnregisterCommand>
-  void
-  unregisterPrefix(const PrefixRegOptions& options,
-                 const CommandSucceedCallback& onSuccess,
-                 const FailCallback&    onFail);
-
-  /// \deprecated
-  void
-  advertisePrefix(const PrefixRegOptions& options,
-                  const CommandSucceedCallback& onSuccess,
-                  const FailCallback& onFail);
-
-  /// \deprecated
-  void
-  withdrawPrefix(const PrefixRegOptions& options,
-                 const CommandSucceedCallback& onSuccess,
-                 const FailCallback& onFail);
-
-protected:
-  /// \deprecated
-  void
-  startCommand(const std::string& command,
-               const PrefixRegOptions& options,
-               const CommandSucceedCallback& onSuccess,
-               const FailCallback& onFailure);
-
-  // selfreg using RIB Management commands
-  virtual void
-  selfRegisterPrefix(const Name& prefixToRegister,
-                     const SuccessCallback& onSuccess,
-                     const FailCallback&    onFail,
-                     const Sign& sign);
-
-  virtual void
-  selfDeregisterPrefix(const Name& prefixToDeRegister,
-                       const SuccessCallback& onSuccess,
-                       const FailCallback&    onFail,
-                       const Sign& sign);
-
-private:
-  /// \deprecated
-  void
-  processCommandResponse(Data& data,
-                         const CommandSucceedCallback& onSuccess,
-                         const FailCallback& onFail);
-};
-
-} // namespace nrd
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NRD_CONTROLLER_HPP
diff --git a/src/management/nrd-prefix-reg-options.hpp b/src/management/nrd-prefix-reg-options.hpp
deleted file mode 100644
index f821e66..0000000
--- a/src/management/nrd-prefix-reg-options.hpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (c) 2013-2014,  Regents of the University of California.
- * All rights reserved.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * This file licensed under New BSD License.  See COPYING for detailed information about
- * ndn-cxx library copyright, permissions, and redistribution restrictions.
- */
-
-#ifndef NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP
-#define NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP
-
-#include "../encoding/encoding-buffer.hpp"
-#include "../encoding/tlv-nrd.hpp"
-#include "../name.hpp"
-
-namespace ndn {
-namespace nrd {
-
-const uint64_t INVALID_FACE_ID = std::numeric_limits<uint64_t>::max();
-const uint64_t DEFAULT_COST = 0;
-const uint64_t DEFAULT_FLAGS = tlv::nrd::NDN_FORW_CHILD_INHERIT;
-
-/**
- * @brief Abstraction for prefix registration options for NRD Prefix registration protocol
- *
- * @see http://redmine.named-data.net/projects/nrd/wiki/NRD_Prefix_Registration_protocol
- * @deprecated use NFD RIB Management
- */
-class PrefixRegOptions
-{
-public:
-  class Error : public Tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : Tlv::Error(what)
-    {
-    }
-  };
-
-  PrefixRegOptions()
-    : m_faceId(INVALID_FACE_ID)
-    , m_flags(DEFAULT_FLAGS)
-    , m_cost(DEFAULT_COST)
-    , m_expirationPeriod(time::milliseconds::min())
-  {
-  }
-
-  explicit
-  PrefixRegOptions(const Block& block)
-  {
-    wireDecode(block);
-  }
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  void
-  wireDecode(const Block& wire);
-
-  ////////////////////////////////////////////////////////
-
-  const Name&
-  getName() const
-  {
-    return m_name;
-  }
-
-  PrefixRegOptions&
-  setName(const Name& name)
-  {
-    m_name = name;
-    m_wire.reset();
-    return *this;
-  }
-
-  //
-
-  uint64_t
-  getFaceId() const
-  {
-    return m_faceId;
-  }
-
-  PrefixRegOptions&
-  setFaceId(uint64_t faceId)
-  {
-    m_faceId = faceId;
-    m_wire.reset();
-    return *this;
-  }
-
-  //
-
-  uint64_t
-  getFlags() const
-  {
-    return m_flags;
-  }
-
-  PrefixRegOptions&
-  setFlags(uint64_t flags)
-  {
-    m_flags = flags;
-    m_wire.reset();
-    return *this;
-  }
-
-  //
-
-  uint64_t
-  getCost() const
-  {
-    return m_cost;
-  }
-
-  PrefixRegOptions&
-  setCost(uint64_t cost)
-  {
-    m_cost = cost;
-    m_wire.reset();
-    return *this;
-  }
-
-  //
-
-  const time::milliseconds&
-  getExpirationPeriod() const
-  {
-    return m_expirationPeriod;
-  }
-
-  PrefixRegOptions&
-  setExpirationPeriod(const time::milliseconds& expirationPeriod)
-  {
-    m_expirationPeriod = expirationPeriod;
-    m_wire.reset();
-    return *this;
-  }
-
-  //
-
-  const std::string&
-  getProtocol() const
-  {
-    return m_protocol;
-  }
-
-  PrefixRegOptions&
-  setProtocol(const std::string& protocol)
-  {
-    m_protocol = protocol;
-    m_wire.reset();
-    return *this;
-  }
-
-private:
-  Name m_name;
-  uint64_t m_faceId;
-  uint64_t m_flags;
-  uint64_t m_cost;
-  time::milliseconds m_expirationPeriod;
-  std::string m_protocol;
-
-  mutable Block m_wire;
-};
-
-template<bool T>
-inline size_t
-PrefixRegOptions::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
-  //                        Name
-  //                        FaceId?
-  //                        Flags?
-  //                        Cost?
-  //                        ExpirationPeriod?
-  //                        Protocol?
-
-  // (reverse encoding)
-
-  // Protocol
-  if (!m_protocol.empty())
-    {
-      totalLength += prependByteArrayBlock(block,
-                                           tlv::nrd::Protocol,
-                                           reinterpret_cast<const uint8_t*>(m_protocol.c_str()),
-                                           m_protocol.size());
-    }
-
-  // ExpirationPeriod
-  if (m_expirationPeriod > time::milliseconds::zero())
-    {
-      totalLength += prependNonNegativeIntegerBlock(block,
-                                                    tlv::nrd::ExpirationPeriod,
-                                                    m_expirationPeriod.count());
-    }
-
-  // Cost
-  if (m_cost != DEFAULT_COST)
-    {
-      totalLength += prependNonNegativeIntegerBlock(block, tlv::nrd::Cost, m_cost);
-    }
-
-  // Flags
-  if (m_flags != DEFAULT_FLAGS)
-    {
-      totalLength += prependNonNegativeIntegerBlock(block, tlv::nrd::Flags, m_flags);
-    }
-
-  // FaceId
-  if (m_faceId != INVALID_FACE_ID)
-    {
-      totalLength += prependNonNegativeIntegerBlock(block, tlv::nrd::FaceId, m_faceId);
-    }
-
-  // Name
-  totalLength += m_name.wireEncode(block);
-
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::nrd::PrefixRegOptions);
-  return totalLength;
-}
-
-inline const Block&
-PrefixRegOptions::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-inline void
-PrefixRegOptions::wireDecode(const Block& wire)
-{
-  // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
-  //                        Name
-  //                        FaceId?
-  //                        Flags?
-  //                        Cost?
-  //                        ExpirationPeriod?
-  //                        Protocol?
-
-  m_name.clear();
-  m_faceId = INVALID_FACE_ID;
-  m_flags = DEFAULT_FLAGS;
-  m_cost = DEFAULT_COST;
-  m_expirationPeriod = time::milliseconds::min();
-  m_protocol.clear();
-
-  m_wire = wire;
-
-  if (m_wire.type() != tlv::nrd::PrefixRegOptions)
-    throw Error("Requested decoding of PrefixRegOptions, but Block is of different type");
-
-  m_wire.parse ();
-
-  // Name
-  Block::element_const_iterator val = m_wire.find(Tlv::Name);
-  if (val != m_wire.elements_end())
-    {
-      m_name.wireDecode(*val);
-    }
-
-  // FaceId
-  val = m_wire.find(tlv::nrd::FaceId);
-  if (val != m_wire.elements_end())
-    {
-      m_faceId = readNonNegativeInteger(*val);
-    }
-
-  // Flags
-  val = m_wire.find(tlv::nrd::Flags);
-  if (val != m_wire.elements_end())
-    {
-      m_flags = readNonNegativeInteger(*val);
-    }
-
-  // Cost
-  val = m_wire.find(tlv::nrd::Cost);
-  if (val != m_wire.elements_end())
-    {
-      m_cost = readNonNegativeInteger(*val);
-    }
-
-  // ExpirationPeriod
-  val = m_wire.find(tlv::nrd::ExpirationPeriod);
-  if (val != m_wire.elements_end())
-    {
-      m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
-    }
-
-  // Protocol
-  val = m_wire.find(tlv::nrd::Protocol);
-  if (val != m_wire.elements_end())
-    {
-      m_protocol = std::string(reinterpret_cast<const char*>(val->value()),
-                               val->value_size());
-    }
-}
-
-inline std::ostream&
-operator << (std::ostream& os, const PrefixRegOptions& option)
-{
-  os << "PrefixRegOptions(";
-
-  // Name
-  os << "Prefix: " << option.getName() << ", ";
-
-  // FaceID
-  os << "FaceID: " << option.getFaceId() << ", ";
-
-  // Flags
-  os << "Flags: " << option.getFlags() << ", ";
-
-  // Cost
-  os << "Cost: " << option.getCost() << ", ";
-
-  // ExpirationPeriod
-  os << "ExpirationPeriod: " << option.getExpirationPeriod() << ", ";
-
-  // Protocol
-  os << "Protocol: " << option.getProtocol();
-
-  os << ")";
-  return os;
-}
-
-} // namespace nrd
-} // namespace ndn
-
-#endif // NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP
