diff --git a/AUTHORS.md b/AUTHORS.md
index 5cd6e45..e9bfc0a 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -35,3 +35,4 @@
 * Eric Newberry         <http://ericnewberry.com>
 * João Pereira          <http://website.jpereira.co.uk>
 * Mickey Sweatt         <https://www.linkedin.com/in/michaelsweatt>
+* Yanbiao Li            <https://www.linkedin.com/pub/yanbiao-li/24/7a1/4ba>
diff --git a/src/management/nfd-control-command.hpp b/src/management/nfd-control-command.hpp
index a7b8bc6..9d3cbb3 100644
--- a/src/management/nfd-control-command.hpp
+++ b/src/management/nfd-control-command.hpp
@@ -307,7 +307,6 @@
   validateResponse(const ControlParameters& parameters) const;
 };
 
-
 } // namespace nfd
 } // namespace ndn
 
diff --git a/src/management/nfd-control-parameters.cpp b/src/management/nfd-control-parameters.cpp
index f8ce363..d777843 100644
--- a/src/management/nfd-control-parameters.cpp
+++ b/src/management/nfd-control-parameters.cpp
@@ -95,7 +95,7 @@
 template size_t
 ControlParameters::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>&) const;
 
-const Block&
+Block
 ControlParameters::wireEncode() const
 {
   if (m_wire.hasWire())
diff --git a/src/management/nfd-control-parameters.hpp b/src/management/nfd-control-parameters.hpp
index 29434fc..3a099cc 100644
--- a/src/management/nfd-control-parameters.hpp
+++ b/src/management/nfd-control-parameters.hpp
@@ -25,6 +25,7 @@
 #include "../encoding/nfd-constants.hpp"
 #include "../name.hpp"
 #include "../util/time.hpp"
+#include "../mgmt/control-parameters.hpp"
 
 namespace ndn {
 namespace nfd {
@@ -71,7 +72,7 @@
  * @sa http://redmine.named-data.net/projects/nfd/wiki/ControlCommand#ControlParameters
  * @detail This type is copyable because it's an abstraction of a TLV type.
  */
-class ControlParameters
+class ControlParameters : public ndn::mgmt::ControlParameters
 {
 public:
   class Error : public tlv::Error
@@ -93,11 +94,11 @@
   size_t
   wireEncode(EncodingImpl<TAG>& encoder) const;
 
-  const Block&
-  wireEncode() const;
+  virtual Block
+  wireEncode() const NDN_CXX_DECL_FINAL;
 
-  void
-  wireDecode(const Block& wire);
+  virtual void
+  wireDecode(const Block& wire) NDN_CXX_DECL_FINAL;
 
 public: // getters & setters
 
diff --git a/src/management/nfd-control-response.cpp b/src/management/nfd-control-response.cpp
deleted file mode 100644
index 7056162..0000000
--- a/src/management/nfd-control-response.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2015 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library 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 Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "nfd-control-response.hpp"
-#include "encoding/tlv-nfd.hpp"
-#include "encoding/block-helpers.hpp"
-
-namespace ndn {
-namespace nfd {
-
-//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(makeNonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
-
-  m_wire.push_back(makeBinaryBlock(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)
-    BOOST_THROW_EXCEPTION(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)
-    {
-      BOOST_THROW_EXCEPTION(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)
-    {
-      BOOST_THROW_EXCEPTION(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 nfd
-} // namespace ndn
diff --git a/src/management/nfd-control-response.hpp b/src/management/nfd-control-response.hpp
index 42ffd3d..83ba11d 100644
--- a/src/management/nfd-control-response.hpp
+++ b/src/management/nfd-control-response.hpp
@@ -22,112 +22,12 @@
 #ifndef NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
 #define NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
 
-#include "../encoding/block.hpp"
+#include "../mgmt/dispatcher.hpp"
 
 namespace ndn {
 namespace nfd {
 
-/**
- * @ingroup management
- * @brief Class defining abstraction of ControlResponse for NFD Control Protocol
- *
- * @see http://redmine.named-data.net/projects/nfd/wiki/ControlCommand#Response-format
- * @detail This type is copyable because it's an abstraction of a TLV type.
- */
-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;
-
-  void
-  setCode(uint32_t code);
-
-  const std::string&
-  getText() const;
-
-  void
-  setText(const std::string& text);
-
-  const Block&
-  getBody() const;
-
-  void
-  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 void
-ControlResponse::setCode(uint32_t code)
-{
-  m_code = code;
-  m_wire.reset();
-}
-
-inline const std::string&
-ControlResponse::getText() const
-{
-  return m_text;
-}
-
-inline void
-ControlResponse::setText(const std::string& text)
-{
-  m_text = text;
-  m_wire.reset();
-}
-
-inline const Block&
-ControlResponse::getBody() const
-{
-  return m_body;
-}
-
-inline void
-ControlResponse::setBody(const Block& body)
-{
-  m_body = body;
-  m_body.encode(); // will do nothing if already encoded
-  m_wire.reset();
-}
-
-std::ostream&
-operator<<(std::ostream& os, const ControlResponse& response);
+typedef ndn::mgmt::ControlResponse ControlResponse;
 
 } // namespace nfd
 } // namespace ndn
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
diff --git a/tests/unit-tests/mgmt/dispatcher.t.cpp b/tests/unit-tests/mgmt/dispatcher.t.cpp
new file mode 100644
index 0000000..050b927
--- /dev/null
+++ b/tests/unit-tests/mgmt/dispatcher.t.cpp
@@ -0,0 +1,386 @@
+/* -*- 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 "mgmt/dispatcher.hpp"
+#include "management/nfd-control-parameters.hpp"
+#include "util/dummy-client-face.hpp"
+
+#include "boost-test.hpp"
+#include "identity-management-fixture.hpp"
+#include "unit-tests/unit-test-time-fixture.hpp"
+#include "unit-tests/make-interest-data.hpp"
+
+namespace ndn {
+namespace mgmt {
+namespace tests {
+
+using namespace ndn::tests;
+
+BOOST_AUTO_TEST_SUITE(MgmtDispatcher)
+
+class DispatcherFixture : public UnitTestTimeFixture
+                        , public security::IdentityManagementFixture
+{
+public:
+  DispatcherFixture()
+    : face(util::makeDummyClientFace(io, {true, true}))
+    , dispatcher(*face, m_keyChain, security::SigningInfo())
+  {
+  }
+
+public:
+  shared_ptr<util::DummyClientFace> face;
+  mgmt::Dispatcher dispatcher;
+};
+
+class VoidParameters : public mgmt::ControlParameters
+{
+public:
+  explicit
+  VoidParameters(const Block& wire)
+  {
+    wireDecode(wire);
+  }
+
+  virtual Block
+  wireEncode() const NDN_CXX_DECL_FINAL
+  {
+    return Block(128);
+  }
+
+  virtual void
+  wireDecode(const Block& wire) NDN_CXX_DECL_FINAL
+  {
+    if (wire.type() != 128)
+      throw tlv::Error("Expecting TLV type 128");
+  }
+};
+
+static Authorization
+makeTestAuthorization()
+{
+  return [] (const Name& prefix,
+             const Interest& interest,
+             const ControlParameters* params,
+             AcceptContinuation accept,
+             RejectContinuation reject) {
+    if (interest.getName()[-1] == name::Component("valid")) {
+      accept("");
+    }
+    else {
+      if (interest.getName()[-1] == name::Component("silent")) {
+        reject(RejectReply::SILENT);
+      }
+      else {
+        reject(RejectReply::STATUS403);
+      }
+    }
+  };
+}
+
+BOOST_FIXTURE_TEST_CASE(BasicUsageSemantics, DispatcherFixture)
+{
+  BOOST_CHECK_NO_THROW(dispatcher
+                         .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
+                                                            bind([] { return true; }),
+                                                            bind([]{})));
+  BOOST_CHECK_NO_THROW(dispatcher
+                         .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
+                                                            bind([] { return true; }),
+                                                            bind([]{})));
+
+  BOOST_CHECK_THROW(dispatcher
+                      .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
+                                                         bind([] { return true; }),
+                                                         bind([]{})),
+                    std::out_of_range);
+
+  BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
+                                                   makeAcceptAllAuthorization(), bind([]{})));
+  BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
+                                                   makeAcceptAllAuthorization(), bind([]{})));
+  BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
+                                                makeAcceptAllAuthorization(), bind([]{})),
+                    std::out_of_range);
+
+  BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
+  BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
+  BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
+
+
+  BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
+  BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
+  BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
+
+  BOOST_CHECK_THROW(dispatcher
+                      .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
+                                                         bind([] { return true; }),
+                                                         bind([]{})),
+                    std::domain_error);
+
+  BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
+                                                makeAcceptAllAuthorization(), bind([]{})),
+                    std::domain_error);
+
+  BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRemoveTopPrefix, DispatcherFixture)
+{
+  std::map<std::string, size_t> nCallbackCalled;
+  dispatcher
+    .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
+                                       bind([] { return true; }),
+                                       bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
+
+  dispatcher
+    .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
+                                       bind([] { return true; }),
+                                       bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
+
+  face->receive(*util::makeInterest("/root/1/test/1/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
+
+  dispatcher.addTopPrefix("/root/1");
+  advanceClocks(time::milliseconds(1));
+
+  face->receive(*util::makeInterest("/root/1/test/1/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
+
+  face->receive(*util::makeInterest("/root/1/test/2/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
+
+  face->receive(*util::makeInterest("/root/2/test/1/%80%00"));
+  face->receive(*util::makeInterest("/root/2/test/2/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
+
+  dispatcher.addTopPrefix("/root/2");
+  advanceClocks(time::milliseconds(1));
+
+  face->receive(*util::makeInterest("/root/1/test/1/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 2);
+
+  face->receive(*util::makeInterest("/root/2/test/1/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
+
+  dispatcher.removeTopPrefix("/root/1");
+  advanceClocks(time::milliseconds(1));
+
+  face->receive(*util::makeInterest("/root/1/test/1/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
+
+  face->receive(*util::makeInterest("/root/2/test/1/%80%00"));
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
+}
+
+BOOST_FIXTURE_TEST_CASE(ControlCommand, DispatcherFixture)
+{
+  size_t nCallbackCalled = 0;
+  dispatcher
+    .addControlCommand<VoidParameters>("test",
+                                       makeTestAuthorization(),
+                                       bind([] { return true; }),
+                                       bind([&nCallbackCalled] { ++nCallbackCalled; }));
+
+  dispatcher.addTopPrefix("/root");
+  advanceClocks(time::milliseconds(1));
+  face->sentDatas.clear();
+
+  face->receive(*util::makeInterest("/root/test/%80%00")); // returns 403
+  face->receive(*util::makeInterest("/root/test/%80%00/invalid")); // returns 403
+  face->receive(*util::makeInterest("/root/test/%80%00/silent")); // silently ignored
+  face->receive(*util::makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
+  face->receive(*util::makeInterest("/root/test/.../valid"));  // silently ignored (wrong format)
+  advanceClocks(time::milliseconds(1), 20);
+  BOOST_CHECK_EQUAL(nCallbackCalled, 0);
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 2);
+
+  BOOST_CHECK(face->sentDatas[0].getContentType() == tlv::ContentType_Blob);
+  BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[0].getContent().blockFromValue()).getCode(), 403);
+  BOOST_CHECK(face->sentDatas[1].getContentType() == tlv::ContentType_Blob);
+  BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[1].getContent().blockFromValue()).getCode(), 403);
+
+  face->receive(*util::makeInterest("/root/test/%80%00/valid"));
+  advanceClocks(time::milliseconds(1), 10);
+  BOOST_CHECK_EQUAL(nCallbackCalled, 1);
+}
+
+BOOST_FIXTURE_TEST_CASE(StatusDataset, DispatcherFixture)
+{
+  static Block smallBlock("\x81\x01\0x01", 3);
+  static Block largeBlock = [] () -> Block {
+    EncodingBuffer encoder;
+    for (size_t i = 0; i < 2500; ++i) {
+      encoder.prependByte(1);
+    }
+    encoder.prependVarNumber(2500);
+    encoder.prependVarNumber(129);
+    return encoder.block();
+  }();
+
+  dispatcher.addStatusDataset("test/small",
+                              makeTestAuthorization(),
+                              [] (const Name& prefix, const Interest& interest,
+                                  StatusDatasetContext context) {
+                                context.append(smallBlock);
+                                context.append(smallBlock);
+                                context.append(smallBlock);
+                                context.end();
+                              });
+
+  dispatcher.addStatusDataset("test/large",
+                              makeTestAuthorization(),
+                              [] (const Name& prefix, const Interest& interest,
+                                  StatusDatasetContext context) {
+                                context.append(largeBlock);
+                                context.append(largeBlock);
+                                context.append(largeBlock);
+                                context.end();
+                              });
+
+  dispatcher.addStatusDataset("test/reject",
+                              makeTestAuthorization(),
+                              [] (const Name& prefix, const Interest& interest,
+                                  StatusDatasetContext context) {
+                                context.reject();
+                              });
+
+  dispatcher.addTopPrefix("/root");
+  advanceClocks(time::milliseconds(1));
+  face->sentDatas.clear();
+
+  face->receive(*util::makeInterest("/root/test/small/%80%00")); // returns 403
+  face->receive(*util::makeInterest("/root/test/small/%80%00/invalid")); // returns 403
+  face->receive(*util::makeInterest("/root/test/small/%80%00/silent")); // silently ignored
+  advanceClocks(time::milliseconds(1), 20);
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 2);
+
+  BOOST_CHECK(face->sentDatas[0].getContentType() == tlv::ContentType_Blob);
+  BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[0].getContent().blockFromValue()).getCode(), 403);
+  BOOST_CHECK(face->sentDatas[1].getContentType() == tlv::ContentType_Blob);
+  BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[1].getContent().blockFromValue()).getCode(), 403);
+
+  face->sentDatas.clear();
+  face->receive(*util::makeInterest("/root/test/small/valid"));
+  advanceClocks(time::milliseconds(1), 10);
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 1);
+
+  face->receive(*util::makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
+  face->receive(*util::makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
+  advanceClocks(time::milliseconds(1), 10);
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 1);
+
+  Block content = face->sentDatas[0].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+
+  BOOST_CHECK_EQUAL(content.elements().size(), 3);
+  BOOST_CHECK(content.elements()[0] == smallBlock);
+  BOOST_CHECK(content.elements()[1] == smallBlock);
+  BOOST_CHECK(content.elements()[2] == smallBlock);
+
+  face->sentDatas.clear();
+  face->receive(*util::makeInterest("/root/test/large/valid"));
+  advanceClocks(time::milliseconds(1), 10);
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 2);
+
+  const auto& datas = face->sentDatas;
+  content = [&datas] () -> Block {
+    EncodingBuffer encoder;
+    size_t valueLength = encoder.prependByteArray(datas[1].getContent().value(),
+                                                  datas[1].getContent().value_size());
+    valueLength += encoder.prependByteArray(datas[0].getContent().value(),
+                                            datas[0].getContent().value_size());
+    encoder.prependVarNumber(valueLength);
+    encoder.prependVarNumber(tlv::Content);
+    return encoder.block();
+  }();
+
+  BOOST_CHECK_NO_THROW(content.parse());
+
+  BOOST_CHECK_EQUAL(content.elements().size(), 3);
+  BOOST_CHECK(content.elements()[0] == largeBlock);
+  BOOST_CHECK(content.elements()[1] == largeBlock);
+  BOOST_CHECK(content.elements()[2] == largeBlock);
+
+  face->sentDatas.clear();
+  face->receive(*util::makeInterest("/root/test/reject/%80%00/valid")); // returns nack
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].getContentType() == tlv::ContentType_Nack);
+  BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[0].getContent().blockFromValue()).getCode(), 400);
+}
+
+BOOST_FIXTURE_TEST_CASE(NotificationStream, DispatcherFixture)
+{
+  static Block block("\x82\x01\x02", 3);
+
+  auto post = dispatcher.addNotificationStream("test");
+
+  post(block);
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 0);
+
+  dispatcher.addTopPrefix("/root");
+  advanceClocks(time::milliseconds(1));
+  face->sentDatas.clear();
+
+  post(block);
+  advanceClocks(time::milliseconds(1));
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 1);
+
+  post(block);
+  post(block);
+  post(block);
+  advanceClocks(time::milliseconds(1), 10);
+
+  BOOST_CHECK_EQUAL(face->sentDatas.size(), 4);
+  BOOST_CHECK_EQUAL(face->sentDatas[0].getName(), "/root/test/%FE%00");
+  BOOST_CHECK_EQUAL(face->sentDatas[1].getName(), "/root/test/%FE%01");
+  BOOST_CHECK_EQUAL(face->sentDatas[2].getName(), "/root/test/%FE%02");
+  BOOST_CHECK_EQUAL(face->sentDatas[3].getName(), "/root/test/%FE%03");
+
+  BOOST_CHECK(face->sentDatas[0].getContent().blockFromValue() == block);
+  BOOST_CHECK(face->sentDatas[1].getContent().blockFromValue() == block);
+  BOOST_CHECK(face->sentDatas[2].getContent().blockFromValue() == block);
+  BOOST_CHECK(face->sentDatas[3].getContent().blockFromValue() == block);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace mgmt
+} // namespace ndn
diff --git a/tests/unit-tests/mgmt/status-dataset-context.t.cpp b/tests/unit-tests/mgmt/status-dataset-context.t.cpp
new file mode 100644
index 0000000..40c5bf6
--- /dev/null
+++ b/tests/unit-tests/mgmt/status-dataset-context.t.cpp
@@ -0,0 +1,256 @@
+/* -*- 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 "mgmt/status-dataset-context.hpp"
+#include "boost-test.hpp"
+#include "unit-tests/make-interest-data.hpp"
+
+namespace ndn {
+namespace mgmt {
+namespace tests {
+
+class StatusDatasetContextFixture
+{
+public:
+  StatusDatasetContextFixture()
+    : interest(util::makeInterest("/test/context/interest"))
+    , contentBlock(makeStringBlock(tlv::Content, "/test/data/content"))
+    , context(*interest, bind(&StatusDatasetContextFixture::sendData, this, _1, _2, _3))
+  {
+  }
+
+  void
+  sendData(const Name& dataName, const Block& content, const MetaInfo& info)
+  {
+    sentData.push_back(Data(dataName).setContent(content).setMetaInfo(info));
+  }
+
+  Block
+  concatenate()
+  {
+    EncodingBuffer encoder;
+    size_t valueLength = 0;
+    for (auto data : sentData) {
+       valueLength += encoder.appendByteArray(data.getContent().value(),
+                                              data.getContent().value_size());
+    }
+    encoder.prependVarNumber(valueLength);
+    encoder.prependVarNumber(tlv::Content);
+    return encoder.block();
+  }
+
+public:
+  std::vector<Data> sentData;
+  shared_ptr<Interest> interest;
+  Block contentBlock;
+  mgmt::StatusDatasetContext context;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtStatusDatasetContext, StatusDatasetContextFixture)
+
+BOOST_AUTO_TEST_CASE(GetPrefix)
+{
+  Name dataName = context.getPrefix();
+  BOOST_CHECK(dataName[-1].isVersion());
+  BOOST_CHECK(dataName.getPrefix(-1) == interest->getName());
+}
+
+BOOST_AUTO_TEST_SUITE(SetPrefix)
+
+BOOST_AUTO_TEST_CASE(Valid)
+{
+  Name validPrefix = Name(interest->getName()).append("/valid");
+  BOOST_CHECK_NO_THROW(context.setPrefix(validPrefix));
+  BOOST_CHECK(context.getPrefix()[-1].isVersion());
+  BOOST_CHECK(context.getPrefix().getPrefix(-1) == validPrefix);
+}
+
+BOOST_AUTO_TEST_CASE(Invalid)
+{
+  Name invalidPrefix = Name(interest->getName()).getPrefix(-1).append("/invalid");
+  BOOST_CHECK_THROW(context.setPrefix(invalidPrefix), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE(ValidWithAppendCalled)
+{
+  Name validPrefix = Name(interest->getName()).append("/valid");
+  context.append(contentBlock);
+  BOOST_CHECK_THROW(context.setPrefix(validPrefix), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(ValidWithEndCalled)
+{
+  Name validPrefix = Name(interest->getName()).append("/valid");
+  context.end();
+  BOOST_CHECK_THROW(context.setPrefix(validPrefix), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(ValidWithRejectCalled)
+{
+  Name validPrefix = Name(interest->getName()).append("/valid");
+  context.reject();
+  BOOST_CHECK_THROW(context.setPrefix(validPrefix), std::domain_error);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // SetPrefix
+
+BOOST_AUTO_TEST_CASE(Expiry)
+{
+  // getExpiry & setExpiry
+  auto period = time::milliseconds(9527);
+  BOOST_CHECK_EQUAL(context.getExpiry(), time::milliseconds(1000));
+  BOOST_CHECK_EQUAL(context.setExpiry(period).getExpiry(), period);
+}
+
+BOOST_AUTO_TEST_CASE(Respond)
+{
+  BOOST_CHECK_NO_THROW(context.append(contentBlock));
+  BOOST_CHECK(sentData.empty()); // does not call end yet
+
+  BOOST_CHECK_NO_THROW(context.end());
+  BOOST_CHECK_EQUAL(sentData.size(), 1);
+  BOOST_CHECK_EQUAL(sentData[0].getName()[-1].toSegment(), 0);
+  BOOST_CHECK_EQUAL(sentData[0].getName().getPrefix(-1), context.getPrefix());
+  BOOST_CHECK_EQUAL(sentData[0].getFinalBlockId().toSegment(), 0);
+  BOOST_CHECK(sentData[0].getContent().blockFromValue() == contentBlock);
+}
+
+BOOST_AUTO_TEST_CASE(RespondLarge)
+{
+  static Block largeBlock = [] () -> Block {
+    EncodingBuffer encoder;
+    size_t maxBlockSize = MAX_NDN_PACKET_SIZE >> 1;
+    for (size_t i = 0; i < maxBlockSize; ++i) {
+      encoder.prependByte(1);
+    }
+    encoder.prependVarNumber(maxBlockSize);
+    encoder.prependVarNumber(tlv::Content);
+    return encoder.block();
+  }();
+
+  BOOST_CHECK_NO_THROW(context.append(largeBlock));
+  BOOST_CHECK_NO_THROW(context.end());
+  BOOST_CHECK_EQUAL(sentData.size(), 2);
+  BOOST_CHECK_EQUAL(sentData[0].getName()[-1].toSegment(), 0);
+  BOOST_CHECK_EQUAL(sentData[0].getName().getPrefix(-1), context.getPrefix());
+  BOOST_CHECK_EQUAL(sentData[1].getName()[-1].toSegment(), 1);
+  BOOST_CHECK_EQUAL(sentData[1].getName().getPrefix(-1), context.getPrefix());
+  BOOST_CHECK_EQUAL(sentData[1].getFinalBlockId().toSegment(), 1);
+
+  auto contentLargeBlock = concatenate();
+  BOOST_CHECK_NO_THROW(contentLargeBlock.parse());
+  BOOST_CHECK_EQUAL(contentLargeBlock.elements().size(), 1);
+  BOOST_CHECK(contentLargeBlock.elements()[0] == largeBlock);
+}
+
+BOOST_AUTO_TEST_CASE(ResponseMultipleSmall)
+{
+  size_t nBlocks = 100;
+  for (size_t i = 0 ; i < nBlocks ; i ++) {
+    BOOST_CHECK_NO_THROW(context.append(contentBlock));
+  }
+  BOOST_CHECK_NO_THROW(context.end());
+  BOOST_CHECK_EQUAL(sentData.size(), 1);
+  BOOST_CHECK_EQUAL(sentData[0].getName()[-1].toSegment(), 0);
+  BOOST_CHECK_EQUAL(sentData[0].getName().getPrefix(-1), context.getPrefix());
+  BOOST_CHECK_EQUAL(sentData[0].getFinalBlockId().toSegment(), 0);
+
+  auto contentMultiBlocks = concatenate();
+  BOOST_CHECK_NO_THROW(contentMultiBlocks.parse());
+  BOOST_CHECK_EQUAL(contentMultiBlocks.elements().size(), nBlocks);
+  for (auto&& element : contentMultiBlocks.elements()) {
+    BOOST_CHECK(element == contentBlock);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(Reject)
+{
+  BOOST_CHECK_NO_THROW(context.reject());
+  BOOST_CHECK_EQUAL(sentData.size(), 1);
+  BOOST_CHECK(sentData[0].getContentType() == tlv::ContentType_Nack);
+  BOOST_CHECK_EQUAL(ControlResponse(sentData[0].getContent().blockFromValue()).getCode(), 400);
+}
+
+BOOST_AUTO_TEST_SUITE(AbnormalState)
+
+BOOST_AUTO_TEST_CASE(AppendReject)
+{
+  mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.append(Block("\x82\x01\x02", 3)));
+  BOOST_CHECK_THROW(context.reject(), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(AppendEndReject)
+{
+  mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.append(Block("\x82\x01\x02", 3)));
+  BOOST_CHECK_NO_THROW(context.end());
+  BOOST_CHECK_THROW(context.reject(), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(EndAppend)
+{
+  mgmt::StatusDatasetContext context (Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.end());
+  // end, append -> error
+  BOOST_CHECK_THROW(context.append(Block("\x82\x01\x02", 3)), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(EndEnd)
+{
+  mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.end());
+  BOOST_CHECK_THROW(context.end(), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(EndReject)
+{
+  mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.end());
+  BOOST_CHECK_THROW(context.reject(), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(RejectAppend)
+{
+  mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.reject());
+  BOOST_CHECK_THROW(context.append(Block("\x82\x01\x02", 3)), std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE(RejectEnd)
+{
+  mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
+  BOOST_CHECK_NO_THROW(context.reject());
+  BOOST_CHECK_THROW(context.end(), std::domain_error);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // AbnormalState
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace mgmt
+} // namespace ndn
