diff --git a/src/management/nfd-control-command.hpp b/src/management/nfd-control-command.hpp
index 69407c0..168daec 100644
--- a/src/management/nfd-control-command.hpp
+++ b/src/management/nfd-control-command.hpp
@@ -16,7 +16,7 @@
 /** \brief base class of NFD ControlCommand
  *  \sa http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
  */
-class ControlCommand
+class ControlCommand : noncopyable
 {
 public:
   /** \brief represents an error in ControlParameters
diff --git a/src/management/nfd-control-parameters.hpp b/src/management/nfd-control-parameters.hpp
index 836369b..c92a23f 100644
--- a/src/management/nfd-control-parameters.hpp
+++ b/src/management/nfd-control-parameters.hpp
@@ -14,8 +14,14 @@
 namespace nfd {
 
 class ControlParameters;
+/** \deprecated use ControlParameters instead
+ */
 typedef ControlParameters FaceManagementOptions;
+/** \deprecated use ControlParameters instead
+ */
 typedef ControlParameters FibManagementOptions;
+/** \deprecated use ControlParameters instead
+ */
 typedef ControlParameters StrategyChoiceOptions;
 
 enum ControlParameterField {
@@ -42,7 +48,11 @@
   LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID = 2
 };
 
-class ControlParameters {
+/** \brief represents parameters in a ControlCommand request or response
+ *  \sa http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
+ */
+class ControlParameters
+{
 public:
   class Error : public Tlv::Error
   {
diff --git a/src/management/nfd-controller.cpp b/src/management/nfd-controller.cpp
index 19e98f8..5a7e397 100644
--- a/src/management/nfd-controller.cpp
+++ b/src/management/nfd-controller.cpp
@@ -4,13 +4,7 @@
  * See COPYING for copyright and distribution information.
  */
 
-#include "common.hpp"
-#include "../face.hpp"
-
 #include "nfd-controller.hpp"
-#include "nfd-fib-management-options.hpp"
-#include "nfd-face-management-options.hpp"
-#include "nfd-strategy-choice-options.hpp"
 #include "nfd-control-response.hpp"
 
 namespace ndn {
@@ -22,11 +16,70 @@
 }
 
 void
+Controller::processCommandResponse(const Data& data,
+                                   const shared_ptr<ControlCommand>& command,
+                                   const CommandSucceedCallback& onSuccess,
+                                   const CommandFailCallback& onFailure)
+{
+  /// \todo verify Data signature
+
+  const uint32_t serverErrorCode = 500;
+
+  ControlResponse response;
+  try {
+    response.wireDecode(data.getContent().blockFromValue());
+  }
+  catch (ndn::Tlv::Error& e) {
+    if (static_cast<bool>(onFailure))
+      onFailure(serverErrorCode, e.what());
+    return;
+  }
+
+  uint32_t code = response.getCode();
+  const uint32_t errorCodeLowerBound = 400;
+  if (code >= errorCodeLowerBound) {
+    if (static_cast<bool>(onFailure))
+      onFailure(code, response.getText());
+    return;
+  }
+
+  ControlParameters parameters;
+  try {
+    parameters.wireDecode(response.getBody());
+  }
+  catch (ndn::Tlv::Error& e) {
+    if (static_cast<bool>(onFailure))
+      onFailure(serverErrorCode, e.what());
+    return;
+  }
+
+  try {
+    command->validateResponse(parameters);
+  }
+  catch (ControlCommand::ArgumentError& e) {
+    if (static_cast<bool>(onFailure))
+      onFailure(serverErrorCode, e.what());
+    return;
+  }
+
+  onSuccess(parameters);
+}
+
+
+void
 Controller::selfRegisterPrefix(const Name& prefixToRegister,
                                const SuccessCallback& onSuccess,
                                const FailCallback&    onFail)
 {
-  fibAddNextHop(prefixToRegister, 0, 0, bind(onSuccess), onFail);
+  const uint32_t selfFaceId = 0;
+
+  ControlParameters parameters;
+  parameters.setName(prefixToRegister)
+            .setFaceId(selfFaceId);
+
+  this->start<FibAddNextHopCommand>(parameters,
+                                    bind(onSuccess),
+                                    bind(onFail, _2));
 }
 
 void
@@ -34,7 +87,15 @@
                                  const SuccessCallback& onSuccess,
                                  const FailCallback&    onFail)
 {
-  fibRemoveNextHop(prefixToDeRegister, 0, bind(onSuccess), onFail);
+  const uint32_t selfFaceId = 0;
+
+  ControlParameters parameters;
+  parameters.setName(prefixToDeRegister)
+            .setFaceId(selfFaceId);
+
+  this->start<FibRemoveNextHopCommand>(parameters,
+                                       bind(onSuccess),
+                                       bind(onFail, _2));
 }
 
 void
@@ -42,12 +103,16 @@
                           const FibCommandSucceedCallback& onSuccess,
                           const FailCallback& onFail)
 {
-  startFibCommand("add-nexthop",
-                  FibManagementOptions()
-                    .setName(prefix)
-                    .setFaceId(faceId)
-                    .setCost(cost),
-                  onSuccess, onFail);
+  BOOST_ASSERT(cost >= 0);
+
+  ControlParameters parameters;
+  parameters.setName(prefix)
+            .setFaceId(faceId)
+            .setCost(static_cast<uint64_t>(cost));
+
+  this->start<FibAddNextHopCommand>(parameters,
+                                    onSuccess,
+                                    bind(onFail, _2));
 }
 
 void
@@ -55,11 +120,13 @@
                              const FibCommandSucceedCallback& onSuccess,
                              const FailCallback& onFail)
 {
-  startFibCommand("remove-nexthop",
-                  FibManagementOptions()
-                    .setName(prefix)
-                    .setFaceId(faceId),
-                  onSuccess, onFail);
+  ControlParameters parameters;
+  parameters.setName(prefix)
+            .setFaceId(faceId);
+
+  this->start<FibRemoveNextHopCommand>(parameters,
+                                       onSuccess,
+                                       bind(onFail, _2));
 }
 
 void
@@ -68,41 +135,19 @@
                             const FibCommandSucceedCallback& onSuccess,
                             const FailCallback& onFail)
 {
-  Name fibCommandInterestName("/localhost/nfd/fib");
-  fibCommandInterestName
-    .append(command)
-    .append(options.wireEncode());
-
-  Interest fibCommandInterest(fibCommandInterestName);
-  m_commandInterestGenerator.generate(fibCommandInterest);
-
-  m_face.expressInterest(fibCommandInterest,
-                         bind(&Controller::processFibCommandResponse, this, _2,
-                              onSuccess, onFail),
-                         bind(onFail, "Command Interest timed out"));
-}
-
-void
-Controller::processFibCommandResponse(Data& data,
-                                      const FibCommandSucceedCallback& onSuccess,
-                                      const FailCallback& onFail)
-{
-  /// \todo Add validation of incoming Data
-
-  try
-    {
-      ControlResponse response(data.getContent().blockFromValue());
-      if (response.getCode() != 200)
-        return onFail(response.getText());
-
-      FibManagementOptions options(response.getBody());
-      return onSuccess(options);
-    }
-  catch(ndn::Tlv::Error& e)
-    {
-      if (static_cast<bool>(onFail))
-        return onFail(e.what());
-    }
+  if (command == "add-nexthop") {
+    this->start<FibAddNextHopCommand>(options,
+                                      onSuccess,
+                                      bind(onFail, _2));
+  }
+  else if (command == "remove-nexthop") {
+    this->start<FibRemoveNextHopCommand>(options,
+                                         onSuccess,
+                                         bind(onFail, _2));
+  }
+  else {
+    onFail("unknown command");
+  }
 }
 
 void
