diff --git a/src/mgmt/control-parameters.hpp b/src/mgmt/control-parameters.hpp
new file mode 100644
index 0000000..3a17091
--- /dev/null
+++ b/src/mgmt/control-parameters.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDN_MGMT_CONTROL_PARAMETERS_HPP
+#define NDN_MGMT_CONTROL_PARAMETERS_HPP
+
+#include "../encoding/block.hpp"
+
+namespace ndn {
+namespace mgmt {
+
+/** \brief base class for a struct that contains ControlCommand parameters
+ */
+class ControlParameters
+{
+public:
+  virtual void
+  wireDecode(const Block& wire) = 0;
+
+  virtual Block
+  wireEncode() const = 0;
+};
+
+} // namespace mgmt
+} // namespace ndn
+
+#endif // NDN_MGMT_CONTROL_PARAMETERS_HPP
diff --git a/src/mgmt/control-response.cpp b/src/mgmt/control-response.cpp
new file mode 100644
index 0000000..9c66f2a
--- /dev/null
+++ b/src/mgmt/control-response.cpp
@@ -0,0 +1,111 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "control-response.hpp"
+#include "../encoding/block-helpers.hpp"
+#include "../encoding/tlv-nfd.hpp"
+
+namespace ndn {
+namespace mgmt {
+
+// BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlResponse>));
+BOOST_CONCEPT_ASSERT((WireEncodable<ControlResponse>));
+BOOST_CONCEPT_ASSERT((WireDecodable<ControlResponse>));
+static_assert(std::is_base_of<tlv::Error, ControlResponse::Error>::value,
+              "ControlResponse::Error must inherit from tlv::Error");
+
+ControlResponse::ControlResponse()
+  : m_code(200)
+{
+}
+
+ControlResponse::ControlResponse(uint32_t code, const std::string& text)
+  : m_code(code)
+  , m_text(text)
+{
+}
+
+ControlResponse::ControlResponse(const Block& block)
+{
+  wireDecode(block);
+}
+
+const Block&
+ControlResponse::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  m_wire = Block(tlv::nfd::ControlResponse);
+  m_wire.push_back(nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
+
+  m_wire.push_back(dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
+
+  if (m_body.hasWire()) {
+    m_wire.push_back(m_body);
+  }
+
+  m_wire.encode();
+  return m_wire;
+}
+
+void
+ControlResponse::wireDecode(const Block& wire)
+{
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::nfd::ControlResponse)
+    throw Error("Requested decoding of ControlResponse, but Block is of different type");
+
+  Block::element_const_iterator val = m_wire.elements_begin();
+  if (val == m_wire.elements_end() || val->type() != tlv::nfd::StatusCode) {
+    throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
+  }
+
+  m_code = readNonNegativeInteger(*val);
+  ++val;
+
+  if (val == m_wire.elements_end() || val->type() != tlv::nfd::StatusText) {
+    throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
+  }
+  m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
+  ++val;
+
+  if (val != m_wire.elements_end())
+    m_body = *val;
+  else
+    m_body = Block();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const ControlResponse& response)
+{
+  os << response.getCode() << " " << response.getText();
+  return os;
+}
+
+} // namespace mgmt
+} // namespace ndn
diff --git a/src/mgmt/control-response.hpp b/src/mgmt/control-response.hpp
new file mode 100644
index 0000000..a107940
--- /dev/null
+++ b/src/mgmt/control-response.hpp
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDN_MGMT_CONTROL_RESPONSE_HPP
+#define NDN_MGMT_CONTROL_RESPONSE_HPP
+
+#include "../encoding/block.hpp"
+
+namespace ndn {
+namespace mgmt {
+
+/** \brief ControlCommand response
+ */
+class ControlResponse
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  ControlResponse();
+
+  ControlResponse(uint32_t code, const std::string& text);
+
+  explicit
+  ControlResponse(const Block& block);
+
+  uint32_t
+  getCode() const;
+
+  ControlResponse&
+  setCode(uint32_t code);
+
+  const std::string&
+  getText() const;
+
+  ControlResponse&
+  setText(const std::string& text);
+
+  const Block&
+  getBody() const;
+
+  ControlResponse&
+  setBody(const Block& body);
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& block);
+
+protected:
+  uint32_t m_code;
+  std::string m_text;
+  Block m_body;
+
+  mutable Block m_wire;
+};
+
+inline uint32_t
+ControlResponse::getCode() const
+{
+  return m_code;
+}
+
+inline ControlResponse&
+ControlResponse::setCode(uint32_t code)
+{
+  m_code = code;
+  m_wire.reset();
+  return *this;
+}
+
+inline const std::string&
+ControlResponse::getText() const
+{
+  return m_text;
+}
+
+inline ControlResponse&
+ControlResponse::setText(const std::string& text)
+{
+  m_text = text;
+  m_wire.reset();
+  return *this;
+}
+
+inline const Block&
+ControlResponse::getBody() const
+{
+  return m_body;
+}
+
+inline ControlResponse&
+ControlResponse::setBody(const Block& body)
+{
+  m_body = body;
+  m_body.encode(); // will do nothing if already encoded
+  m_wire.reset();
+  return *this;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const ControlResponse& response);
+
+} // namespace mgmt
+} // namespace ndn
+
+#endif // NDN_MGMT_CONTRO_RESPONSE_HPP
diff --git a/src/mgmt/dispatcher.cpp b/src/mgmt/dispatcher.cpp
new file mode 100644
index 0000000..b43334b
--- /dev/null
+++ b/src/mgmt/dispatcher.cpp
@@ -0,0 +1,310 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dispatcher.hpp"
+
+#include <algorithm>
+
+// #define NDN_CXX_MGMT_DISPATCHER_ENABLE_LOGGING
+
+namespace ndn {
+namespace mgmt {
+
+Authorization
+makeAcceptAllAuthorization()
+{
+  return [] (const Name& prefix,
+             const Interest& interest,
+             const ControlParameters* params,
+             AcceptContinuation accept,
+             RejectContinuation reject) {
+    accept("");
+  };
+}
+
+Dispatcher::Dispatcher(Face& face, security::KeyChain& keyChain,
+                       const security::SigningInfo& signingInfo)
+  : m_face(face)
+  , m_keyChain(keyChain)
+  , m_signingInfo(signingInfo)
+{
+}
+
+Dispatcher::~Dispatcher()
+{
+  std::vector<Name> topPrefixNames;
+
+  std::transform(m_topLevelPrefixes.begin(),
+                 m_topLevelPrefixes.end(),
+                 std::back_inserter(topPrefixNames),
+                 [] (const std::unordered_map<Name, TopPrefixEntry>::value_type& entry) {
+                   return entry.second.topPrefix;
+                 });
+
+  for (auto&& name : topPrefixNames) {
+    removeTopPrefix(name);
+  }
+}
+
+void
+Dispatcher::addTopPrefix(const Name& prefix,
+                         bool wantRegister,
+                         const security::SigningInfo& signingInfo)
+{
+  bool hasOverlap = std::any_of(m_topLevelPrefixes.begin(),
+                                m_topLevelPrefixes.end(),
+                                [&] (const std::unordered_map<Name, TopPrefixEntry>::value_type& x) {
+                                  return x.first.isPrefixOf(prefix) || prefix.isPrefixOf(x.first);
+                                });
+  if (hasOverlap) {
+    BOOST_THROW_EXCEPTION(std::out_of_range("Top-level Prefixes overlapped"));
+  }
+
+  TopPrefixEntry& topPrefixEntry = m_topLevelPrefixes[prefix];;
+  topPrefixEntry.topPrefix = prefix;
+  topPrefixEntry.wantRegister = wantRegister;
+
+  if (wantRegister) {
+    RegisterPrefixFailureCallback failure = [] (const Name& name, const std::string& reason) {
+      BOOST_THROW_EXCEPTION(std::runtime_error(reason));
+    };
+    topPrefixEntry.registerPrefixId =
+      m_face.registerPrefix(prefix, bind([]{}), failure, signingInfo);
+  }
+
+  for (auto&& entry : m_handlers) {
+    Name fullPrefix = prefix;
+    fullPrefix.append(entry.first);
+
+    const InterestFilterId* interestFilterId =
+      m_face.setInterestFilter(fullPrefix, std::bind(entry.second, prefix, _2));
+
+    topPrefixEntry.interestFilters.push_back(interestFilterId);
+  }
+}
+
+void
+Dispatcher::removeTopPrefix(const Name& prefix)
+{
+  auto it = m_topLevelPrefixes.find(prefix);
+  if (it == m_topLevelPrefixes.end()) {
+    return;
+  }
+
+  const TopPrefixEntry& topPrefixEntry = it->second;
+  if (topPrefixEntry.wantRegister) {
+    m_face.unregisterPrefix(topPrefixEntry.registerPrefixId, bind([]{}), bind([]{}));
+  }
+
+  for (auto&& filter : topPrefixEntry.interestFilters) {
+    m_face.unsetInterestFilter(filter);
+  }
+
+  m_topLevelPrefixes.erase(it);
+}
+
+bool
+Dispatcher::isOverlappedWithOthers(const PartialName& relPrefix)
+{
+  bool hasOverlapWithHandlers =
+    std::any_of(m_handlers.begin(), m_handlers.end(),
+                [&] (const HandlerMap::value_type& entry) {
+                  return entry.first.isPrefixOf(relPrefix) || relPrefix.isPrefixOf(entry.first);
+                });
+  bool hasOverlapWithStreams =
+    std::any_of(m_streams.begin(), m_streams.end(),
+                [&] (const std::unordered_map<PartialName, uint64_t>::value_type& entry) {
+                  return entry.first.isPrefixOf(relPrefix) || relPrefix.isPrefixOf(entry.first);
+                });
+
+  return hasOverlapWithHandlers || hasOverlapWithStreams;
+}
+
+void
+Dispatcher::afterAuthorizationRejected(RejectReply act, const Interest& interest)
+{
+  if (act == RejectReply::STATUS403) {
+    sendControlResponse(ControlResponse(403, "authorization rejected"), interest);
+  }
+}
+
+void
+Dispatcher::sendData(const Name& dataName, const Block& content,
+                     const MetaInfo& metaInfo)
+{
+  shared_ptr<Data> data = make_shared<Data>(dataName);
+  data->setContent(content).setMetaInfo(metaInfo);
+
+  m_keyChain.sign(*data, m_signingInfo);
+
+  try {
+    m_face.put(*data);
+  }
+  catch (Face::Error& e) {
+#ifdef NDN_CXX_MGMT_DISPATCHER_ENABLE_LOGGING
+    std::clog << e.what() << std::endl;
+#endif // NDN_CXX_MGMT_DISPATCHER_ENABLE_LOGGING.
+  }
+}
+
+void
+Dispatcher::processControlCommandInterest(const Name& prefix,
+                                          const Name& relPrefix,
+                                          const Interest& interest,
+                                          const ControlParametersParser& parser,
+                                          const Authorization& authorization,
+                                          const AuthorizationAcceptedCallback& accepted,
+                                          const AuthorizationRejectedCallback& rejected)
+{
+  // /<prefix>/<relPrefix>/<parameters>
+  size_t parametersLoc = prefix.size() + relPrefix.size();
+  const name::Component& pc = interest.getName().get(parametersLoc);
+
+  shared_ptr<ControlParameters> parameters;
+  try {
+    parameters = parser(pc);
+  }
+  catch (tlv::Error& e) {
+    return;
+  }
+
+  AcceptContinuation accept = bind(accepted, _1, prefix, interest, parameters.get());
+  RejectContinuation reject = bind(rejected, _1, interest);
+  authorization(prefix, interest, parameters.get(), accept, reject);
+}
+
+void
+Dispatcher::processAuthorizedControlCommandInterest(const std::string& requester,
+                                                    const Name& prefix,
+                                                    const Interest& interest,
+                                                    const ControlParameters* parameters,
+                                                    const ValidateParameters& validateParams,
+                                                    const ControlCommandHandler& handler)
+{
+  if (validateParams(*parameters)) {
+    handler(prefix, interest, *parameters,
+            bind(&Dispatcher::sendControlResponse, this, _1, interest, false));
+  }
+  else {
+    sendControlResponse(ControlResponse(400, "failed in validating parameters"), interest);
+  }
+}
+
+void
+Dispatcher::sendControlResponse(const ControlResponse& resp, const Interest& interest,
+                                bool isNack/*= false*/)
+{
+  MetaInfo info;
+  if (isNack) {
+    info.setType(tlv::ContentType_Nack);
+  }
+
+  sendData(interest.getName(), resp.wireEncode(), info);
+}
+
+void
+Dispatcher::addStatusDataset(const PartialName& relPrefix,
+                             Authorization authorization,
+                             StatusDatasetHandler handler)
+{
+  if (!m_topLevelPrefixes.empty()) {
+    BOOST_THROW_EXCEPTION(std::domain_error("one or more top-level prefix has been added"));
+  }
+
+  if (isOverlappedWithOthers(relPrefix)) {
+    BOOST_THROW_EXCEPTION(std::out_of_range("relPrefix overlapped"));
+  }
+
+  AuthorizationAcceptedCallback accepted =
+    bind(&Dispatcher::processAuthorizedStatusDatasetInterest, this,
+         _1, _2, _3, handler);
+  AuthorizationRejectedCallback rejected =
+    bind(&Dispatcher::afterAuthorizationRejected, this, _1, _2);
+  m_handlers[relPrefix] = bind(&Dispatcher::processStatusDatasetInterest, this,
+                               _1, _2, authorization, accepted, rejected);
+}
+
+void
+Dispatcher::processStatusDatasetInterest(const Name& prefix,
+                                         const Interest& interest,
+                                         const Authorization& authorization,
+                                         const AuthorizationAcceptedCallback& accepted,
+                                         const AuthorizationRejectedCallback& rejected)
+{
+  const Name& interestName = interest.getName();
+  bool endsWithVersionOrSegment = interestName.size() >= 1 &&
+                                  (interestName[-1].isVersion() || interestName[-1].isSegment());
+  if (endsWithVersionOrSegment) {
+    return;
+  }
+
+  AcceptContinuation accept = bind(accepted, _1, prefix, interest, nullptr);
+  RejectContinuation reject = bind(rejected, _1, interest);
+  authorization(prefix, interest, nullptr, accept, reject);
+}
+
+void
+Dispatcher::processAuthorizedStatusDatasetInterest(const std::string& requester,
+                                                   const Name& prefix,
+                                                   const Interest& interest,
+                                                   const StatusDatasetHandler& handler)
+{
+  StatusDatasetContext context(interest, bind(&Dispatcher::sendData, this, _1, _2, _3));
+  handler(prefix, interest, context);
+}
+
+PostNotification
+Dispatcher::addNotificationStream(const PartialName& relPrefix)
+{
+  if (!m_topLevelPrefixes.empty()) {
+    throw std::domain_error("one or more top-level prefix has been added");
+  }
+
+  if (isOverlappedWithOthers(relPrefix)) {
+    throw std::out_of_range("relPrefix overlaps with another relPrefix");
+  }
+
+  m_streams[relPrefix] = 0;
+  return bind(&Dispatcher::postNotification, this, _1, relPrefix);
+}
+
+void
+Dispatcher::postNotification(const Block& notification, const PartialName& relPrefix)
+{
+  if (m_topLevelPrefixes.empty() || m_topLevelPrefixes.size() > 1) {
+#ifdef NDN_CXX_MGMT_DISPATCHER_ENABLE_LOGGING
+    std::clog << "no top-level prefix or too many top-level prefixes" << std::endl;
+#endif // NDN_CXX_MGMT_DISPATCHER_ENABLE_LOGGING.
+    return;
+  }
+
+  Name streamName(m_topLevelPrefixes.begin()->second.topPrefix);
+  streamName.append(relPrefix);
+  streamName.appendSequenceNumber(m_streams[streamName]++);
+  sendData(streamName, notification, MetaInfo());
+}
+
+} // namespace mgmt
+} // namespace ndn
diff --git a/src/mgmt/dispatcher.hpp b/src/mgmt/dispatcher.hpp
new file mode 100644
index 0000000..922722f
--- /dev/null
+++ b/src/mgmt/dispatcher.hpp
@@ -0,0 +1,451 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDN_MGMT_DISPATCHER_HPP
+#define NDN_MGMT_DISPATCHER_HPP
+
+#include "../face.hpp"
+#include "../security/key-chain.hpp"
+#include "../encoding/block.hpp"
+#include "control-response.hpp"
+#include "control-parameters.hpp"
+#include "status-dataset-context.hpp"
+
+#include <unordered_map>
+
+namespace ndn {
+namespace mgmt {
+
+// ---- AUTHORIZATION ----
+
+/** \brief a function to be called if authorization is successful
+ *  \param requester a string that indicates the requester, whose semantics is determined by
+ *                   the Authorization function; this value is intended for logging only,
+ *                   and should not affect how the request is processed
+ */
+typedef std::function<void(const std::string& requester)> AcceptContinuation;
+
+/** \brief indicate how to reply in case authorization is rejected
+ */
+enum class RejectReply {
+  /** \brief do not reply
+   */
+  SILENT,
+  /** \brief reply with a ControlResponse where StatusCode is 403
+   */
+  STATUS403
+};
+
+/** \brief a function to be called if authorization is rejected
+ */
+typedef std::function<void(RejectReply act)> RejectContinuation;
+
+/** \brief a function that performs authorization
+ *  \param prefix top-level prefix, e.g., "/localhost/nfd";
+ *                This argument can be inspected to allow Interests only under a subset of
+ *                top-level prefixes (e.g., allow "/localhost/nfd" only),
+ *                or to use different trust model regarding to the prefix.
+ *  \param interest incoming Interest
+ *  \param params parsed ControlParameters for ControlCommand, otherwise nullptr;
+ *                This is guaranteed to be not-null and have correct type for the command,
+ *                but may not be valid (e.g., can have missing fields).
+ *
+ *  Either accept or reject must be called after authorization completes.
+ */
+typedef std::function<void(const Name& prefix, const Interest& interest,
+                           const ControlParameters* params,
+                           AcceptContinuation accept,
+                           RejectContinuation reject)> Authorization;
+
+/** \return an Authorization that accepts all Interests, with empty string as requester
+ */
+Authorization
+makeAcceptAllAuthorization();
+
+// ---- CONTROL COMMAND ----
+
+/** \brief a function to validate input ControlParameters
+ *  \param params parsed ControlParameters;
+ *                This is guaranteed to have correct type for the command.
+ */
+typedef std::function<bool(const ControlParameters& params)> ValidateParameters;
+
+/** \brief a function to be called after ControlCommandHandler completes
+ *  \param resp the response to be sent to requester
+ */
+typedef std::function<void(const ControlResponse& resp)> CommandContinuation;
+
+/** \brief a function to handle an authorized ControlCommand
+ *  \param prefix top-level prefix, e.g., "/localhost/nfd";
+ *  \param interest incoming Interest
+ *  \param params parsed ControlParameters;
+ *                This is guaranteed to have correct type for the command,
+ *                and is valid (e.g., has all required fields).
+ */
+typedef std::function<void(const Name& prefix, const Interest& interest,
+                           const ControlParameters& params,
+                           CommandContinuation done)> ControlCommandHandler;
+
+
+/** \brief a function to handle a StatusDataset request
+ *  \param prefix top-level prefix, e.g., "/localhost/nfd";
+ *  \param interest incoming Interest; its Name doesn't contain version and segment components
+ *
+ *  This function can generate zero or more blocks and pass them to \p append,
+ *  and must call \p end upon completion.
+ */
+typedef std::function<void(const Name& prefix, const Interest& interest,
+                           StatusDatasetContext& context)> StatusDatasetHandler;
+
+//---- NOTIFICATION STREAM ----
+
+/** \brief a function to post a notification
+ */
+typedef std::function<void(const Block& notification)> PostNotification;
+
+// ---- DISPATCHER ----
+
+/** \brief represents a dispatcher on server side of NFD Management protocol
+ */
+class Dispatcher : noncopyable
+{
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  /** \brief constructor
+   *  \param face the Face on which the dispatcher operates
+   *  \param keyChain a KeyChain to sign Data
+   *  \param signingInfo signing parameters to sign Data with \p keyChain
+   */
+  Dispatcher(Face& face, security::KeyChain& keyChain,
+             const security::SigningInfo& signingInfo = security::SigningInfo());
+
+  virtual
+  ~Dispatcher();
+
+  /** \brief add a top-level prefix
+   *  \param prefix a top-level prefix, e.g., "/localhost/nfd"
+   *  \param wantRegister whether prefix registration should be performed through the Face
+   *  \param signingInfo signing parameters to sign the prefix registration command
+   *  \throw std::out_of_range \p prefix overlaps with an existing top-level prefix
+   *
+   *  Procedure for adding a top-level prefix:
+   *  1. if the new top-level prefix overlaps with an existing top-level prefix
+   *     (one top-level prefix is a prefix of another top-level prefix), throw std::domain_error
+   *  2. if wantRegister is true, invoke face.registerPrefix for the top-level prefix;
+   *     the returned RegisteredPrefixId shall be recorded internally, indexed by the top-level
+   *     prefix
+   *  3. foreach relPrefix from ControlCommands and StatusDatasets,
+   *     join the top-level prefix with the relPrefix to obtain the full prefix,
+   *     and invoke non-registering overload of face.setInterestFilter,
+   *     with the InterestHandler set to an appropriate private method to handle incoming Interests
+   *     for the ControlCommand or StatusDataset;
+   *     the returned InterestFilterId shall be recorded internally, indexed by the top-level
+   *     prefix
+   */
+  void
+  addTopPrefix(const Name& prefix, bool wantRegister = true,
+               const security::SigningInfo& signingInfo = security::SigningInfo());
+
+  /** \brief remove a top-level prefix
+   *  \param prefix a top-level prefix, e.g., "/localhost/nfd"
+   *
+   *  Procedure for removing a top-level prefix:
+   *  1. if the top-level prefix has not been added, abort these steps
+   *  2. if the top-level prefix has been added with wantRegister,
+   *     invoke face.unregisterPrefix with the RegisteredPrefixId
+   *  3. foreach InterestFilterId recorded during addTopPrefix,
+   *     invoke face.unsetInterestFilter with the InterestFilterId
+   */
+  void
+  removeTopPrefix(const Name& prefix);
+
+public: // ControlCommand
+  /** \brief register a ControlCommand
+   *  \tparam CP subclass of ControlParameters used by this command
+   *  \param relPrefix a prefix for this command, e.g., "faces/create";
+   *                   relPrefixes in ControlCommands, StatusDatasets, NotificationStreams must be
+   *                   non-overlapping
+   *                   (no relPrefix is a prefix of another relPrefix)
+   *  \pre no top-level prefix has been added
+   *  \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix
+   *  \throw std::domain_error one or more top-level prefix has been added
+   *
+   *  Procedure for processing a ControlCommand:
+   *  1. extract the NameComponent containing ControlParameters (the component after relPrefix),
+   *     and parse ControlParameters into type CP; if parsing fails, abort these steps
+   *  2. perform authorization; if authorization is rejected,
+   *     perform the RejectReply action, and abort these steps
+   *  3. validate ControlParameters; if validation fails,
+   *     make ControlResponse with StatusCode 400, and go to step 5
+   *  4. invoke handler, wait until CommandContinuation is called
+   *  5. encode the ControlResponse into one Data packet
+   *  6. sign the Data packet
+   *  7. if the Data packet is too large, abort these steps and log an error
+   *  8. send the signed Data packet
+   */
+  template<typename CP>
+  void
+  addControlCommand(const PartialName& relPrefix,
+                    Authorization authorization,
+                    ValidateParameters validateParams,
+                    ControlCommandHandler handler);
+
+public: // StatusDataset
+  /** \brief register a StatusDataset or a prefix under which StatusDatasets can be requested
+   *  \param relPrefix a prefix for this dataset, e.g., "faces/list";
+   *                   relPrefixes in ControlCommands, StatusDatasets, NotificationStreams must be
+   *                   non-overlapping
+   *                   (no relPrefix is a prefix of another relPrefix)
+   *  \param authorization should set identity to Name() if the dataset is public
+   *  \pre no top-level prefix has been added
+   *  \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix
+   *  \throw std::domain_error one or more top-level prefix has been added
+   *
+   * The payload of the returned status dataset data packet is at most half of the maximum
+   * data packet size.
+   *
+   *  Procedure for processing a StatusDataset request:
+   *  1. if the request Interest contains version or segment components, abort these steps;
+   *     note: the request may contain more components after relPrefix, e.g., a query condition
+   *  2. perform authorization; if authorization is rejected,
+   *     perform the RejectReply action, and abort these steps
+   *  3. invoke handler, store blocks passed to StatusDatasetAppend calls in a buffer,
+   *     wait until StatusDatasetEnd is called
+   *  4. allocate a version
+   *  5. segment the buffer into one or more segments under the allocated version,
+   *     such that the Data packets will not become too large after signing
+   *  6. set FinalBlockId on at least the last segment
+   *  7. sign the Data packets
+   *  8. send the signed Data packets
+   *
+   *  As an optimization, a Data packet may be sent as soon as enough octets have been collected
+   *  through StatusDatasetAppend calls.
+   */
+  void
+  addStatusDataset(const PartialName& relPrefix,
+                   Authorization authorization,
+                   StatusDatasetHandler handler);
+
+public: // NotificationStream
+  /** \brief register a NotificationStream
+   *  \param relPrefix a prefix for this notification stream, e.g., "faces/events";
+   *                   relPrefixes in ControlCommands, StatusDatasets, NotificationStreams must be
+   *                   non-overlapping
+   *                   (no relPrefix is a prefix of another relPrefix)
+   *  \return a function into which notifications can be posted
+   *  \pre no top-level prefix has been added
+   *  \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix
+   *  \throw std::domain_error one or more top-level prefix has been added
+   *
+   *  Procedure for posting a notification:
+   *  1. if no top-level prefix has been added, or more than one top-level prefixes have been
+   *     added,
+   *     abort these steps and log an error
+   *  2. assign the next sequence number to the notification
+   *  3. place the notification block into one Data packet under the sole top-level prefix
+   *  4. sign the Data packet
+   *  5. if the Data packet is too large, abort these steps and log an error
+   *  6. send the signed Data packet
+   */
+  PostNotification
+  addNotificationStream(const PartialName& relPrefix);
+
+private:
+  typedef std::function<void(const Name& prefix,
+                             const Interest& interest)> InterestHandler;
+
+  typedef std::function<void(const std::string& requester,
+                             const Name& prefix,
+                             const Interest& interest,
+                             const ControlParameters*)> AuthorizationAcceptedCallback;
+
+  typedef std::function<void(RejectReply act,
+                             const Interest& interest)> AuthorizationRejectedCallback;
+
+  /**
+   * @brief the parser of extracting control parameters from name component.
+   *
+   * @param component name component that may encode control parameters.
+   * @return a shared pointer to the extracted control parameters.
+   * @throw tlv::Error if the NameComponent cannot be parsed as ControlParameters
+   */
+  typedef std::function<shared_ptr<ControlParameters>(const name::Component& component)>
+  ControlParametersParser;
+
+  bool
+  isOverlappedWithOthers(const PartialName& relPrefix);
+
+  /**
+   * @brief process unauthorized request
+   *
+   * @param act action to reply
+   * @param interest the incoming Interest
+   */
+  void
+  afterAuthorizationRejected(RejectReply act, const Interest& interest);
+
+  void
+  sendData(const Name& dataName, const Block& content,
+           const MetaInfo& metaInfo);
+
+  /**
+   * @brief process the control-command Interest before authorization.
+   *
+   * @param prefix the top-level prefix
+   * @param relPrefix the relative prefix
+   * @param interest the incoming Interest
+   * @param parser to extract control parameters from the \p interest
+   * @param authorization to process validation on this command
+   * @param accepted the callback for successful authorization
+   * @param rejected the callback for failed authorization
+   */
+  void
+  processControlCommandInterest(const Name& prefix,
+                                const Name& relPrefix,
+                                const Interest& interest,
+                                const ControlParametersParser& parser,
+                                const Authorization& authorization,
+                                const AuthorizationAcceptedCallback& accepted,
+                                const AuthorizationRejectedCallback& rejected);
+
+  /**
+   * @brief process the authorized control-command.
+   *
+   * @param requester the requester
+   * @param prefix the top-level prefix
+   * @param interest the incoming Interest
+   * @param parameters control parameters of this command
+   * @param validate to validate control parameters
+   * @param handler to process this command
+   */
+  void
+  processAuthorizedControlCommandInterest(const std::string& requester,
+                                          const Name& prefix,
+                                          const Interest& interest,
+                                          const ControlParameters* parameters,
+                                          const ValidateParameters& validate,
+                                          const ControlCommandHandler& handler);
+
+  void
+  sendControlResponse(const ControlResponse& resp, const Interest& interest, bool isNack = false);
+
+  /**
+   * @brief process the status-dataset Interest before authorization.
+   *
+   * @param prefix the top-level prefix
+   * @param interest the incoming Interest
+   * @param authorization to process verification
+   * @param accepted callback for successful authorization
+   * @param rejected callback for failed authorization
+   */
+  void
+  processStatusDatasetInterest(const Name& prefix,
+                               const Interest& interest,
+                               const Authorization& authorization,
+                               const AuthorizationAcceptedCallback& accepted,
+                               const AuthorizationRejectedCallback& rejected);
+
+  /**
+   * @brief process the authorized status-dataset request
+   *
+   * @param requester the requester
+   * @param prefix the top-level prefix
+   * @param interest the incoming Interest
+   * @param handler to process this request
+   */
+  void
+  processAuthorizedStatusDatasetInterest(const std::string& requester,
+                                         const Name& prefix,
+                                         const Interest& interest,
+                                         const StatusDatasetHandler& handler);
+
+  void
+  postNotification(const Block& notification, const PartialName& relPrefix);
+
+private:
+  struct TopPrefixEntry
+  {
+    Name topPrefix;
+    bool wantRegister;
+    const ndn::RegisteredPrefixId* registerPrefixId;
+    std::vector<const ndn::InterestFilterId*> interestFilters;
+  };
+  std::unordered_map<Name, TopPrefixEntry> m_topLevelPrefixes;
+
+  Face& m_face;
+  security::KeyChain& m_keyChain;
+  security::SigningInfo m_signingInfo;
+
+  typedef std::unordered_map<PartialName, InterestHandler> HandlerMap;
+  typedef HandlerMap::iterator HandlerMapIt;
+  HandlerMap m_handlers;
+
+  // NotificationStream name => next sequence number
+  std::unordered_map<Name, uint64_t> m_streams;
+};
+
+template<typename CP>
+void
+Dispatcher::addControlCommand(const PartialName& relPrefix,
+                              Authorization authorization,
+                              ValidateParameters validateParams,
+                              ControlCommandHandler handler)
+{
+  if (!m_topLevelPrefixes.empty()) {
+    throw std::domain_error("one or more top-level prefix has been added");
+  }
+
+  if (isOverlappedWithOthers(relPrefix)) {
+    throw std::out_of_range("relPrefix overlaps with another relPrefix");
+  }
+
+  ControlParametersParser parser =
+    [] (const name::Component& component) -> shared_ptr<ControlParameters> {
+    return make_shared<CP>(component.blockFromValue());
+  };
+
+  AuthorizationAcceptedCallback accepted =
+    bind(&Dispatcher::processAuthorizedControlCommandInterest, this,
+         _1, _2, _3, _4, validateParams, handler);
+
+  AuthorizationRejectedCallback rejected =
+    bind(&Dispatcher::afterAuthorizationRejected, this, _1, _2);
+
+  m_handlers[relPrefix] = bind(&Dispatcher::processControlCommandInterest, this,
+                               _1, relPrefix, _2, parser, authorization, accepted, rejected);
+}
+
+} // namespace mgmt
+} // namespace ndn
+#endif // NDN_MGMT_DISPATCHER_HPP
diff --git a/src/mgmt/status-dataset-context.cpp b/src/mgmt/status-dataset-context.cpp
new file mode 100644
index 0000000..1d386ef
--- /dev/null
+++ b/src/mgmt/status-dataset-context.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "status-dataset-context.hpp"
+
+namespace ndn {
+namespace mgmt {
+
+const time::milliseconds DEFAULT_STATUS_DATASET_FRESHNESS_PERIOD = time::milliseconds(1000);
+
+const Name&
+StatusDatasetContext::getPrefix() const
+{
+  return m_prefix;
+}
+
+StatusDatasetContext&
+StatusDatasetContext::setPrefix(const Name& prefix)
+{
+  if (!m_interest.getName().isPrefixOf(prefix)) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("prefix does not start with Interest Name"));
+  }
+
+  if (m_state != State::INITIAL) {
+    BOOST_THROW_EXCEPTION(std::domain_error("state is not in INITIAL"));
+  }
+
+  m_prefix = prefix;
+
+  if (!m_prefix[-1].isVersion()) {
+    m_prefix.appendVersion();
+  }
+
+  return *this;
+}
+
+const time::milliseconds&
+StatusDatasetContext::getExpiry() const
+{
+  return m_expiry;
+}
+
+StatusDatasetContext&
+StatusDatasetContext::setExpiry(const time::milliseconds& expiry)
+{
+  m_expiry = expiry;
+  return *this;
+}
+
+void
+StatusDatasetContext::append(const Block& block)
+{
+  if (m_state == State::FINALIZED) {
+    BOOST_THROW_EXCEPTION(std::domain_error("state is in FINALIZED"));
+  }
+
+  m_state = State::RESPONDED;
+
+  size_t nBytesLeft = block.size();
+
+  while (nBytesLeft > 0) {
+    size_t nBytesAppend = std::min(nBytesLeft,
+                                   (ndn::MAX_NDN_PACKET_SIZE >> 1) - m_buffer->size());
+    m_buffer->appendByteArray(block.wire() + (block.size() - nBytesLeft), nBytesAppend);
+    nBytesLeft -= nBytesAppend;
+
+    if (nBytesLeft > 0) {
+      const Block& content = makeBinaryBlock(tlv::Content, m_buffer->buf(), m_buffer->size());
+      m_dataSender(Name(m_prefix).appendSegment(m_segmentNo++), content,
+                   MetaInfo().setFreshnessPeriod(m_expiry));
+
+      m_buffer = std::make_shared<EncodingBuffer>();
+    }
+  }
+}
+
+void
+StatusDatasetContext::end()
+{
+  if (m_state == State::FINALIZED) {
+    BOOST_THROW_EXCEPTION(std::domain_error("state is in FINALIZED"));
+  }
+
+  m_state = State::FINALIZED;
+
+  auto dataName = Name(m_prefix).appendSegment(m_segmentNo++);
+  m_dataSender(dataName, makeBinaryBlock(tlv::Content, m_buffer->buf(), m_buffer->size()),
+               MetaInfo().setFreshnessPeriod(m_expiry).setFinalBlockId(dataName[-1]));
+}
+
+void
+StatusDatasetContext::reject(const ControlResponse& resp /*= a ControlResponse with 400*/)
+{
+  if (m_state != State::INITIAL) {
+    BOOST_THROW_EXCEPTION(std::domain_error("state is in REPONSED or FINALIZED"));
+  }
+
+  m_state = State::FINALIZED;
+
+  m_dataSender(m_interest.getName(), resp.wireEncode(),
+               MetaInfo().setType(tlv::ContentType_Nack));
+}
+
+StatusDatasetContext::StatusDatasetContext(const Interest& interest,
+                                           const DataSender& dataSender)
+  : m_interest(interest)
+  , m_dataSender(dataSender)
+  , m_expiry(DEFAULT_STATUS_DATASET_FRESHNESS_PERIOD)
+  , m_buffer(make_shared<EncodingBuffer>())
+  , m_segmentNo(0)
+  , m_state(State::INITIAL)
+{
+  setPrefix(interest.getName());
+}
+
+} // namespace mgmt
+} // namespace ndn
diff --git a/src/mgmt/status-dataset-context.hpp b/src/mgmt/status-dataset-context.hpp
new file mode 100644
index 0000000..196a296
--- /dev/null
+++ b/src/mgmt/status-dataset-context.hpp
@@ -0,0 +1,125 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDN_MGMT_STATUS_DATASET_CONTEXT_HPP
+#define NDN_MGMT_STATUS_DATASET_CONTEXT_HPP
+
+#include "../interest.hpp"
+#include "../data.hpp"
+#include "../util/time.hpp"
+#include "../encoding/encoding-buffer.hpp"
+#include "control-response.hpp"
+
+namespace ndn {
+namespace mgmt {
+
+class StatusDatasetContext
+{
+public:
+  /** \return prefix of Data packets, with version component but without segment component
+   */
+  const Name&
+  getPrefix() const;
+
+  /** \brief change prefix of Data packets
+   *  \param prefix the prefix; it must start with Interest Name, may contain version component,
+   *         but must not contain segment component
+   *  \throw std::invalid_argument prefix does not start with Interest Name
+   *  \throw std::domain_error append, end, or reject has been invoked
+   *
+   *  StatusDatasetHandler may change the prefix of Data packets with this method,
+   *  before sending any response.
+   *  The version component is optional, and will be generated from current timestamp when omitted.
+   */
+  StatusDatasetContext&
+  setPrefix(const Name& prefix);
+
+  /** \return expiration duration for this dataset response
+   */
+  const time::milliseconds&
+  getExpiry() const;
+
+  /** \brief set expiration duration
+   *
+   *  The response will be cached for the specified duration.
+   *  Incoming Interest that matches a cached response will be satisfied with that response,
+   *  without invoking StatusDatasetHandler again.
+   */
+  StatusDatasetContext&
+  setExpiry(const time::milliseconds& expiry);
+
+  /** \brief append a Block to the response
+   *  \throw std::domain_error end or reject has been invoked
+   */
+  void
+  append(const Block& block);
+
+  /** \brief end the response successfully after appending zero or more blocks
+   *  \throw std::domain_error reject has been invoked
+   */
+  void
+  end();
+
+  /** \brief declare the non-existence of a response
+   *  \throw std::domain_error append or end has been invoked
+   *
+   *  This should be invoked when the incoming Interest is malformed.
+   *  A producer-generated NACK will be returned to requester.
+   *
+   *  \param content Content of producer-generated NACK
+   */
+  void
+  reject(const ControlResponse& resp = ControlResponse().setCode(400));
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  typedef std::function<void(const Name& dataName, const Block& content,
+                             const MetaInfo& metaInfo)> DataSender;
+
+  StatusDatasetContext(const Interest& interest, const DataSender& dataSender);
+
+private:
+  friend class Dispatcher;
+
+  const Interest& m_interest;
+  DataSender m_dataSender;
+  Name m_prefix;
+  time::milliseconds m_expiry;
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  shared_ptr<EncodingBuffer> m_buffer;
+  uint64_t m_segmentNo;
+
+  enum class State {
+    INITIAL, ///< none of .append, .end, .reject has been invoked
+    RESPONDED, ///< .append has been invoked
+    FINALIZED ///< .end or .reject has been invoked
+  };
+  State m_state;
+};
+
+} // namespace mgmt
+} // namespace ndn
+
+#endif // NDN_MGMT_STATUS_DATASET_CONTEXT_HPP
