diff --git a/tools/nfdc.cpp b/tools/nfdc.cpp
index a603cd6..08ad859 100644
--- a/tools/nfdc.cpp
+++ b/tools/nfdc.cpp
@@ -34,6 +34,8 @@
     "       -h print usage and exit\n"
     "\n"
     "   COMMAND can be one of following:\n"
+    "       add <name> <faceUri> [<cost>]\n"
+    "           Create a face, and add a nexthop for this face to a FIB entry\n"
     "       add-nexthop <name> <faceId> [<cost>]\n"
     "           Add a nexthop to a FIB entry\n"
     "       remove-nexthop <name> <faceId> \n"
@@ -63,40 +65,48 @@
 }
 
 bool
-Nfdc::dispatch(const std::string& command, const char* commandOptions[], int nOptions)
+Nfdc::dispatch(const std::string& command)
 {
-  if (command == "add-nexthop") {
-    if (nOptions == 2)
-      fibAddNextHop(commandOptions, false);
-    else if (nOptions == 3)
-      fibAddNextHop(commandOptions, true);
+  if (command == "add") {
+    if (m_nOptions == 2)
+      addName();
+    else if (m_nOptions == 3)
+      addName();
+    else
+      return false;
+  }
+  else if (command == "add-nexthop") {
+    if (m_nOptions == 2)
+      fibAddNextHop(false);
+    else if (m_nOptions == 3)
+      fibAddNextHop(true);
     else
       return false;
   }
   else if (command == "remove-nexthop") {
-    if (nOptions != 2)
+    if (m_nOptions != 2)
       return false;
-    fibRemoveNextHop(commandOptions);
+    fibRemoveNextHop();
   }
   else if (command == "create") {
-    if (nOptions != 1)
+    if (m_nOptions != 1)
       return false;
-    faceCreate(commandOptions);
+    faceCreate();
   }
   else if (command == "destroy") {
-    if (nOptions != 1)
+    if (m_nOptions != 1)
       return false;
-    faceDestroy(commandOptions);
+    faceDestroy();
   }
   else if (command == "set-strategy") {
-    if (nOptions != 2)
+    if (m_nOptions != 2)
       return false;
-    strategyChoiceSet(commandOptions);
+    strategyChoiceSet();
   }
   else if (command == "unset-strategy") {
-    if (nOptions != 1)
+    if (m_nOptions != 1)
       return false;
-    strategyChoiceUnset(commandOptions);
+    strategyChoiceUnset();
   }
   else
     usage(m_programName);
@@ -104,45 +114,6 @@
   return true;
 }
 
-void
-Nfdc::fibAddNextHop(const char* commandOptions[], bool hasCost)
-{
-  const std::string& name = commandOptions[0];
-  const int faceId = boost::lexical_cast<int>(commandOptions[1]);
-
-  ControlParameters parameters;
-  parameters
-    .setName(name)
-    .setFaceId(faceId);
-
-  if (hasCost)
-  {
-    const uint64_t cost = boost::lexical_cast<uint64_t>(commandOptions[2]);
-    parameters.setCost(cost);
-  }
-
-  m_controller.start<FibAddNextHopCommand>(
-    parameters,
-    bind(&Nfdc::onSuccess, this, _1, "Nexthop insertion succeeded"),
-    bind(&Nfdc::onError, this, _1, _2, "Nexthop insertion failed"));
-}
-
-void
-Nfdc::fibRemoveNextHop(const char* commandOptions[])
-{
-  const std::string& name = commandOptions[0];
-  const int faceId = boost::lexical_cast<int>(commandOptions[1]);
-
-  ControlParameters parameters;
-  parameters
-    .setName(name)
-    .setFaceId(faceId);
-
-  m_controller.start<FibRemoveNextHopCommand>(
-    parameters,
-    bind(&Nfdc::onSuccess, this, _1, "Nexthop removal succeeded"),
-    bind(&Nfdc::onError, this, _1, _2, "Nexthop removal failed"));
-}
 
 namespace {
 
@@ -158,15 +129,78 @@
 } // anonymous namespace
 
 void
-Nfdc::faceCreate(const char* commandOptions[])
+Nfdc::addName()
 {
-  const std::string& uri = commandOptions[0];
-  if (!isValidUri(uri))
+  if (!isValidUri(m_commandLineArguments[1]))
     throw Error("invalid uri format");
 
   ControlParameters parameters;
   parameters
-    .setUri(uri);
+    .setUri(m_commandLineArguments[1]);
+
+  m_controller.start<FaceCreateCommand>(
+    parameters,
+    bind(&Nfdc::onAddSuccess, this, _1, "nfdc add:Face creation succeeded"),
+    bind(&Nfdc::onError, this, _1, _2, "nfdc add: Face creation failed"));
+
+}
+
+void
+Nfdc::fibAddNextHop(bool hasCost)
+{
+  const std::string& name = m_commandLineArguments[0];
+  const int faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
+
+  fibAddNextHop(name, faceId, hasCost);
+
+}
+
+void
+Nfdc::fibAddNextHop(const std::string& name, const uint64_t faceId, bool hasCost)
+{
+  ControlParameters parameters;
+  parameters
+    .setName(name)
+    .setFaceId(faceId);
+
+  if (hasCost)
+  {
+    const uint64_t cost = boost::lexical_cast<uint64_t>(m_commandLineArguments[2]);
+    parameters.setCost(cost);
+  }
+
+  m_controller.start<FibAddNextHopCommand>(
+    parameters,
+    bind(&Nfdc::onSuccess, this, _1, "Nexthop insertion succeeded"),
+    bind(&Nfdc::onError, this, _1, _2, "Nexthop insertion failed"));
+}
+
+void
+Nfdc::fibRemoveNextHop()
+{
+  const std::string& name = m_commandLineArguments[0];
+  const int faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
+
+  ControlParameters parameters;
+  parameters
+    .setName(name)
+    .setFaceId(faceId);
+
+  m_controller.start<FibRemoveNextHopCommand>(
+    parameters,
+    bind(&Nfdc::onSuccess, this, _1, "Nexthop removal succeeded"),
+    bind(&Nfdc::onError, this, _1, _2, "Nexthop removal failed"));
+}
+
+void
+Nfdc::faceCreate()
+{
+  if (!isValidUri(m_commandLineArguments[0]))
+    throw Error("invalid uri format");
+
+  ControlParameters parameters;
+  parameters
+    .setUri(m_commandLineArguments[0]);
 
   m_controller.start<FaceCreateCommand>(
     parameters,
@@ -175,9 +209,9 @@
 }
 
 void
-Nfdc::faceDestroy(const char* commandOptions[])
+Nfdc::faceDestroy()
 {
-  const int faceId = boost::lexical_cast<int>(commandOptions[0]);
+  const int faceId = boost::lexical_cast<int>(m_commandLineArguments[0]);
 
   ControlParameters parameters;
   parameters
@@ -190,10 +224,10 @@
 }
 
 void
-Nfdc::strategyChoiceSet(const char* commandOptions[])
+Nfdc::strategyChoiceSet()
 {
-  const std::string& name = commandOptions[0];
-  const std::string& strategy = commandOptions[1];
+  const std::string& name = m_commandLineArguments[0];
+  const std::string& strategy = m_commandLineArguments[1];
 
   ControlParameters parameters;
   parameters
@@ -207,9 +241,9 @@
 }
 
 void
-Nfdc::strategyChoiceUnset(const char* commandOptions[])
+Nfdc::strategyChoiceUnset()
 {
-  const std::string& name = commandOptions[0];
+  const std::string& name = m_commandLineArguments[0];
 
   ControlParameters parameters;
   parameters
@@ -228,6 +262,18 @@
 }
 
 void
+Nfdc::onAddSuccess(const ControlParameters& parameters, const std::string& message)
+{
+  uint64_t faceId = parameters.getFaceId();
+
+  if (m_nOptions == 2)
+    fibAddNextHop(m_commandLineArguments[0], faceId, false);
+  else if (m_nOptions == 3)
+    fibAddNextHop(m_commandLineArguments[0], faceId, true);
+  else
+    throw Error("invalid number of arguments");
+}
+void
 Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
 {
   std::ostringstream os;
@@ -244,6 +290,7 @@
   nfdc::Nfdc p(face);
 
   p.m_programName = argv[0];
+
   int opt;
   while ((opt = getopt(argc, argv, "h")) != -1) {
     switch (opt) {
@@ -263,9 +310,9 @@
   }
 
   try {
-    bool isOk = p.dispatch(argv[optind],
-                           const_cast<const char**>(argv + optind + 1),
-                           argc - optind - 1);
+    p.m_commandLineArguments = const_cast<const char**>(argv + optind + 1);
+    p.m_nOptions = argc - optind - 1;
+    bool isOk = p.dispatch(argv[optind]);
     if (!isOk) {
       usage(p.m_programName);
       return 1;
diff --git a/tools/nfdc.hpp b/tools/nfdc.hpp
index ab74e10..b54d12f 100644
--- a/tools/nfdc.hpp
+++ b/tools/nfdc.hpp
@@ -28,13 +28,12 @@
 #include <ndn-cpp-dev/face.hpp>
 #include <ndn-cpp-dev/management/controller.hpp>
 #include <ndn-cpp-dev/management/nfd-controller.hpp>
-#include <vector>
 
 namespace nfdc {
 
 using namespace ndn::nfd;
 
-class Nfdc
+class Nfdc : boost::noncopyable
 {
 public:
   class Error : public std::runtime_error
@@ -53,22 +52,31 @@
   ~Nfdc();
 
   bool
-  dispatch(const std::string& cmd,
-           const char* cmdOptions[],
-           int nOptions);
+  dispatch(const std::string& cmd);
 
   /**
+   * \brief Adds a name to a FIB entry after creating the attaced face.
+   *
+   * Create a new face for the given faceUri and use it when adding the given name to the fib
+   *
+   *
+   * cmd format:
+   *   add name faceUri [cost]
+   *
+   */
+  void
+  addName();
+  /**
    * \brief Adds a nexthop to a FIB entry.
    *
    * If the FIB entry does not exist, it is inserted automatically
    *
    * cmd format:
-   *   name
+   *   name faceId [cost]
    *
-   * \param cmdOptions Add next hop command parameters without leading 'add-nexthop' component
    */
   void
-  fibAddNextHop(const char* cmdOptions[], bool hasCost);
+  fibAddNextHop(bool hasCost);
 
   /**
    * \brief Removes a nexthop from an existing FIB entry
@@ -78,11 +86,9 @@
    * cmd format:
    *   name faceId
    *
-   * \param cmdOptions Remove next hop command parameters without leading
-   *                   'remove-nexthop' component
    */
   void
-  fibRemoveNextHop(const char* cmdOptions[]);
+  fibRemoveNextHop();
 
   /**
    * \brief create new face
@@ -92,10 +98,9 @@
    * cmd format:
    *   uri
    *
-   * \param cmdOptions Create face command parameters without leading 'create' component
    */
   void
-  faceCreate(const char* cmdOptions[]);
+  faceCreate();
 
   /**
    * \brief destroy a face
@@ -103,10 +108,9 @@
    * cmd format:
    *   faceId
    *
-   * \param cmdOptions Destroy face command parameters without leading 'destroy' component
    */
   void
-  faceDestroy(const char* cmdOptions[]);
+  faceDestroy();
 
   /**
    * \brief Set the strategy for a namespace
@@ -115,11 +119,9 @@
    * cmd format:
    *   name strategy
    *
-   * \param cmdOptions Set strategy choice command parameters without leading
-   *                   'set-strategy' component
    */
   void
-  strategyChoiceSet(const char* cmdOptions[]);
+  strategyChoiceSet();
 
   /**
    * \brief Unset the strategy for a namespace
@@ -128,23 +130,33 @@
    * cmd format:
    *   name strategy
    *
-   * \param cmdOptions Unset strategy choice command parameters without leading
-   *                   'unset-strategy' component
    */
   void
-  strategyChoiceUnset(const char* cmdOptions[]);
+  strategyChoiceUnset();
 
 private:
+
   void
   onSuccess(const ControlParameters& parameters,
             const std::string& message);
 
   void
+  onAddSuccess(const ControlParameters& parameters,
+               const std::string& message);
+
+  void
   onError(uint32_t code, const std::string& error, const std::string& message);
 
+  void
+  fibAddNextHop(const std::string& name, const uint64_t faceId, bool hasCost);
+
 public:
   const char* m_programName;
 
+  // command parameters without leading 'cmd' component
+  const char** m_commandLineArguments;
+  int m_nOptions;
+
 private:
   Controller m_controller;
 };
