diff --git a/tools/nfdc/face-id-fetcher.cpp b/tools/nfdc/face-id-fetcher.cpp
new file mode 100644
index 0000000..da09c11
--- /dev/null
+++ b/tools/nfdc/face-id-fetcher.cpp
@@ -0,0 +1,203 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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 "face-id-fetcher.hpp"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/regex.hpp>
+
+#include <ndn-cxx/management/nfd-face-query-filter.hpp>
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/util/segment-fetcher.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+FaceIdFetcher::FaceIdFetcher(ndn::Face& face,
+                             ndn::nfd::Controller& controller,
+                             bool allowCreate,
+                             const SuccessCallback& onSucceed,
+                             const FailureCallback& onFail)
+  : m_face(face)
+  , m_controller(controller)
+  , m_allowCreate(allowCreate)
+  , m_onSucceed(onSucceed)
+  , m_onFail(onFail)
+{
+}
+
+void
+FaceIdFetcher::start(ndn::Face& face,
+                     ndn::nfd::Controller& controller,
+                     const std::string& input,
+                     bool allowCreate,
+                     const SuccessCallback& onSucceed,
+                     const FailureCallback& onFail)
+{
+  // 1. Try parse input as FaceId, if input is FaceId, succeed with parsed FaceId
+  // 2. Try parse input as FaceUri, if input is not FaceUri, fail
+  // 3. Canonize faceUri
+  // 4. If canonization fails, fail
+  // 5. Query for face
+  // 6. If query succeeds and finds a face, succeed with found FaceId
+  // 7. Create face
+  // 8. If face creation succeeds, succeed with created FaceId
+  // 9. Fail
+
+  boost::regex e("^[a-z0-9]+\\:.*");
+  if (!boost::regex_match(input, e)) {
+    try {
+      uint32_t faceId = boost::lexical_cast<uint32_t>(input);
+      onSucceed(faceId);
+      return;
+    }
+    catch (const boost::bad_lexical_cast&) {
+      onFail("No valid faceId or faceUri is provided");
+      return;
+    }
+  }
+  else {
+    FaceUri faceUri;
+    if (!faceUri.parse(input)) {
+      onFail("FaceUri parse failed");
+      return;
+    }
+
+    auto fetcher = new FaceIdFetcher(std::ref(face), std::ref(controller),
+                                     allowCreate, onSucceed, onFail);
+    fetcher->startGetFaceId(faceUri);
+  }
+}
+
+void
+FaceIdFetcher::startGetFaceId(const FaceUri& faceUri)
+{
+  faceUri.canonize(bind(&FaceIdFetcher::onCanonizeSuccess, this, _1),
+                   bind(&FaceIdFetcher::onCanonizeFailure, this, _1),
+                   m_face.getIoService(), time::seconds(4));
+}
+
+void
+FaceIdFetcher::onCanonizeSuccess(const FaceUri& canonicalUri)
+{
+  ndn::Name queryName("/localhost/nfd/faces/query");
+  ndn::nfd::FaceQueryFilter queryFilter;
+  queryFilter.setRemoteUri(canonicalUri.toString());
+  queryName.append(queryFilter.wireEncode());
+
+  ndn::Interest interestPacket(queryName);
+  interestPacket.setMustBeFresh(true);
+  interestPacket.setInterestLifetime(time::milliseconds(4000));
+  auto interest = std::make_shared<ndn::Interest>(interestPacket);
+
+  ndn::util::SegmentFetcher::fetch(
+    m_face, *interest, m_validator,
+    bind(&FaceIdFetcher::onQuerySuccess, this, _1, canonicalUri),
+    bind(&FaceIdFetcher::onQueryFailure, this, _1, canonicalUri));
+}
+
+void
+FaceIdFetcher::onCanonizeFailure(const std::string& reason)
+{
+  fail("Canonize faceUri failed : " + reason);
+}
+
+void
+FaceIdFetcher::onQuerySuccess(const ndn::ConstBufferPtr& data,
+                              const FaceUri& canonicalUri)
+{
+  size_t offset = 0;
+  bool isOk = false;
+  ndn::Block block;
+  std::tie(isOk, block) = ndn::Block::fromBuffer(data, offset);
+
+  if (!isOk) {
+    if (m_allowCreate) {
+      startFaceCreate(canonicalUri);
+    }
+    else {
+      fail("Fail to find faceId");
+    }
+  }
+  else {
+    try {
+      ndn::nfd::FaceStatus status(block);
+      succeed(status.getFaceId());
+    }
+    catch (const ndn::tlv::Error& e) {
+      std::string errorMessage(e.what());
+      fail("ERROR: " + errorMessage);
+    }
+  }
+}
+
+void
+FaceIdFetcher::onQueryFailure(uint32_t errorCode,
+                              const FaceUri& canonicalUri)
+{
+  std::stringstream ss;
+  ss << "Cannot fetch data (code " << errorCode << ")";
+  fail(ss.str());
+}
+
+void
+FaceIdFetcher::onFaceCreateError(uint32_t code,
+                                 const std::string& error,
+                                 const std::string& message)
+{
+  std::stringstream ss;
+  ss << message << " : " << error << " (code " << code << ")";
+  fail(ss.str());
+}
+
+void
+FaceIdFetcher::startFaceCreate(const FaceUri& canonicalUri)
+{
+  ndn::nfd::ControlParameters parameters;
+  parameters.setUri(canonicalUri.toString());
+
+  m_controller.start<ndn::nfd::FaceCreateCommand>(parameters,
+    [this] (const ndn::nfd::ControlParameters& result) { succeed(result.getFaceId()); },
+    bind(&FaceIdFetcher::onFaceCreateError, this, _1, _2, "Face creation failed"));
+}
+
+void
+FaceIdFetcher::succeed(uint32_t faceId)
+{
+  m_onSucceed(faceId);
+  delete this;
+}
+
+void
+FaceIdFetcher::fail(const std::string& reason)
+{
+  m_onFail(reason);
+  delete this;
+}
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfdc/face-id-fetcher.hpp b/tools/nfdc/face-id-fetcher.hpp
new file mode 100644
index 0000000..50e0083
--- /dev/null
+++ b/tools/nfdc/face-id-fetcher.hpp
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFDC_FACE_ID_FETCHER_HPP
+#define NFD_TOOLS_NFDC_FACE_ID_FETCHER_HPP
+
+#include "core/common.hpp"
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/management/nfd-controller.hpp>
+#include <ndn-cxx/util/face-uri.hpp>
+#include <ndn-cxx/security/validator-null.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+using ndn::util::FaceUri;
+
+class FaceIdFetcher
+{
+public:
+  typedef std::function<void(uint32_t)> SuccessCallback;
+  typedef std::function<void(const std::string&)> FailureCallback;
+
+  /** \brief obtain FaceId from input
+   *  \param face Reference to the Face that should be used to fetch data
+   *  \param controller Reference to the controller that should be used to sign the Interest
+   *  \param input User input, either FaceId or FaceUri
+   *  \param allowCreate Whether creating face is allowed
+   *  \param onSucceed Callback to be fired when faceId is obtained
+   *  \param onFail Callback to be fired when an error occurs
+   */
+  static void
+  start(ndn::Face& face,
+        ndn::nfd::Controller& controller,
+        const std::string& input,
+        bool allowCreate,
+        const SuccessCallback& onSucceed,
+        const FailureCallback& onFail);
+
+private:
+  FaceIdFetcher(ndn::Face& face,
+                ndn::nfd::Controller& controller,
+                bool allowCreate,
+                const SuccessCallback& onSucceed,
+                const FailureCallback& onFail);
+
+  void
+  onQuerySuccess(const ndn::ConstBufferPtr& data,
+                 const FaceUri& canonicalUri);
+
+  void
+  onQueryFailure(uint32_t errorCode,
+                 const FaceUri& canonicalUri);
+
+  void
+  onCanonizeSuccess(const FaceUri& canonicalUri);
+
+  void
+  onCanonizeFailure(const std::string& reason);
+
+  void
+  startGetFaceId(const FaceUri& faceUri);
+
+  void
+  startFaceCreate(const FaceUri& canonicalUri);
+
+  void
+  onFaceCreateError(uint32_t code,
+                    const std::string& error,
+                    const std::string& message);
+
+  void
+  succeed(uint32_t faceId);
+
+  void
+  fail(const std::string& reason);
+
+private:
+  ndn::Face& m_face;
+  ndn::nfd::Controller& m_controller;
+  bool m_allowCreate;
+  SuccessCallback m_onSucceed;
+  FailureCallback m_onFail;
+  ndn::ValidatorNull m_validator;
+};
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFDC_FACE_ID_FETCHER_HPP
diff --git a/tools/nfdc/legacy-nfdc.cpp b/tools/nfdc/legacy-nfdc.cpp
new file mode 100644
index 0000000..83a3db8
--- /dev/null
+++ b/tools/nfdc/legacy-nfdc.cpp
@@ -0,0 +1,290 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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 "legacy-nfdc.hpp"
+#include "face-id-fetcher.hpp"
+
+#include <boost/regex.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+using ndn::nfd::ControlParameters;
+
+const time::milliseconds LegacyNfdc::DEFAULT_EXPIRATION_PERIOD = time::milliseconds::max();
+const uint64_t LegacyNfdc::DEFAULT_COST = 0;
+
+LegacyNfdc::LegacyNfdc(ndn::Face& face)
+  : m_flags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
+  , m_cost(DEFAULT_COST)
+  , m_origin(ndn::nfd::ROUTE_ORIGIN_STATIC)
+  , m_expires(DEFAULT_EXPIRATION_PERIOD)
+  , m_facePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+  , m_face(face)
+  , m_controller(face, m_keyChain)
+{
+}
+
+bool
+LegacyNfdc::dispatch(const std::string& command)
+{
+  if (command == "add-nexthop") {
+    if (m_nOptions != 2)
+      return false;
+    fibAddNextHop();
+  }
+  else if (command == "remove-nexthop") {
+    if (m_nOptions != 2)
+      return false;
+    fibRemoveNextHop();
+  }
+  else if (command == "register") {
+    if (m_nOptions != 2)
+      return false;
+    ribRegisterPrefix();
+  }
+  else if (command == "unregister") {
+    if (m_nOptions != 2)
+      return false;
+    ribUnregisterPrefix();
+  }
+  else if (command == "create") {
+    if (m_nOptions != 1)
+      return false;
+    faceCreate();
+  }
+  else if (command == "destroy") {
+    if (m_nOptions != 1)
+      return false;
+    faceDestroy();
+  }
+  else if (command == "set-strategy") {
+    if (m_nOptions != 2)
+      return false;
+    strategyChoiceSet();
+  }
+  else if (command == "unset-strategy") {
+    if (m_nOptions != 1)
+      return false;
+    strategyChoiceUnset();
+  }
+  else
+    return false;
+
+  return true;
+}
+
+void
+LegacyNfdc::fibAddNextHop()
+{
+  m_name = m_commandLineArguments[0];
+  const std::string& faceName = m_commandLineArguments[1];
+
+  FaceIdFetcher::start(m_face, m_controller, faceName, true,
+    [this] (const uint32_t faceId) {
+      ControlParameters parameters;
+      parameters
+        .setName(m_name)
+        .setCost(m_cost)
+        .setFaceId(faceId);
+
+      m_controller.start<ndn::nfd::FibAddNextHopCommand>(parameters,
+        bind(&LegacyNfdc::onSuccess, this, _1, "Nexthop insertion succeeded"),
+        bind(&LegacyNfdc::onError, this, _1, _2, "Nexthop insertion failed"));
+    },
+    bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::fibRemoveNextHop()
+{
+  m_name = m_commandLineArguments[0];
+  const std::string& faceName = m_commandLineArguments[1];
+
+  FaceIdFetcher::start(m_face, m_controller, faceName, false,
+    [this] (const uint32_t faceId) {
+      ControlParameters parameters;
+      parameters
+        .setName(m_name)
+        .setFaceId(faceId);
+
+      m_controller.start<ndn::nfd::FibRemoveNextHopCommand>(parameters,
+        bind(&LegacyNfdc::onSuccess, this, _1, "Nexthop removal succeeded"),
+        bind(&LegacyNfdc::onError, this, _1, _2, "Nexthop removal failed"));
+    },
+    bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::ribRegisterPrefix()
+{
+  m_name = m_commandLineArguments[0];
+  const std::string& faceName = m_commandLineArguments[1];
+
+  FaceIdFetcher::start(m_face, m_controller, faceName, true,
+    [this] (const uint32_t faceId) {
+      ControlParameters parameters;
+      parameters
+        .setName(m_name)
+        .setCost(m_cost)
+        .setFlags(m_flags)
+        .setOrigin(m_origin)
+        .setFaceId(faceId);
+
+      if (m_expires != DEFAULT_EXPIRATION_PERIOD)
+        parameters.setExpirationPeriod(m_expires);
+
+      m_controller.start<ndn::nfd::RibRegisterCommand>(parameters,
+        bind(&LegacyNfdc::onSuccess, this, _1, "Successful in name registration"),
+        bind(&LegacyNfdc::onError, this, _1, _2, "Failed in name registration"));
+    },
+    bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::ribUnregisterPrefix()
+{
+  m_name = m_commandLineArguments[0];
+  const std::string& faceName = m_commandLineArguments[1];
+
+  FaceIdFetcher::start(m_face, m_controller, faceName, false,
+    [this] (const uint32_t faceId) {
+      ControlParameters parameters;
+      parameters
+        .setName(m_name)
+        .setFaceId(faceId)
+        .setOrigin(m_origin);
+
+      m_controller.start<ndn::nfd::RibUnregisterCommand>(parameters,
+        bind(&LegacyNfdc::onSuccess, this, _1, "Successful in unregistering name"),
+        bind(&LegacyNfdc::onError, this, _1, _2, "Failed in unregistering name"));
+    },
+    bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::onCanonizeFailure(const std::string& reason)
+{
+  BOOST_THROW_EXCEPTION(Error(reason));
+}
+
+void
+LegacyNfdc::onObtainFaceIdFailure(const std::string& message)
+{
+  BOOST_THROW_EXCEPTION(Error(message));
+}
+
+void
+LegacyNfdc::faceCreate()
+{
+  boost::regex e("^[a-z0-9]+\\:.*");
+  if (!boost::regex_match(m_commandLineArguments[0], e))
+    BOOST_THROW_EXCEPTION(Error("invalid uri format"));
+
+  FaceUri faceUri;
+  faceUri.parse(m_commandLineArguments[0]);
+
+  faceUri.canonize(bind(&LegacyNfdc::startFaceCreate, this, _1),
+                   bind(&LegacyNfdc::onCanonizeFailure, this, _1),
+                   m_face.getIoService(), time::seconds(4));
+}
+
+void
+LegacyNfdc::startFaceCreate(const FaceUri& canonicalUri)
+{
+  ControlParameters parameters;
+  parameters.setUri(canonicalUri.toString());
+  parameters.setFacePersistency(m_facePersistency);
+
+  m_controller.start<ndn::nfd::FaceCreateCommand>(parameters,
+    bind(&LegacyNfdc::onSuccess, this, _1, "Face creation succeeded"),
+    bind(&LegacyNfdc::onError, this, _1, _2, "Face creation failed"));
+}
+
+void
+LegacyNfdc::faceDestroy()
+{
+  ControlParameters parameters;
+  const std::string& faceName = m_commandLineArguments[0];
+
+  FaceIdFetcher::start(m_face, m_controller, faceName, false,
+    [this] (const uint32_t faceId) {
+      ControlParameters faceParameters;
+      faceParameters.setFaceId(faceId);
+
+      m_controller.start<ndn::nfd::FaceDestroyCommand>(faceParameters,
+        bind(&LegacyNfdc::onSuccess, this, _1, "Face destroy succeeded"),
+        bind(&LegacyNfdc::onError, this, _1, _2, "Face destroy failed"));
+    },
+    bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
+}
+
+void
+LegacyNfdc::strategyChoiceSet()
+{
+  const std::string& name = m_commandLineArguments[0];
+  const std::string& strategy = m_commandLineArguments[1];
+
+  ControlParameters parameters;
+  parameters
+    .setName(name)
+    .setStrategy(strategy);
+
+  m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(parameters,
+    bind(&LegacyNfdc::onSuccess, this, _1, "Successfully set strategy choice"),
+    bind(&LegacyNfdc::onError, this, _1, _2, "Failed to set strategy choice"));
+}
+
+void
+LegacyNfdc::strategyChoiceUnset()
+{
+  const std::string& name = m_commandLineArguments[0];
+
+  ControlParameters parameters;
+  parameters.setName(name);
+
+  m_controller.start<ndn::nfd::StrategyChoiceUnsetCommand>(parameters,
+    bind(&LegacyNfdc::onSuccess, this, _1, "Successfully unset strategy choice"),
+    bind(&LegacyNfdc::onError, this, _1, _2, "Failed to unset strategy choice"));
+}
+
+void
+LegacyNfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
+{
+  std::cout << message << ": " << commandSuccessResult << std::endl;
+}
+
+void
+LegacyNfdc::onError(uint32_t code, const std::string& error, const std::string& message)
+{
+  std::ostringstream os;
+  os << message << ": " << error << " (code: " << code << ")";
+  BOOST_THROW_EXCEPTION(Error(os.str()));
+}
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfdc/legacy-nfdc.hpp b/tools/nfdc/legacy-nfdc.hpp
new file mode 100644
index 0000000..01ed7b9
--- /dev/null
+++ b/tools/nfdc/legacy-nfdc.hpp
@@ -0,0 +1,186 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
+#define NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
+
+#include "core/common.hpp"
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/management/nfd-controller.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+class LegacyNfdc : noncopyable
+{
+public:
+  static const time::milliseconds DEFAULT_EXPIRATION_PERIOD;
+  static const uint64_t DEFAULT_COST;
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  explicit
+  LegacyNfdc(ndn::Face& face);
+
+  bool
+  dispatch(const std::string& cmd);
+
+  /**
+   * \brief Adds a nexthop to a FIB entry
+   *
+   * If the FIB entry does not exist, it is inserted automatically
+   *
+   * cmd format:
+   *  [-c cost]  name faceId|faceUri
+   *
+   */
+  void
+  fibAddNextHop();
+
+  /**
+   * \brief Removes a nexthop from an existing FIB entry
+   *
+   * If the last nexthop record in a FIB entry is removed, the FIB entry is also deleted
+   *
+   * cmd format:
+   *  name faceId
+   *
+   */
+  void
+  fibRemoveNextHop();
+
+  /**
+   * \brief Registers name to the given faceId or faceUri
+   *
+   * cmd format:
+   *  [-I] [-C] [-c cost] name faceId|faceUri
+   */
+  void
+  ribRegisterPrefix();
+
+  /**
+   * \brief Unregisters name from the given faceId/faceUri
+   *
+   * cmd format:
+   *  name faceId/faceUri
+   */
+  void
+  ribUnregisterPrefix();
+
+  /**
+   * \brief Creates new face
+   *
+   * This command allows creation of UDP unicast and TCP faces only
+   *
+   * cmd format:
+   *  uri
+   *
+   */
+  void
+  faceCreate();
+
+  /**
+   * \brief Destroys face
+   *
+   * cmd format:
+   *  faceId|faceUri
+   *
+   */
+  void
+  faceDestroy();
+
+  /**
+   * \brief Sets the strategy for a namespace
+   *
+   * cmd format:
+   *  name strategy
+   *
+   */
+  void
+  strategyChoiceSet();
+
+  /**
+   * \brief Unset the strategy for a namespace
+   *
+   * cmd format:
+   *  name strategy
+   *
+   */
+  void
+  strategyChoiceUnset();
+
+private:
+
+  void
+  onSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
+            const std::string& message);
+
+  void
+  onError(uint32_t code, const std::string& error, const std::string& message);
+
+  void
+  onCanonizeFailure(const std::string& reason);
+
+  void
+  startFaceCreate(const ndn::util::FaceUri& canonicalUri);
+
+  void
+  onObtainFaceIdFailure(const std::string& message);
+
+public:
+  const char* m_programName;
+
+  // command parameters without leading 'cmd' component
+  const char* const* m_commandLineArguments;
+  int m_nOptions;
+  uint64_t m_flags;
+  uint64_t m_cost;
+  uint64_t m_faceId;
+  uint64_t m_origin;
+  time::milliseconds m_expires;
+  std::string m_name;
+  ndn::nfd::FacePersistency m_facePersistency;
+
+private:
+  ndn::KeyChain m_keyChain;
+  ndn::Face& m_face;
+  ndn::nfd::Controller m_controller;
+};
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
diff --git a/tools/nfdc/main.cpp b/tools/nfdc/main.cpp
new file mode 100644
index 0000000..7d9f763
--- /dev/null
+++ b/tools/nfdc/main.cpp
@@ -0,0 +1,182 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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 "legacy-nfdc.hpp"
+#include "core/version.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+static void
+usage(const char* programName)
+{
+  std::cout << "Usage:\n" << programName  << " [-h] [-V] COMMAND [<Command Options>]\n"
+    "       -h print usage and exit\n"
+    "       -V print version and exit\n"
+    "\n"
+    "   COMMAND can be one of the following:\n"
+    "       register [-I] [-C] [-c cost] [-e expiration time] [-o origin] name <faceId | faceUri>\n"
+    "           register name to the given faceId or faceUri\n"
+    "           -I: unset CHILD_INHERIT flag\n"
+    "           -C: set CAPTURE flag\n"
+    "           -c: specify cost (default 0)\n"
+    "           -e: specify expiration time in ms\n"
+    "               (by default the entry remains in FIB for the lifetime of the associated face)\n"
+    "           -o: specify origin\n"
+    "               0 for Local producer applications, 128 for NLSR, 255(default) for static routes\n"
+    "       unregister [-o origin] name <faceId | faceUri>\n"
+    "           unregister name from the given faceId\n"
+    "       create [-P] <faceUri> \n"
+    "           Create a face in one of the following formats:\n"
+    "           UDP unicast:    udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
+    "           TCP:            tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
+    "           -P: create permanent (instead of persistent) face\n"
+    "       destroy <faceId | faceUri> \n"
+    "           Destroy a face\n"
+    "       set-strategy <name> <strategy> \n"
+    "           Set the strategy for a namespace \n"
+    "       unset-strategy <name> \n"
+    "           Unset the strategy for a namespace \n"
+    "       add-nexthop [-c <cost>] <name> <faceId | faceUri>\n"
+    "           Add a nexthop to a FIB entry\n"
+    "           -c: specify cost (default 0)\n"
+    "       remove-nexthop <name> <faceId | faceUri> \n"
+    "           Remove a nexthop from a FIB entry\n"
+    << std::endl;
+}
+
+static int
+main(int argc, char** argv)
+{
+  ndn::Face face;
+  LegacyNfdc p(face);
+
+  p.m_programName = argv[0];
+
+  if (argc < 2) {
+    usage(p.m_programName);
+    return 0;
+  }
+
+  if (!strcmp(argv[1], "-h")) {
+    usage(p.m_programName);
+    return 0;
+  }
+
+  if (!strcmp(argv[1], "-V")) {
+    std::cout << NFD_VERSION_BUILD_STRING << std::endl;
+    return 0;
+  }
+
+  ::optind = 2; //start reading options from 2nd argument i.e. Command
+  int opt;
+  while ((opt = ::getopt(argc, argv, "ICc:e:o:P")) != -1) {
+    switch (opt) {
+      case 'I':
+        p.m_flags = p.m_flags & ~(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
+        break;
+
+      case 'C':
+        p.m_flags = p.m_flags | ndn::nfd::ROUTE_FLAG_CAPTURE;
+        break;
+
+      case 'c':
+        try {
+          p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
+        }
+        catch (const boost::bad_lexical_cast&) {
+          std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
+          return 1;
+        }
+        break;
+
+      case 'e':
+        uint64_t expires;
+        try {
+          expires = boost::lexical_cast<uint64_t>(::optarg);
+        }
+        catch (const boost::bad_lexical_cast&) {
+          std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
+          return 1;
+        }
+        p.m_expires = ndn::time::milliseconds(expires);
+        break;
+
+      case 'o':
+        try {
+          p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
+        }
+        catch (const boost::bad_lexical_cast&) {
+          std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
+          return 1;
+        }
+        break;
+
+      case 'P':
+        p.m_facePersistency = ndn::nfd::FACE_PERSISTENCY_PERMANENT;
+        break;
+
+      default:
+        usage(p.m_programName);
+        return 1;
+    }
+  }
+
+  if (argc == ::optind) {
+    usage(p.m_programName);
+    return 1;
+  }
+
+  try {
+    p.m_commandLineArguments = argv + ::optind;
+    p.m_nOptions = argc - ::optind;
+
+    //argv[1] points to the command, so pass it to the dispatch
+    bool isOk = p.dispatch(argv[1]);
+    if (!isOk) {
+      usage(p.m_programName);
+      return 1;
+    }
+    face.processEvents();
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 2;
+  }
+  return 0;
+}
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+int
+main(int argc, char** argv)
+{
+  return nfd::tools::nfdc::main(argc, argv);
+}