@@ -111,40 +156,19 @@
                              const FaceCommandSucceedCallback& onSuccess,
                              const FailCallback& onFail)
 {
-  Name faceCommandInterestName("/localhost/nfd/faces");
-  faceCommandInterestName
-    .append(command)
-    .append(options.wireEncode());
-
-  Interest faceCommandInterest(faceCommandInterestName);
-  m_commandInterestGenerator.generate(faceCommandInterest);
-
-  m_face.expressInterest(faceCommandInterest,
-                         bind(&Controller::processFaceCommandResponse, this, _2,
-                              onSuccess, onFail),
-                         bind(onFail, "Command Interest timed out"));
-}
-  
-void
-Controller::processFaceCommandResponse(Data& data,
-                                       const FaceCommandSucceedCallback& onSuccess,
-                                       const FailCallback& onFail)
-{
-  /// \todo Add validation of incoming Data
-  
-  try
-  {
-    ControlResponse response(data.getContent().blockFromValue());
-    if (response.getCode() != 200)
-      return onFail(response.getText());
-    
-    FaceManagementOptions options(response.getBody());
-    return onSuccess(options);
+  if (command == "create") {
+    this->start<FaceCreateCommand>(options,
+                                   onSuccess,
+                                   bind(onFail, _2));
   }
-  catch(ndn::Tlv::Error& e)
-  {
-    if (static_cast<bool>(onFail))
-      return onFail(e.what());
+  else if (command == "destroy") {
+    this->start<FaceDestroyCommand>(options,
+                                    onSuccess,
+                                    bind(onFail, _2));
+  }
+  // enable-local-control and disable-local-control are not in legacy API.
+  else {
+    onFail("unknown command");
   }
 }
 
@@ -154,43 +178,21 @@
                                        const StrategyChoiceCommandSucceedCallback& onSuccess,
                                        const FailCallback& onFail)
 {
-  Name strategyChoiceCommandInterestName("/localhost/nfd/strategy-choice");
-  strategyChoiceCommandInterestName
-    .append(command)
-    .append(options.wireEncode());
-  
-  Interest strategyChoiceCommandInterest(strategyChoiceCommandInterestName);
-  m_commandInterestGenerator.generate(strategyChoiceCommandInterest);
-  
-  m_face.expressInterest(strategyChoiceCommandInterest,
-                         bind(&Controller::processStrategyChoiceCommandResponse, this, _2,
-                              onSuccess, onFail),
-                         bind(onFail, "Command Interest timed out"));
-}
-void
-Controller::processStrategyChoiceCommandResponse(
-    Data& data,
-    const StrategyChoiceCommandSucceedCallback& onSuccess,
-    const FailCallback& onFail)
-{
-  /// \todo Add validation of incoming Data
-  
-  try
-  {
-    ControlResponse response(data.getContent().blockFromValue());
-    if (response.getCode() != 200)
-      return onFail(response.getText());
-    
-    StrategyChoiceOptions options(response.getBody());
-    return onSuccess(options);
+  if (command == "set") {
+    this->start<StrategyChoiceSetCommand>(options,
+                                          onSuccess,
+                                          bind(onFail, _2));
   }
-  catch (ndn::Tlv::Error& error)
-  {
-    if (static_cast<bool>(onFail))
-      return onFail(error.what());
+  else if (command == "unset") {
+    this->start<StrategyChoiceUnsetCommand>(options,
+                                            onSuccess,
+                                            bind(onFail, _2));
+  }
+  else {
+    onFail("unknown command");
   }
 }
 
-  
+
 } // namespace nfd
 } // namespace ndn
diff --git a/src/management/nfd-controller.hpp b/src/management/nfd-controller.hpp
index f3ab116..536994c 100644
--- a/src/management/nfd-controller.hpp
+++ b/src/management/nfd-controller.hpp
@@ -8,25 +8,37 @@
 #define NDN_MANAGEMENT_NFD_CONTROLLER_HPP
 
 #include "controller.hpp"
-#include "nfd-control-parameters.hpp"
-#include "../util/command-interest-generator.hpp"
+#include "nfd-control-command.hpp"
+#include "../face.hpp"
 
 namespace ndn {
-
 namespace nfd {
 
+/** \brief NFD Management protocol - ControlCommand client
+ */
 class Controller : public ndn::Controller
 {
 public:
-  typedef function<void(const FibManagementOptions&)> FibCommandSucceedCallback;
-  typedef function<void(const FaceManagementOptions&)> FaceCommandSucceedCallback;
-  typedef function<void(const StrategyChoiceOptions&)> StrategyChoiceCommandSucceedCallback;
-
-  /**
-   * @brief Construct ndnd::Control object
+  /** \brief a callback on command success
    */
+  typedef function<void(const ControlParameters&)> CommandSucceedCallback;
+
+  /** \brief a callback on command failure
+   */
+  typedef function<void(uint32_t/*code*/,const std::string&/*reason*/)> CommandFailCallback;
+
+  explicit
   Controller(Face& face);
 
+  /** \brief start command execution
+   */
+  template<typename Command>
+  void
+  start(const ControlParameters& parameters,
+               const CommandSucceedCallback& onSuccess,
+               const CommandFailCallback&    onFailure);
+
+public: // selfreg
   virtual void
   selfRegisterPrefix(const Name& prefixToRegister,
                      const SuccessCallback& onSuccess,
@@ -37,8 +49,20 @@
                        const SuccessCallback& onSuccess,
                        const FailCallback&    onFail);
 
+public:
+  /** \deprecated use CommandSucceedCallback instead
+   */
+  typedef function<void(const FibManagementOptions&)> FibCommandSucceedCallback;
+  /** \deprecated use CommandSucceedCallback instead
+   */
+  typedef function<void(const FaceManagementOptions&)> FaceCommandSucceedCallback;
+  /** \deprecated use CommandSucceedCallback instead
+   */
+  typedef function<void(const StrategyChoiceOptions&)> StrategyChoiceCommandSucceedCallback;
+
   /**
    * \brief Adds a nexthop to an existing or new FIB entry
+   * \deprecated use startCommand instead
    *
    * If FIB entry for the specified prefix does not exist, it will be automatically created.
    *
@@ -58,6 +82,7 @@
 
   /**
    * \brief Remove a nexthop from FIB entry
+   * \deprecated use startCommand instead
    *
    * If after removal of the nexthop FIB entry has zero next hops, this FIB entry will
    * be automatically deleted.
@@ -75,18 +100,24 @@
                    const FailCallback& onFail);
 
 protected:
+  /** \deprecated use startCommand instead
+   */
   void
   startFibCommand(const std::string& command,
                   const FibManagementOptions& options,
                   const FibCommandSucceedCallback& onSuccess,
                   const FailCallback& onFailure);
 
+  /** \deprecated use startCommand instead
+   */
   void
   startFaceCommand(const std::string& command,
                    const FaceManagementOptions& options,
                    const FaceCommandSucceedCallback& onSuccess,
                    const FailCallback& onFailure);
 
+  /** \deprecated use startCommand instead
+   */
   void
   startStrategyChoiceCommand(const std::string& command,
                              const StrategyChoiceOptions& options,
@@ -95,25 +126,35 @@
 
 private:
   void
-  processFibCommandResponse(Data& data,
-                            const FibCommandSucceedCallback& onSuccess,
-                            const FailCallback& onFail);
-
-  void
-  processFaceCommandResponse(Data& data,
-                             const FaceCommandSucceedCallback& onSuccess,
-                             const FailCallback& onFail);
-
-  void
-  processStrategyChoiceCommandResponse(Data& data,
-                                       const StrategyChoiceCommandSucceedCallback& onSuccess,
-                                       const FailCallback& onFail);
+  processCommandResponse(const Data& data,
+                         const shared_ptr<ControlCommand>& command,
+                         const CommandSucceedCallback& onSuccess,
+                         const CommandFailCallback& onFailure);
 
 protected:
   Face& m_face;
   CommandInterestGenerator m_commandInterestGenerator;
 };
 
+
+template<typename Command>
+void
+Controller::start(const ControlParameters& parameters,
+                  const CommandSucceedCallback& onSuccess,
+                  const CommandFailCallback&    onFailure)
+{
+  shared_ptr<ControlCommand> command = make_shared<Command>();
+
+  Interest commandInterest = command->makeCommandInterest(parameters, m_commandInterestGenerator);
+
+  // http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668.aspx
+  const uint32_t timeoutCode = 10060;
+  m_face.expressInterest(commandInterest,
+                         bind(&Controller::processCommandResponse, this, _2,
+                              command, onSuccess, onFailure),
+                         bind(onFailure, timeoutCode, "Command Interest timed out"));
+}
+
 } // namespace nfd
 } // namespace ndn
 
diff --git a/tests/management/nfd-controller.cpp b/tests/management/nfd-controller.cpp
new file mode 100644
index 0000000..9176690
--- /dev/null
+++ b/tests/management/nfd-controller.cpp
@@ -0,0 +1,174 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "management/nfd-controller.hpp"
+// Having a separate compilation unit is necessary to ensure .hpp can compile on its own.
+#include "management/nfd-control-response.hpp"
+
+#include "../transport/dummy-face.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace ndn {
+namespace nfd {
+
+BOOST_AUTO_TEST_SUITE(NfdController)
+
+class CommandFixture
+{
+protected:
+  CommandFixture()
+    : face(makeDummyFace())
+    , controller(*face)
+    , commandSucceedCallback(bind(&CommandFixture::onCommandSucceed, this, _1))
+    , commandFailCallback(bind(&CommandFixture::onCommandFail, this, _1, _2))
+  {
+  }
+
+private:
+  void
+  onCommandSucceed(const ControlParameters& parameters)
+  {
+    commandSucceedHistory.push_back(boost::make_tuple(parameters));
+  }
+
+  void
+  onCommandFail(uint32_t code, const std::string& reason)
+  {
+    commandFailHistory.push_back(boost::make_tuple(code, reason));
+  }
+
+protected:
+  shared_ptr<DummyFace> face;
+  Controller controller;
+  KeyChain keyChain;
+
+  Controller::CommandSucceedCallback commandSucceedCallback;
+  typedef boost::tuple<ControlParameters> CommandSucceedArgs;
+  std::vector<CommandSucceedArgs> commandSucceedHistory;
+
+  Controller::CommandFailCallback commandFailCallback;
+  typedef boost::tuple<uint32_t,std::string> CommandFailArgs;
+  std::vector<CommandFailArgs> commandFailHistory;
+};
+
+BOOST_FIXTURE_TEST_CASE(CommandSuccess, CommandFixture)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://example.com");
+
+  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
+                         parameters,
+                         commandSucceedCallback,
+                         commandFailCallback));
+  face->processEvents(time::milliseconds(1));
+
+  BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
+  const Interest& commandInterest = face->m_sentInterests[0];
+
+  FaceCreateCommand command;
+  BOOST_CHECK(command.getPrefix().isPrefixOf(commandInterest.getName()));
+  // 9 components: ndn:/localhost/nfd/face/create/<parameters>/<command Interest signature x4>
+  BOOST_REQUIRE_EQUAL(commandInterest.getName().size(), 9);
+  ControlParameters request;
+  // 4th component: <parameters>
+  BOOST_REQUIRE_NO_THROW(request.wireDecode(commandInterest.getName().at(4).blockFromValue()));
+  BOOST_CHECK_NO_THROW(command.validateRequest(request));
+  BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
+
+  ControlParameters responseBody;
+  responseBody.setUri("tcp4://192.0.2.1:6363")
+              .setFaceId(22);
+  ControlResponse responsePayload(201, "created");
+  responsePayload.setBody(responseBody.wireEncode());
+
+  Data responseData(commandInterest.getName());
+  responseData.setContent(responsePayload.wireEncode());
+  keyChain.sign(responseData);
+  face->receive(responseData);
+  face->processEvents(time::milliseconds(1));
+
+  BOOST_CHECK_EQUAL(commandFailHistory.size(), 0);
+  BOOST_REQUIRE_EQUAL(commandSucceedHistory.size(), 1);
+  const ControlParameters& response = commandSucceedHistory[0].get<0>();
+  BOOST_CHECK_EQUAL(response.getUri(), responseBody.getUri());
+  BOOST_CHECK_EQUAL(response.getFaceId(), responseBody.getFaceId());
+}
+
+BOOST_FIXTURE_TEST_CASE(CommandInvalidRequest, CommandFixture)
+{
+  ControlParameters parameters;
+  parameters.setName("ndn:/should-not-have-this-field");
+  // Uri is missing
+
+  BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
+                      parameters,
+                      commandSucceedCallback,
+                      commandFailCallback),
+                    ControlCommand::ArgumentError);
+}
+
+BOOST_FIXTURE_TEST_CASE(CommandErrorCode, CommandFixture)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://example.com");
+
+  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
+                         parameters,
+                         commandSucceedCallback,
+                         commandFailCallback));
+  face->processEvents(time::milliseconds(1));
+
+  BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
+  const Interest& commandInterest = face->m_sentInterests[0];
+
+  ControlResponse responsePayload(401, "Not Authenticated");
+
+  Data responseData(commandInterest.getName());
+  responseData.setContent(responsePayload.wireEncode());
+  keyChain.sign(responseData);
+  face->receive(responseData);
+  face->processEvents(time::milliseconds(1));
+
+  BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
+  BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
+  BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), 401);
+}
+
+BOOST_FIXTURE_TEST_CASE(CommandInvalidResponse, CommandFixture)
+{
+  ControlParameters parameters;
+  parameters.setUri("tcp://example.com");
+
+  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
+                         parameters,
+                         commandSucceedCallback,
+                         commandFailCallback));
+  face->processEvents(time::milliseconds(1));
+
+  BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
+  const Interest& commandInterest = face->m_sentInterests[0];
+
+  ControlParameters responseBody;
+  responseBody.setUri("tcp4://192.0.2.1:6363")
+              .setName("ndn:/should-not-have-this-field");
+  // FaceId is missing
+  ControlResponse responsePayload(201, "created");
+  responsePayload.setBody(responseBody.wireEncode());
+
+  Data responseData(commandInterest.getName());
+  responseData.setContent(responsePayload.wireEncode());
+  keyChain.sign(responseData);
+  face->receive(responseData);
+  face->processEvents(time::milliseconds(1));
+
+  BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
+  BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace nfd
+} // namespace ndn
diff --git a/tests/security/identity-fixture.cpp b/tests/security/identity-fixture.cpp
new file mode 100644
index 0000000..2cc7e4f
--- /dev/null
+++ b/tests/security/identity-fixture.cpp
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi0@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "security/key-chain.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace ndn {
+
+// OSX KeyChain, when used on a headless server,
+// forbids usage of a private key if that key isn't created by the calling process.
+// Therefore, unit testing must create its own key pair.
+
+class IdentityFixture
+{
+public:
+  IdentityFixture()
+  {
+    // save the old default identity
+    m_oldDefaultIdentity = m_keyChain.getDefaultIdentity();
+
+    m_newIdentity.set("/ndn-cpp-dev-test-identity");
+    m_newIdentity.appendVersion();
+
+    // create the new identity and self-signed certificate
+    m_keyChain.createIdentity(m_newIdentity);
+
+    // set the new identity as default identity,
+    // and the corresponding certificate becomes the default certificate
+    m_keyChain.setDefaultIdentity(m_newIdentity);
+  }
+
+  ~IdentityFixture()
+  {
+    // recover the old default setting
+    m_keyChain.setDefaultIdentity(m_oldDefaultIdentity);
+
+    // remove the temporarily created identity and certificates
+    m_keyChain.deleteIdentity(m_newIdentity);
+  }
+
+private:
+  KeyChain m_keyChain;
+  Name m_oldDefaultIdentity;
+  Name m_newIdentity;
+};
+
+BOOST_GLOBAL_FIXTURE(IdentityFixture);
+
+} // namespace ndn
diff --git a/tests/transport/dummy-face.hpp b/tests/transport/dummy-face.hpp
new file mode 100644
index 0000000..1ac3cc9
--- /dev/null
+++ b/tests/transport/dummy-face.hpp
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_TESTS_DUMMY_FACE_HPP
+#define NDN_TESTS_DUMMY_FACE_HPP
+
+#include "face.hpp"
+
+namespace ndn {
+
+class DummyTransport : public Transport
+{
+public:
+  void
+  receive(const Block& block)
+  {
+    m_receiveCallback(block);
+  }
+
+  virtual void
+  close()
+  {
+  }
+
+  virtual void
+  pause()
+  {
+  }
+
+  virtual void
+  resume()
+  {
+  }
+
+  virtual void
+  send(const Block& wire)
+  {
+    if (wire.type() == Tlv::Interest) {
+      m_sentInterests->push_back(Interest(wire));
+    }
+    else if (wire.type() == Tlv::Data) {
+      m_sentDatas->push_back(Data(wire));
+    }
+  }
+
+  virtual void
+  send(const Block& header, const Block& payload)
+  {
+    this->send(payload);
+  }
+
+public:
+  std::vector<Interest>* m_sentInterests;
+  std::vector<Data>*     m_sentDatas;
+};
+
+
+/** \brief a Face for unit testing
+ */
+class DummyFace : public Face
+{
+public:
+  explicit
+  DummyFace(shared_ptr<DummyTransport> transport)
+    : Face(transport)
+    , m_transport(transport)
+  {
+    m_transport->m_sentInterests = &m_sentInterests;
+    m_transport->m_sentDatas     = &m_sentDatas;
+  }
+
+  /** \brief cause the Face to receive a packet
+   */
+  template<typename Packet>
+  void
+  receive(const Packet& packet)
+  {
+    m_transport->receive(packet.wireEncode());
+  }
+
+public:
+  std::vector<Interest> m_sentInterests;
+  std::vector<Data>     m_sentDatas;
+
+private:
+  shared_ptr<DummyTransport> m_transport;
+};
+
+inline shared_ptr<DummyFace>
+makeDummyFace()
+{
+  return make_shared<DummyFace>(make_shared<DummyTransport>());
+}
+
+} // namespace ndn
+#endif // NDN_TESTS_DUMMY_FACE_HPP
