diff --git a/tools/nfdc.cpp b/tools/nfdc.cpp
new file mode 100644
index 0000000..1ad54af
--- /dev/null
+++ b/tools/nfdc.cpp
@@ -0,0 +1,269 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+#include "nfdc.hpp"
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/regex_find_format.hpp>
+#include <boost/regex.hpp>
+
+void
+usage(const char* programName)
+{
+  std::cout << "Usage:\n" << programName  << " [-h] COMMAND\n"
+  "       -h print usage and exit\n"
+  "\n"
+  "   COMMAND can be one of following:\n"
+  "       insert <name> \n"
+  "           Insert a FIB entry \n"
+  "       delete <name> \n"
+  "           Delete a FIB entry\n"
+  "       add-nexthop <name> <faceId> [<cost>]\n"
+  "           Add a nexthop to an existing FIB entry\n"
+  "       remove-nexthop <name> <faceId> \n"
+  "           Remove a nexthop from a FIB entry\n"
+  "       set-strategy <name> <stratgy>\n"
+  "           Set a forwarding strategy for a namespace\n"
+  "       create <uri> \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"
+  "       destroy <faceId> \n"
+  "           Destroy a face\n"
+  << std::endl;
+}
+
+namespace nfdc {
+  
+Controller::Controller(ndn::Face& face)
+  : ndn::nfd::Controller(face)
+{
+}
+  
+Controller::~Controller()
+{
+}
+bool
+Controller::dispatch(const std::string& command, const char* commandOptions[], int nOptions)
+{
+  if (command == "insert") {
+    if (nOptions != 1)
+      return false;
+    fibInsert(commandOptions);
+  }
+  else if (command == "delete") {
+    if (nOptions != 1)
+      return false;
+    fibDelete(commandOptions);
+  }
+  else if (command == "add-nexthop") {
+    if (nOptions == 2)
+      fibAddNextHop(commandOptions, false);
+    else if (nOptions == 3)
+      fibAddNextHop(commandOptions, true);
+    else
+      return false;
+  }
+  else if (command == "remove-nexthop") {
+    if (nOptions != 2)
+      return false;
+    fibRemoveNextHop(commandOptions);
+  }
+  else if (command == "set-strategy") {
+    if (nOptions != 2)
+      return false;
+    fibSetStrategy(commandOptions);
+  }
+  else if (command == "create") {
+    if (nOptions != 1)
+      return false;
+    faceCreate(commandOptions);
+  }
+  else if (command == "destroy") {
+    if (nOptions != 1)
+      return false;
+    faceDestroy(commandOptions);
+  }
+  else
+    usage(m_programName);
+
+  return true;
+}
+  
+void
+Controller::fibInsert(const char* commandOptions[])
+{
+  const std::string& name = commandOptions[0];
+
+  ndn::nfd::FibManagementOptions fibOptions;
+  fibOptions.setName(name);
+  startFibCommand("insert",
+                  fibOptions,
+                  bind(&Controller::onFibSuccess, this, _1, "Fib insertion succeeded"),
+                  bind(&Controller::onError, this, _1, "Fib insertion failed"));
+}
+    
+void
+Controller::fibDelete(const char* commandOptions[])
+{
+  const std::string& name = commandOptions[0];
+  ndn::nfd::FibManagementOptions fibOptions;
+  fibOptions.setName(name);
+  startFibCommand("delete",
+                  fibOptions,
+                  bind(&Controller::onFibSuccess, this, _1, "Fib deletion succeeded"),
+                  bind(&Controller::onError, this, _1, "Fib deletion failed" ));
+}
+
+
+void
+Controller::fibAddNextHop(const char* commandOptions[], bool hasCost)
+{
+  ndn::nfd::FibManagementOptions fibOptions;
+  
+  const std::string& name = commandOptions[0];
+  const int faceId = boost::lexical_cast<int>(commandOptions[1]);
+
+  fibOptions.setName(name);
+  fibOptions.setFaceId(faceId);
+
+  if (hasCost)
+  {
+    const int cost = boost::lexical_cast<int>(commandOptions[2]);
+    fibOptions.setCost(cost);
+  }
+  startFibCommand("add-nexthop",
+                  fibOptions,
+                  bind(&Controller::onFibSuccess, this, _1, "Nexthop insertion succeeded"),
+                  bind(&Controller::onError, this, _1, "Nexthop insertion failed"));
+}
+
+void
+Controller::fibRemoveNextHop(const char* commandOptions[])
+{
+  const std::string& name = commandOptions[0];
+  const int faceId = boost::lexical_cast<int>(commandOptions[1]);
+  ndn::nfd::FibManagementOptions fibOptions;
+
+  fibOptions.setName(name);
+  fibOptions.setFaceId(faceId);
+  startFibCommand("remove-nexthop",
+                  fibOptions,
+                  bind(&Controller::onFibSuccess, this, _1, "Nexthop Removal succeeded"),
+                  bind(&Controller::onError, this, _1, "Nexthop Removal failed"));
+}
+
+void
+Controller::fibSetStrategy(const char* commandOptions[])
+{
+    
+  // std::string name      = commandOptions[0];
+  // std::string strategy  = commandOptions[1];
+  // startFibCommand("set-strategy",
+  //                  ndn::nfd::FibManagementOptions()
+  //                  .setName(name)
+  //                  .setStrategy(strategy),
+  //                  bind(&Controller::onFibSuccess,this, _1),
+  //                  bind(&Controller::onError,this, _1));
+}
+ 
+namespace {
+bool
+isValidUri(const std::string& input)
+{
+  // an extended regex to support the validation of uri structure
+  // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
+  boost::regex e("^[a-z0-9]+\\:.*");
+  return boost::regex_match(input, e);
+}
+} // anonymous namespace
+
+void
+Controller::faceCreate(const char* commandOptions[])
+{
+  ndn::nfd::FaceManagementOptions faceOptions;
+  const std::string& uri = commandOptions[0];
+  faceOptions.setUri(uri);
+  
+  if (isValidUri(uri))
+  {
+    startFaceCommand("create",
+                     faceOptions,
+                     bind(&Controller::onFaceSuccess, this, _1, "Face creation succeeded"),
+                     bind(&Controller::onError, this, _1, "Face creation failed"));
+  }
+  else
+    throw Error("invalid uri format");
+}
+ 
+void
+Controller::faceDestroy(const char* commandOptions[])
+{
+  ndn::nfd::FaceManagementOptions faceOptions;
+  const int faceId = boost::lexical_cast<int>(commandOptions[0]);
+  faceOptions.setFaceId(faceId);
+                        
+  startFaceCommand("destroy",
+                   faceOptions,
+                   bind(&Controller::onFaceSuccess, this, _1, "Face destroy succeeded"),
+                   bind(&Controller::onError, this, _1, "Face destroy failed"));
+}
+
+void
+Controller::onFibSuccess(const ndn::nfd::FibManagementOptions& resp, const std::string& message)
+{
+  std::cout << resp << std::endl;
+}
+  
+void
+Controller::onFaceSuccess(const ndn::nfd::FaceManagementOptions& resp, const std::string& message)
+{
+  std::cout << resp << std::endl;
+}
+  
+void
+Controller::onError(const std::string& error, const std::string& message)
+{
+  throw Error(message + ": " + error);
+}
+}// namespace nfdc
+
+int
+main(int argc, char** argv)
+{
+  ndn::Face face;
+  nfdc::Controller p(face);
+  
+  p.m_programName = argv[0];
+  int opt;
+  while ((opt = getopt(argc, argv, "h")) != -1) {
+    switch (opt) {
+      case 'h':
+        usage(p.m_programName);
+        return 0;
+        
+      default:
+        usage(p.m_programName);
+        return 1;
+    }
+  }
+  try {
+    bool hasSucceeded = p.dispatch(argv[optind],
+                                   const_cast<const char**>(argv + optind + 1),
+                                   argc - optind - 1);
+    if (hasSucceeded == false) {
+      usage(p.m_programName);
+      return 1;
+    }
+    
+    face.processEvents();
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 2;
+  }
+  return 0;
+}
+
