diff --git a/README.md b/README.md
index 127f9f3..ab9b378 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,6 @@
 * [dissect](tools/dissect): inspect TLV structure of NDN packet format
 * [dissect-wireshark](tools/dissect-wireshark): Wireshark extension to inspect TLV structure of NDN
   packets
-* [pib](tools/pib): a service to manage the public information of keys and publish certificates
 
 See [INSTALL.md](INSTALL.md) for build instructions.
 
diff --git a/manpages/conf.py b/manpages/conf.py
index 913f0c8..2603561 100644
--- a/manpages/conf.py
+++ b/manpages/conf.py
@@ -14,5 +14,4 @@
     ('ndnpingserver', 'ndnpingserver', 'reachability testing server', None, 1),
     ('ndndump', 'ndndump', 'traffic analysis tool', None, 8),
     ('ndn-dissect', 'ndn-dissect', 'NDN packet format inspector', None, 1),
-    ('ndn-pib', 'ndn-pib',  'NDN PIB service', None, 1),
 ]
diff --git a/manpages/index.rst b/manpages/index.rst
index d76db17..aa554db 100644
--- a/manpages/index.rst
+++ b/manpages/index.rst
@@ -1,6 +1,5 @@
 .. toctree::
   ndn-dissect
-  ndn-pib
   ndndump
   ndnpeek
   ndnping
diff --git a/manpages/ndn-pib.rst b/manpages/ndn-pib.rst
deleted file mode 100644
index e94a7d2..0000000
--- a/manpages/ndn-pib.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-ndn-pib
-========
-
-``ndn-pib`` is a public key and certificate management and publishing service.
-
-Usage
------
-
-::
-
-    ndn-pib [-h] -o owner -d database_dir -t tpm_locator
-
-Description
------------
-
-This command will start a PIB service process which serves signing key lookup/management for local
-applications and also public the public key certificate of signing keys.  The lookup/management
-interface listens on a prefix "/localhost/pib/[OwnerName]" and accept five types of command (get,
-default, list, update, delete). More details can be found at `Public key Info Base (PIB) Service
-<http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base>`__
-
-Since PIB service is queried through Interest/Data exchange, NFD is required to run before this
-command is executed.
-
-This command requires three arguments: ``owner`` specify the owner of the pib service, which is also
-the third name component in the local lookup/management prefix; ``database_dir`` is the path to the
-database where all the public key, certificate, identity are stored and managed; ``tpm_locator`` is
-locator of a TPM which stores the corresponding private key of the public keys in PIB.
-
-Example
--------
-
-::
-
-    $ ndn-pib -o alice -d /var/pib -t tpm-file:/var/ndn/tpm
diff --git a/tests/pib/cert-publisher.t.cpp b/tests/pib/cert-publisher.t.cpp
deleted file mode 100644
index dfcfef6..0000000
--- a/tests/pib/cert-publisher.t.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "tools/pib/cert-publisher.hpp"
-
-#include "tests/identity-management-fixture.hpp"
-
-#include <ndn-cxx/util/dummy-client-face.hpp>
-#include <boost/filesystem.hpp>
-
-namespace ndn {
-namespace pib {
-namespace tests {
-
-class CertPublisherFixture : public ndn::tests::IdentityManagementTimeFixture
-{
-public:
-  CertPublisherFixture()
-    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
-    , db(tmpPath.c_str())
-    , face(io, m_keyChain, {true, true})
-  {
-  }
-
-  ~CertPublisherFixture()
-  {
-    boost::filesystem::remove_all(tmpPath);
-  }
-
-  boost::asio::io_service io;
-  boost::filesystem::path tmpPath;
-  PibDb db;
-  util::DummyClientFace face;
-};
-
-BOOST_AUTO_TEST_SUITE(Pib)
-BOOST_FIXTURE_TEST_SUITE(TestCertPublisher, CertPublisherFixture)
-
-BOOST_AUTO_TEST_CASE(Basic)
-{
-  // Initialize id1
-  Name id1("/test/identity");
-  addIdentity(id1);
-  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
-  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
-  Name keyName11 = cert111->getPublicKeyName();
-
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
-  Name certName112 = cert112->getName();
-
-  CertPublisher certPublisher(face, db);
-
-  // Add a certificate
-  db.addCertificate(*cert111);
-  advanceClocks(io, time::milliseconds(2), 50);
-
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-  auto interest111 = make_shared<Interest>(cert111->getName().getPrefix(-1));
-  face.receive(*interest111);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK(face.sentData[0].wireEncode() == cert111->wireEncode());
-  face.sentData.clear();
-
-  // Add another certificate
-  db.addCertificate(*cert112);
-  advanceClocks(io, time::milliseconds(2), 50);
-
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-  auto interest112 = make_shared<Interest>(cert112->getName().getPrefix(-1));
-  face.receive(*interest112);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK(face.sentData[0].wireEncode() == cert111->wireEncode());
-  face.sentData.clear();
-
-  Exclude exclude;
-  exclude.excludeOne(cert111->getName().get(-1));
-  interest112->setExclude(exclude);
-  face.receive(*interest112);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK(face.sentData[0].wireEncode() == cert112->wireEncode());
-  face.sentData.clear();
-
-  // delete a certificate
-  db.deleteCertificate(certName112);
-  face.receive(*interest112);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-
-  face.receive(*interest111);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK(face.sentData[0].wireEncode() == cert111->wireEncode());
-  face.sentData.clear();
-
-  // delete another certificate
-  db.deleteCertificate(certName111);
-  face.receive(*interest112);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-
-  face.receive(*interest111);
-  advanceClocks(io, time::milliseconds(2), 50);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestPibPublisher
-BOOST_AUTO_TEST_SUITE_END() // Pib
-
-} // namespace tests
-} // namespace pib
-} // namespace ndn
diff --git a/tests/pib/key-cache.t.cpp b/tests/pib/key-cache.t.cpp
deleted file mode 100644
index ab245c4..0000000
--- a/tests/pib/key-cache.t.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "tools/pib/key-cache.hpp"
-
-#include "tests/test-common.hpp"
-
-namespace ndn {
-namespace pib {
-namespace tests {
-
-BOOST_AUTO_TEST_SUITE(Pib)
-BOOST_AUTO_TEST_SUITE(TestKeyCache)
-
-BOOST_AUTO_TEST_CASE(Basic)
-{
-  KeyCache keyCache(3);
-
-  Name name1("/1");
-  Name name2("/2");
-  Name name3("/3");
-  Name name4("/4");
-
-  auto key1 = make_shared<PublicKey>();
-  auto key2 = make_shared<PublicKey>();
-  auto key3 = make_shared<PublicKey>();
-  auto key4 = make_shared<PublicKey>();
-
-  keyCache.insert(name1, key1);
-  keyCache.insert(name2, key2);
-  keyCache.insert(name3, key3);
-
-  BOOST_CHECK_EQUAL(keyCache.size(), 3);
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name1)));
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name2)));
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
-  BOOST_CHECK(!static_cast<bool>(keyCache.find(name4)));
-
-  keyCache.insert(name1, key1);
-  keyCache.insert(name4, key4);
-  BOOST_CHECK_EQUAL(keyCache.size(), 3);
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name1)));
-  BOOST_CHECK(!static_cast<bool>(keyCache.find(name2)));
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name4)));
-
-  keyCache.erase(name1);
-  BOOST_CHECK_EQUAL(keyCache.size(), 2);
-  BOOST_CHECK(!static_cast<bool>(keyCache.find(name1)));
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
-  BOOST_CHECK(static_cast<bool>(keyCache.find(name4)));
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestKeyCache
-BOOST_AUTO_TEST_SUITE_END() // Pib
-
-} // namespace tests
-} // namespace pib
-} // namespace ndn
diff --git a/tests/pib/pib-db.t.cpp b/tests/pib/pib-db.t.cpp
deleted file mode 100644
index 49e7e2c..0000000
--- a/tests/pib/pib-db.t.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "tools/pib/pib-db.hpp"
-
-#include "tests/identity-management-fixture.hpp"
-
-#include <boost/filesystem.hpp>
-
-namespace ndn {
-namespace pib {
-namespace tests {
-
-class PibDbTestFixture : public ndn::tests::IdentityManagementTimeFixture
-{
-public:
-  PibDbTestFixture()
-    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
-    , db(tmpPath.c_str())
-  {
-  }
-
-  ~PibDbTestFixture()
-  {
-    boost::filesystem::remove_all(tmpPath);
-  }
-
-  boost::asio::io_service io;
-  boost::filesystem::path tmpPath;
-  PibDb db;
-  std::vector<Name> deletedIds;
-  std::vector<Name> deletedKeys;
-  std::vector<Name> deletedCerts;
-  std::vector<Name> insertedCerts;
-};
-
-
-BOOST_AUTO_TEST_SUITE(Pib)
-BOOST_FIXTURE_TEST_SUITE(TestPibDb, PibDbTestFixture)
-
-BOOST_AUTO_TEST_CASE(MgmtTest)
-{
-  Name testUser("/localhost/pib/test/mgmt");
-  addIdentity(testUser);
-  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
-  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
-
-
-  BOOST_CHECK_EQUAL(db.getOwnerName(), "");
-  BOOST_CHECK(db.getMgmtCertificate() == nullptr);
-
-  db.updateMgmtCertificate(*testUserCert);
-  BOOST_CHECK_EQUAL(db.getOwnerName(), "test");
-  BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
-  BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(), testUserCertName);
-
-  db.setTpmLocator("tpmLocator");
-  BOOST_CHECK_EQUAL(db.getTpmLocator(), "tpmLocator");
-
-  Name testUser2("/localhost/pib/test2/mgmt");
-  addIdentity(testUser2);
-  Name testUser2CertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser2);
-  shared_ptr<IdentityCertificate> testUser2Cert = m_keyChain.getCertificate(testUser2CertName);
-
-  BOOST_CHECK_THROW(db.updateMgmtCertificate(*testUser2Cert), PibDb::Error);
-
-  Name testUserKeyName2 = m_keyChain.generateRsaKeyPairAsDefault(testUser);
-  shared_ptr<IdentityCertificate> testUserCert2 = m_keyChain.selfSign(testUserKeyName2);
-
-  BOOST_CHECK_NO_THROW(db.updateMgmtCertificate(*testUserCert2));
-  BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
-  BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(),
-                    testUserCert2->getName());
-}
-
-BOOST_AUTO_TEST_CASE(IdentityTest)
-{
-  db.identityDeleted.connect([this] (const Name& id) {
-      this->deletedIds.push_back(id);
-    });
-
-  Name identity("/test/identity");
-  Name identity2("/test/identity2");
-
-  // Add an identity: /test/identity
-  // Since there is no default identity,
-  // the new added identity will be set as the default identity.
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
-  db.addIdentity(identity);
-  BOOST_CHECK(db.hasIdentity(identity));
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
-
-  // Add the second identity: /test/identity2
-  // Since the default identity exists,
-  // the new added identity will not be set as the default identity.
-  db.addIdentity(identity2);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
-
-  // Set the second identity: /test/identity2 as default explicitly
-  db.setDefaultIdentity(identity2);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
-
-  // Delete identity /test/identity2, which is also the default one
-  // This will trigger the identityDeleted signal
-  // and also causes no default identity.
-  db.deleteIdentity(identity2);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity), true);
-  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
-  BOOST_CHECK_EQUAL(deletedIds[0], identity2);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
-  deletedIds.clear();
-
-  // Add the second identity back
-  // Since there is no default identity (though another identity still exists),
-  // the second identity will be set as default.
-  db.addIdentity(identity2);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
-
-  // Delete identity /test/identity
-  db.deleteIdentity(identity);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
-  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
-  BOOST_CHECK_EQUAL(deletedIds[0], identity);
-  deletedIds.clear();
-
-  // Delete identity /test/identity2
-  db.deleteIdentity(identity2);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
-  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
-  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
-  BOOST_CHECK_EQUAL(deletedIds[0], identity2);
-  deletedIds.clear();
-}
-
-
-BOOST_AUTO_TEST_CASE(KeyTest)
-{
-  db.identityDeleted.connect([this] (const Name& id) {
-      this->deletedIds.push_back(id);
-    });
-
-  db.keyDeleted.connect([this] (const Name& key) {
-      this->deletedKeys.push_back(key);
-    });
-
-  // Initialize id1
-  Name id1("/test/identity");
-  addIdentity(id1);
-  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
-  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
-  Name keyName11 = cert111->getPublicKeyName();
-  PublicKey& key11 = cert111->getPublicKeyInfo();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
-  shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
-  PublicKey& key12 = cert121->getPublicKeyInfo();
-
-  // Initialize id2
-  advanceClocks(io, time::milliseconds(100));
-  Name id2("/test/identity2");
-  addIdentity(id2);
-  Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
-  shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
-  Name keyName21 = cert211->getPublicKeyName();
-  PublicKey& key21 = cert211->getPublicKeyInfo();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
-  shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
-  PublicKey& key22 = cert221->getPublicKeyInfo();
-
-  // Add a key, the corresponding identity should be added as well
-  // Since the PIB does not have any default identity set before,
-  // the added identity will be set as default.
-  // Since there is no default key for the identity,
-  // the added key will be set as default.
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
-  BOOST_CHECK(db.getKey(keyName11) == nullptr);
-  db.addKey(keyName11, key11);
-  BOOST_CHECK(db.hasIdentity(id1));
-  BOOST_CHECK(db.getKey(keyName11) != nullptr);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
-
-  // Add the second key of /test/identity.
-  // Since the default key of /test/identity has been set,
-  // The new added key will not be set as default.
-  db.addKey(keyName12, key12);
-  BOOST_CHECK(db.getKey(keyName12) != nullptr);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
-
-  // Explicitly set the second key as the default key of /test/identity
-  db.setDefaultKeyNameOfIdentity(keyName12);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
-
-  // Delete the second key which is also the default key.
-  // This will trigger the keyDeleted signal.
-  // This will also cause no default key for /test/identity
-  db.deleteKey(keyName12);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName22), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName21), false);
-  BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
-  BOOST_CHECK_EQUAL(deletedKeys[0], keyName12);
-  deletedKeys.clear();
-
-  // Add the second key back.
-  // Since there is no default key of /test/identity (although another key still exists)
-  // The second key will be set as the default key of /test/identity
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
-  db.addKey(keyName12, key12);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
-
-  // Prepare test for identity deletion
-  db.addKey(keyName21, key21);
-  db.addKey(keyName22, key22);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
-
-  // Delete the identity.
-  // All keys of the identity should also be deleted,
-  // and the keyDeleted signal should be triggered twice.
-  db.deleteIdentity(id1);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
-  BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
-  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
-              deletedKeys.end());
-  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
-              deletedKeys.end());
-  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
-  BOOST_CHECK_EQUAL(deletedIds[0], id1);
-}
-
-BOOST_AUTO_TEST_CASE(CertTest)
-{
-  db.identityDeleted.connect([this] (const Name& id) {
-      this->deletedIds.push_back(id);
-    });
-
-  db.keyDeleted.connect([this] (const Name& key) {
-      this->deletedKeys.push_back(key);
-    });
-
-  db.certificateDeleted.connect([this] (const Name& certificate) {
-      this->deletedCerts.push_back(certificate);
-    });
-
-  db.certificateInserted.connect([this] (const Name& certificate) {
-      this->insertedCerts.push_back(certificate);
-    });
-
-  // Initialize id1
-  Name id1("/test/identity");
-  addIdentity(id1);
-  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
-  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
-  Name keyName11 = cert111->getPublicKeyName();
-
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
-  Name certName112 = cert112->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
-  shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
-  Name certName121 = cert121->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert122 = m_keyChain.selfSign(keyName12);
-  Name certName122 = cert122->getName();
-
-  // Initialize id2
-  advanceClocks(io, time::milliseconds(100));
-  Name id2("/test/identity2");
-  addIdentity(id2);
-  Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
-  shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
-  Name keyName21 = cert211->getPublicKeyName();
-
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert212 = m_keyChain.selfSign(keyName21);
-  Name certName212 = cert212->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
-  shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
-  Name certName221 = cert221->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert222 = m_keyChain.selfSign(keyName22);
-  Name certName222 = cert222->getName();
-
-  // Add a certificate
-  // This will also add the corresponding key and identity.
-  // Since there is no default setting before,
-  // The certificate will be set as the default one of the key, and so be the key and identity
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
-  db.addCertificate(*cert111);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
-  BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName111) !=
-              insertedCerts.end());
-  insertedCerts.clear();
-
-  // Add the second certificate of the same key
-  // Since default certificate already exists, no default setting changes.
-  BOOST_CHECK(db.getCertificate(certName112) == nullptr);
-  db.addCertificate(*cert112);
-  BOOST_CHECK(db.getCertificate(certName112) != nullptr);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
-  BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName112) !=
-              insertedCerts.end());
-  insertedCerts.clear();
-
-  // Explicitly set the second certificate as the default one of the key.
-  db.setDefaultCertNameOfKey(certName112);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
-
-  // Delete the default certificate
-  // This will trigger certificateDeleted signal
-  // and also causes no default certificate for the key.
-  db.deleteCertificate(certName112);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
-  BOOST_CHECK_EQUAL(deletedCerts.size(), 1);
-  BOOST_CHECK_EQUAL(deletedCerts[0], certName112);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
-  deletedCerts.clear();
-
-  // Add the second certificate back
-  // Since there is no default certificate of the key (though another certificate still exists),
-  // the new added certificate will be set as default
-  db.addCertificate(*cert112);
-  BOOST_CHECK(db.getCertificate(certName112) != nullptr);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
-  insertedCerts.clear();
-
-  // Add entries for delete tests
-  db.addCertificate(*cert111); // already exists no certInserted signal emitted
-  db.addCertificate(*cert112); // already exists no certInserted signal emitted
-  db.addCertificate(*cert121);
-  db.addCertificate(*cert122);
-  db.addCertificate(*cert211);
-  db.addCertificate(*cert212);
-  db.addCertificate(*cert221);
-  db.addCertificate(*cert222);
-  BOOST_CHECK_EQUAL(insertedCerts.size(), 6);
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName121) !=
-              insertedCerts.end());
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName122) !=
-              insertedCerts.end());
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName211) !=
-              insertedCerts.end());
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName212) !=
-              insertedCerts.end());
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName221) !=
-              insertedCerts.end());
-  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName222) !=
-              insertedCerts.end());
-  insertedCerts.clear();
-
-  // Delete the key.
-  // All the related certificates will be deleted as well.
-  db.deleteKey(keyName11);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName122), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName121), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
-  BOOST_CHECK_EQUAL(deletedCerts.size(), 2);
-  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
-              deletedCerts.end());
-  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
-              deletedCerts.end());
-  BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
-  BOOST_CHECK_EQUAL(deletedKeys[0], keyName11);
-  deletedCerts.clear();
-  deletedKeys.clear();
-
-  // Recover deleted entries
-  db.addCertificate(*cert111);
-  db.addCertificate(*cert112);
-
-  // Delete the identity
-  // All the related certificates and keys will be deleted as well.
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
-  db.deleteIdentity(id1);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName122), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName121), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
-  BOOST_CHECK_EQUAL(deletedCerts.size(), 4);
-  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
-              deletedCerts.end());
-  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
-              deletedCerts.end());
-  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName121) !=
-              deletedCerts.end());
-  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName122) !=
-              deletedCerts.end());
-  BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
-  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
-              deletedKeys.end());
-  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
-              deletedCerts.end());
-  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
-  BOOST_CHECK_EQUAL(deletedIds[0], id1);
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestPibDb
-BOOST_AUTO_TEST_SUITE_END() // Pib
-
-} // namespace tests
-} // namespace pib
-} // namespace ndn
diff --git a/tests/pib/pib-validator.t.cpp b/tests/pib/pib-validator.t.cpp
deleted file mode 100644
index dc83f2a..0000000
--- a/tests/pib/pib-validator.t.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "tools/pib/pib-validator.hpp"
-#include "tools/pib/encoding/update-param.hpp"
-#include "tools/pib/encoding/delete-param.hpp"
-
-#include "tests/identity-management-fixture.hpp"
-
-#include <ndn-cxx/security/key-chain.hpp>
-#include <boost/filesystem.hpp>
-
-namespace ndn {
-namespace pib {
-namespace tests {
-
-class PibValidatorFixture : public ndn::tests::IdentityManagementTimeFixture
-{
-public:
-  PibValidatorFixture()
-    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
-    , db(tmpPath.c_str())
-  {
-  }
-
-  ~PibValidatorFixture()
-  {
-    boost::filesystem::remove_all(tmpPath);
-  }
-
-  boost::asio::io_service io;
-  boost::filesystem::path tmpPath;
-  PibDb db;
-  bool isProcessed;
-};
-
-BOOST_AUTO_TEST_SUITE(Pib)
-BOOST_FIXTURE_TEST_SUITE(TestPibValidator, PibValidatorFixture)
-
-BOOST_AUTO_TEST_CASE(Basic)
-{
-  PibValidator validator(db);
-
-  Name testUser("/localhost/pib/test/mgmt");
-  BOOST_REQUIRE(addIdentity(testUser, RsaKeyParams()));
-  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
-  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name testUser2("/localhost/pib/test2/mgmt");
-  BOOST_REQUIRE(addIdentity(testUser2, RsaKeyParams()));
-
-  db.updateMgmtCertificate(*testUserCert);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name normalId("/normal/id");
-  BOOST_REQUIRE(addIdentity(normalId, RsaKeyParams()));
-  Name normalIdCertName = m_keyChain.getDefaultCertificateNameForIdentity(normalId);
-  shared_ptr<IdentityCertificate> normalIdCert = m_keyChain.getCertificate(normalIdCertName);
-
-  db.addIdentity(normalId);
-  db.addKey(normalIdCert->getPublicKeyName(), normalIdCert->getPublicKeyInfo());
-  db.addCertificate(*normalIdCert);
-
-  Name command1("/localhost/pib/test/verb/param");
-  shared_ptr<Interest> interest1 = make_shared<Interest>(command1);
-  m_keyChain.signByIdentity(*interest1, testUser);
-  // "test" user is trusted for any command about itself, OK.
-  isProcessed = false;
-  validator.validate(*interest1,
-    [this] (const shared_ptr<const Interest>&) {
-      isProcessed = true;
-      BOOST_CHECK(true);
-    },
-    [this] (const shared_ptr<const Interest>&, const std::string&) {
-      isProcessed = true;
-      BOOST_CHECK(false);
-    });
-  BOOST_CHECK(isProcessed);
-
-  Name command2("/localhost/pib/test/verb/param");
-  shared_ptr<Interest> interest2 = make_shared<Interest>(command2);
-  m_keyChain.signByIdentity(*interest2, testUser2);
-  // "test2" user is NOT trusted for any command about other user, MUST fail
-  isProcessed = false;
-  validator.validate(*interest2,
-    [this] (const shared_ptr<const Interest>&) {
-      isProcessed = true;
-      BOOST_CHECK(false);
-    },
-    [this] (const shared_ptr<const Interest>&, const std::string&) {
-      isProcessed = true;
-      BOOST_CHECK(true);
-    });
-  BOOST_CHECK(isProcessed);
-
-  Name command3("/localhost/pib/test/verb/param");
-  shared_ptr<Interest> interest3 = make_shared<Interest>(command3);
-  m_keyChain.signByIdentity(*interest3, normalId);
-  // "normalId" is in "test" pib, can be trusted for some commands about "test".
-  // Detail checking is needed, but it is not the job of Validator, OK.
-  isProcessed = false;
-  validator.validate(*interest3,
-    [this] (const shared_ptr<const Interest>&) {
-      isProcessed = true;
-      BOOST_CHECK(true);
-    },
-    [this] (const shared_ptr<const Interest>&, const std::string&) {
-      isProcessed = true;
-      BOOST_CHECK(false);
-    });
-  BOOST_CHECK(isProcessed);
-
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestPibValidator
-BOOST_AUTO_TEST_SUITE_END() // Pib
-
-} // namespace tests
-} // namespace pib
-} // namespace ndn
diff --git a/tests/pib/pib.t.cpp b/tests/pib/pib.t.cpp
deleted file mode 100644
index 8c9b920..0000000
--- a/tests/pib/pib.t.cpp
+++ /dev/null
@@ -1,1392 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "tools/pib/pib.hpp"
-#include "tools/pib/encoding/pib-encoding.hpp"
-
-#include "tests/identity-management-fixture.hpp"
-
-#include <ndn-cxx/security/sec-tpm-file.hpp>
-#include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/util/dummy-client-face.hpp>
-#include <boost/filesystem.hpp>
-
-namespace ndn {
-namespace pib {
-namespace tests {
-
-class PibTestFixture : public ndn::tests::IdentityManagementTimeFixture
-{
-public:
-  PibTestFixture()
-    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "PibTest")
-    , face(io, m_keyChain, {true, true})
-  {
-  }
-
-  ~PibTestFixture()
-  {
-    boost::filesystem::remove_all(tmpPath);
-  }
-
-  template<class Param>
-  shared_ptr<Interest>
-  generateUnsignedInterest(Param& param, const std::string& user)
-  {
-    Name command("/localhost/pib");
-    command.append(user).append(Param::VERB).append(param.wireEncode());
-    shared_ptr<Interest> interest = make_shared<Interest>(command);
-
-    return interest;
-  }
-
-  template<class Param>
-  shared_ptr<Interest>
-  generateSignedInterest(Param& param, const std::string& user, const Name& certName)
-  {
-    shared_ptr<Interest> interest = generateUnsignedInterest(param, user);
-    m_keyChain.sign(*interest, certName);
-
-    return interest;
-  }
-
-  boost::asio::io_service io;
-  std::string owner;
-  boost::filesystem::path tmpPath;
-  util::DummyClientFace face;
-};
-
-BOOST_AUTO_TEST_SUITE(Pib)
-BOOST_FIXTURE_TEST_SUITE(TestPib, PibTestFixture)
-
-using ndn::pib::Pib;
-
-BOOST_AUTO_TEST_CASE(InitCertTest1)
-{
-  // Create a PIB with full parameters
-  owner = "testUser";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK_EQUAL(pib.getOwner(), owner);
-  BOOST_CHECK_EQUAL(pib.getDb().getOwnerName(), owner);
-
-  auto mgmtCert = pib.getMgmtCert();
-  BOOST_CHECK_EQUAL(mgmtCert.getName().getPrefix(-3),
-                    Name("/localhost/pib/testUser/mgmt/KEY"));
-  BOOST_CHECK_EQUAL(mgmtCert.getName().get(5).toUri().substr(0, 4), "dsk-");
-
-  auto mgmtCert2 = pib.getDb().getMgmtCertificate();
-  BOOST_REQUIRE(mgmtCert2 != nullptr);
-  BOOST_CHECK(mgmtCert.wireEncode() == mgmtCert2->wireEncode());
-
-  BOOST_CHECK_EQUAL(pib.getDb().getTpmLocator(), m_keyChain.getTpm().getTpmLocator());
-
-  GetParam param01;
-  shared_ptr<Interest> interest01 = generateUnsignedInterest(param01, owner);
-
-  face.receive(*interest01);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibUser result01;
-  BOOST_REQUIRE_NO_THROW(result01.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK(result01.getMgmtCert().wireEncode() == mgmtCert.wireEncode());
-  BOOST_CHECK_EQUAL(result01.getTpmLocator(), m_keyChain.getTpm().getTpmLocator());
-}
-
-BOOST_AUTO_TEST_CASE(InitCertTest2)
-{
-  // Create a PIB from a database (assume that the database is configured)
-  std::string dbDir = tmpPath.string();
-  std::string tpmLocator = m_keyChain.getTpm().getTpmLocator();
-  owner = "testUser";
-
-  Name testUser("/localhost/pib/testUser/mgmt");
-
-  addIdentity(testUser);
-  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
-  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
-
-  PibDb db(tmpPath.string());
-  BOOST_CHECK_NO_THROW(Pib(face, dbDir, tpmLocator, owner));
-
-  db.updateMgmtCertificate(*testUserCert);
-  BOOST_CHECK_NO_THROW(Pib(face, dbDir, tpmLocator, owner));
-  BOOST_CHECK_THROW(Pib(face, dbDir, tpmLocator, "wrongUser"), Pib::Error);
-
-  db.setTpmLocator(m_keyChain.getTpm().getTpmLocator());
-  BOOST_CHECK_NO_THROW(Pib(face, dbDir, tpmLocator, owner));
-  BOOST_CHECK_THROW(Pib(face, dbDir, "tpm-file:wrong", owner), Pib::Error);
-
-  advanceClocks(io, time::milliseconds(10));
-  m_keyChain.deleteIdentity(testUser);
-  BOOST_CHECK_NO_THROW(Pib(face, dbDir, tpmLocator, owner));
-}
-
-BOOST_AUTO_TEST_CASE(InitCertTest3)
-{
-  std::string dbDir = tmpPath.string();
-  std::string tpmLocator = m_keyChain.getTpm().getTpmLocator();
-  owner = "testUser";
-
-  Name testUser("/localhost/pib/testUser/mgmt");
-  addIdentity(testUser);
-  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
-  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
-
-  Pib pib1(face, dbDir, tpmLocator, owner);
-  BOOST_CHECK_EQUAL(pib1.getMgmtCert().getName().getPrefix(-3),
-                    Name("/localhost/pib/testUser/mgmt/KEY"));
-
-  PibDb db(tmpPath.string());
-  db.updateMgmtCertificate(*testUserCert);
-  Pib pib2(face, dbDir, tpmLocator, owner);
-  BOOST_CHECK_EQUAL(pib2.getMgmtCert().getName(), testUserCertName);
-
-  advanceClocks(io, time::milliseconds(10));
-  m_keyChain.deleteIdentity(testUser);
-  Pib pib3(face, dbDir, tpmLocator, owner);
-  BOOST_CHECK(pib3.getMgmtCert().getName() != testUserCertName);
-  BOOST_CHECK_EQUAL(pib3.getMgmtCert().getName().getPrefix(-3),
-                    Name("/localhost/pib/testUser/mgmt/KEY"));
-}
-
-BOOST_AUTO_TEST_CASE(GetCommandTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  PibDb db(tmpPath.string());
-
-  Name testId("/test/identity");
-  Name testIdCertName00 = m_keyChain.createIdentity(testId);
-  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
-  Name testIdKeyName0 = cert00->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
-  Name testIdCertName01 = cert01->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName10 = cert10->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName11 = cert11->getName();
-
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
-
-  db.addCertificate(*cert00);
-  db.addCertificate(*cert01);
-  db.addCertificate(*cert10);
-  db.addCertificate(*cert11);
-  db.setDefaultIdentity(testId);
-  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
-  db.setDefaultCertNameOfKey(testIdCertName00);
-
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
-
-  // Get Param
-  GetParam param01;
-  shared_ptr<Interest> interest01 = generateUnsignedInterest(param01, owner);
-
-  face.sentData.clear();
-  face.receive(*interest01);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest01->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibUser result01;
-  BOOST_REQUIRE_NO_THROW(result01.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK(result01.getMgmtCert().wireEncode() == ownerMgmtCert.wireEncode());
-
-
-  GetParam param02;
-  shared_ptr<Interest> interest02 = generateUnsignedInterest(param02, "non-existing");
-
-  face.sentData.clear();
-  face.receive(*interest02);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest02->getName()) == nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-
-
-  GetParam param03(TYPE_ID, testId);
-  shared_ptr<Interest> interest03 = generateUnsignedInterest(param03, owner);
-
-  face.sentData.clear();
-  face.receive(*interest03);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest03->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibIdentity result03;
-  BOOST_REQUIRE_NO_THROW(result03.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result03.getIdentity(), testId);
-
-
-  Name wrongId("/wrong/id");
-  GetParam param04(TYPE_ID, wrongId);
-  shared_ptr<Interest> interest04 = generateUnsignedInterest(param04, owner);
-
-  face.sentData.clear();
-  face.receive(*interest04);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest04->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result04;
-  BOOST_REQUIRE_NO_THROW(result04.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result04.getErrorCode(), ERR_NON_EXISTING_ID);
-
-
-  GetParam param05(TYPE_KEY, testIdKeyName1);
-  shared_ptr<Interest> interest05 = generateUnsignedInterest(param05, owner);
-
-  face.sentData.clear();
-  face.receive(*interest05);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest05->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibPublicKey result05;
-  BOOST_REQUIRE_NO_THROW(result05.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result05.getKeyName(), testIdKeyName1);
-
-
-  Name wrongKeyName1("/wrong/key/name1");
-  GetParam param06(TYPE_KEY, wrongKeyName1);
-  shared_ptr<Interest> interest06 = generateUnsignedInterest(param06, owner);
-
-  face.sentData.clear();
-  face.receive(*interest06);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest06->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result06;
-  BOOST_REQUIRE_NO_THROW(result06.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result06.getErrorCode(), ERR_NON_EXISTING_KEY);
-
-
-  GetParam param07(TYPE_CERT, testIdCertName00);
-  shared_ptr<Interest> interest07 = generateUnsignedInterest(param07, owner);
-
-  face.sentData.clear();
-  face.receive(*interest07);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest07->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibCertificate result07;
-  BOOST_REQUIRE_NO_THROW(result07.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result07.getCertificate().getName(), testIdCertName00);
-
-
-  Name wrongCertName1("/wrong/cert/name1");
-  GetParam param08(TYPE_CERT, wrongCertName1);
-  shared_ptr<Interest> interest08 = generateUnsignedInterest(param08, owner);
-
-  face.sentData.clear();
-  face.receive(*interest08);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest08->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result08;
-  BOOST_REQUIRE_NO_THROW(result08.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result08.getErrorCode(), ERR_NON_EXISTING_CERT);
-
-
-  Name wrongKeyName2;
-  GetParam param09(TYPE_KEY, wrongKeyName2);
-  shared_ptr<Interest> interest09 = generateUnsignedInterest(param09, owner);
-
-  face.sentData.clear();
-  face.receive(*interest09);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest09->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result09;
-  BOOST_REQUIRE_NO_THROW(result09.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result09.getErrorCode(), ERR_WRONG_PARAM);
-}
-
-BOOST_AUTO_TEST_CASE(DefaultCommandTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  PibDb db(tmpPath.string());
-
-  Name testId("/test/identity");
-  Name testIdCertName00 = m_keyChain.createIdentity(testId);
-  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
-  Name testIdKeyName0 = cert00->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
-  Name testIdCertName01 = cert01->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName10 = cert10->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName11 = cert11->getName();
-
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
-
-  db.addCertificate(*cert00);
-  db.addCertificate(*cert01);
-  db.addCertificate(*cert10);
-  db.addCertificate(*cert11);
-  db.setDefaultIdentity(testId);
-  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
-  db.setDefaultCertNameOfKey(testIdCertName00);
-
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
-
-  // Default Param
-  DefaultParam param11(TYPE_ID, TYPE_USER);
-  shared_ptr<Interest> interest11 = generateUnsignedInterest(param11, owner);
-
-  face.sentData.clear();
-  face.receive(*interest11);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest11->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibIdentity result11;
-  BOOST_REQUIRE_NO_THROW(result11.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result11.getIdentity(), testId);
-
-
-  DefaultParam param13(TYPE_ID, TYPE_ID);
-  shared_ptr<Interest> interest13 = generateUnsignedInterest(param13, owner);
-
-  face.sentData.clear();
-  face.receive(*interest13);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest13->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result13;
-  BOOST_REQUIRE_NO_THROW(result13.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result13.getErrorCode(), ERR_WRONG_PARAM);
-
-
-  DefaultParam param14(TYPE_KEY, TYPE_ID, testId);
-  shared_ptr<Interest> interest14 = generateUnsignedInterest(param14, owner);
-
-  face.sentData.clear();
-  face.receive(*interest14);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest14->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibPublicKey result14;
-  BOOST_REQUIRE_NO_THROW(result14.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result14.getKeyName(), testIdKeyName0);
-
-
-  DefaultParam param15(TYPE_CERT, TYPE_ID, testId);
-  shared_ptr<Interest> interest15 = generateUnsignedInterest(param15, owner);
-
-  face.sentData.clear();
-  face.receive(*interest15);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest15->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibCertificate result15;
-  BOOST_REQUIRE_NO_THROW(result15.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result15.getCertificate().getName(), testIdCertName00);
-
-
-  DefaultParam param16(TYPE_CERT, TYPE_USER);
-  shared_ptr<Interest> interest16 = generateUnsignedInterest(param16, owner);
-
-  face.sentData.clear();
-  face.receive(*interest16);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest16->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibCertificate result16;
-  BOOST_REQUIRE_NO_THROW(result16.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result16.getCertificate().getName(), testIdCertName00);
-
-
-  DefaultParam param17(TYPE_CERT, TYPE_KEY, testIdKeyName1);
-  shared_ptr<Interest> interest17 = generateUnsignedInterest(param17, owner);
-
-  face.sentData.clear();
-  face.receive(*interest17);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest17->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibCertificate result17;
-  BOOST_REQUIRE_NO_THROW(result17.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result17.getCertificate().getName(), testIdCertName10);
-}
-
-BOOST_AUTO_TEST_CASE(ListCommandTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  PibDb db(tmpPath.string());
-
-  Name testId("/test/identity");
-  Name testIdCertName00 = m_keyChain.createIdentity(testId);
-  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
-  Name testIdKeyName0 = cert00->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
-  Name testIdCertName01 = cert01->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName10 = cert10->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName11 = cert11->getName();
-
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
-
-  db.addCertificate(*cert00);
-  db.addCertificate(*cert01);
-  db.addCertificate(*cert10);
-  db.addCertificate(*cert11);
-  db.setDefaultIdentity(testId);
-  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
-  db.setDefaultCertNameOfKey(testIdCertName00);
-
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
-
-  Name wrongId("/wrong/id");
-
-  // List Param
-  ListParam param21;
-  shared_ptr<Interest> interest21 = generateUnsignedInterest(param21, owner);
-
-  face.sentData.clear();
-  face.receive(*interest21);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest21->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibNameList result21;
-  BOOST_REQUIRE_NO_THROW(result21.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result21.getNameList().size(), 1);
-
-
-  ListParam param22(TYPE_ID, testId);
-  shared_ptr<Interest> interest22 = generateUnsignedInterest(param22, owner);
-
-  face.sentData.clear();
-  face.receive(*interest22);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest22->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibNameList result22;
-  BOOST_REQUIRE_NO_THROW(result22.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result22.getNameList().size(), 2);
-
-
-  ListParam param23(TYPE_ID, wrongId);
-  shared_ptr<Interest> interest23 = generateUnsignedInterest(param23, owner);
-
-  face.sentData.clear();
-  face.receive(*interest23);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest23->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibNameList result23;
-  BOOST_REQUIRE_NO_THROW(result23.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result23.getNameList().size(), 0);
-}
-
-BOOST_AUTO_TEST_CASE(IsUpdateAllowedTest1)
-{
-  // This test case is to check the access control of local management key
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-
-  UpdateQueryProcessor& pro = pib.m_updateProcessor;
-
-  Name target01("/localhost/pib");
-  Name target02("/localhost/pib/alice/mgmt");
-  Name target03("/localhost/pib/alice/mgmt/ok");
-  Name target04("/localhost/pib/alice");
-  Name target05("/test/id");
-  Name target06("/test/id/ksk-123");
-  Name target07("/test/id/KEY/ksk-123/ID-CERT/version");
-  Name signer01 = pib.getMgmtCert().getName().getPrefix(-1);
-  Name signer02("/localhost/pib/bob/mgmt/KEY/ksk-1234/ID-CERT");
-
-  // TYPE_USER is handled separately, isUpdatedAllowed simply returns false
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_USER, target02, signer01, DEFAULT_OPT_NO), false);
-
-  // Test access control of local management key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target01, signer01, DEFAULT_OPT_NO), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target02, signer01, DEFAULT_OPT_NO), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target03, signer01, DEFAULT_OPT_NO), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target04, signer01, DEFAULT_OPT_NO), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target05, signer01, DEFAULT_OPT_NO), true);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target05, signer02, DEFAULT_OPT_NO), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, target06, signer01, DEFAULT_OPT_NO), true);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, target06, signer02, DEFAULT_OPT_NO), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, target07, signer01, DEFAULT_OPT_NO), true);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, target07, signer02, DEFAULT_OPT_NO), false);
-}
-
-BOOST_AUTO_TEST_CASE(IsUpdateAllowedTest2)
-{
-  // This test case is to check the access control of regular key
-
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  PibDb db(tmpPath.string());
-
-  UpdateQueryProcessor& pro = pib.m_updateProcessor;
-
-  Name parent("/test");
-  addIdentity(parent);
-  Name parentCertName = m_keyChain.getDefaultCertificateNameForIdentity(parent);
-  shared_ptr<IdentityCertificate> parentCert = m_keyChain.getCertificate(parentCertName);
-  Name parentSigner = parentCertName.getPrefix(-1);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name parentKeyName2 = m_keyChain.generateRsaKeyPair(parent);
-  shared_ptr<IdentityCertificate> parentCert2 = m_keyChain.selfSign(parentKeyName2);
-  Name parentSigner2 = parentCert2->getName().getPrefix(-1);
-
-  db.addIdentity(parent);
-  db.addKey(parentCert->getPublicKeyName(), parentCert->getPublicKeyInfo());
-  db.addKey(parentCert2->getPublicKeyName(), parentCert2->getPublicKeyInfo());
-  db.setDefaultKeyNameOfIdentity(parentCert->getPublicKeyName());
-  db.addCertificate(*parentCert);
-  db.setDefaultCertNameOfKey(parentCert->getName());
-  db.addCertificate(*parentCert2);
-  db.setDefaultCertNameOfKey(parentCert2->getName());
-
-  Name testId("/test/id");
-  addIdentity(testId);
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(testId);
-  shared_ptr<IdentityCertificate> testCert = m_keyChain.getCertificate(certName);
-  Name testKeyName = testCert->getPublicKeyName();
-  Name testSigner = certName.getPrefix(-1);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name secondKeyName = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> secondCert = m_keyChain.selfSign(secondKeyName);
-  Name secondCertName = secondCert->getName();
-  Name secondSigner = secondCertName.getPrefix(-1);
-
-  db.addIdentity(testId);
-  db.addKey(testKeyName, testCert->getPublicKeyInfo());
-  db.addKey(secondKeyName, secondCert->getPublicKeyInfo());
-  db.setDefaultKeyNameOfIdentity(testKeyName);
-  db.addCertificate(*testCert);
-  db.setDefaultCertNameOfKey(testCert->getName());
-  db.addCertificate(*secondCert);
-  db.setDefaultCertNameOfKey(secondCert->getName());
-
-  Name nonSigner("/non-signer/KEY/ksk-123/ID-CERT");
-
-  // for target type = TYPE_ID
-  // one cannot add non-child
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, nonSigner, DEFAULT_OPT_NO), false);
-  // parent can add child
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_NO), true);
-  // non-default parent key cannot add a child
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner2, DEFAULT_OPT_NO), false);
-  // only DEFAULT_OPT_NO is allowed if target type is TYPE_ID
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_ID), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_KEY), false);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_USER), false);
-
-  // for target type = TYPE_KEY
-  // one can add its own key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_NO),
-                    true);
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, testSigner, DEFAULT_OPT_NO),
-                    true);
-  // one can set its default key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_ID),
-                    true);
-  // non-default key cannot add its own key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, secondSigner, DEFAULT_OPT_NO),
-                    false);
-  // non-default key cannot set its default key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, secondSigner, DEFAULT_OPT_ID),
-                    false);
-  // one can add its child's key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, parentSigner, DEFAULT_OPT_NO),
-                    true);
-  // one can set its child's default key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, parentSigner, DEFAULT_OPT_ID),
-                    true);
-  // non-default key cannot add its child's key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, parentSigner2, DEFAULT_OPT_NO),
-                    false);
-  // non-default parent key cannot set its child's default key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, parentSigner2, DEFAULT_OPT_ID),
-                    false);
-  // DEFAULT_OPT_KEY is not allowed if target type is TYPE_KEY
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_KEY),
-                    false);
-  // DEFAULT_OPT_USER is not allowed if signer is no local management key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_USER),
-                    false);
-
-  // for target type = TYPE_CERT
-  // one can add its own certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_NO),
-                    true);
-  // one can set its own default certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_ID),
-                    true);
-  // one can set its own key's default certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_KEY),
-                    true);
-  // DEFAULT_OPT_USER is not allowed if signer is no local management key
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_USER),
-                    false);
-  // non-default key can add other key's certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, secondSigner, DEFAULT_OPT_NO),
-                    false);
-  // non-default key can add its own certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_NO),
-                    true);
-  // one can add its child's certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, parentSigner, DEFAULT_OPT_NO),
-                    true);
-  // non-default key cannot add its child's certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, parentSigner2, DEFAULT_OPT_NO),
-                    false);
-  // non-default key cannot set add its identity default certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_ID),
-                    false);
-  // non-default key can set add its own default certificate
-  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_KEY),
-                    true);
-}
-
-BOOST_AUTO_TEST_CASE(IsDeleteAllowedTest1)
-{
-  // This test case is to check the access control of local management key
-
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-
-  DeleteQueryProcessor& pro = pib.m_deleteProcessor;
-
-  Name target01("/localhost/pib");
-  Name target02("/localhost/pib/alice/Mgmt");
-  Name target03("/localhost/pib/alice/Mgmt/ok");
-  Name target04("/localhost/pib/alice");
-  Name target05("/test/id");
-  Name target06("/test/id/ksk-123");
-  Name target07("/test/id/KEY/ksk-123/ID-CERT/version");
-  Name signer01 = pib.getMgmtCert().getName().getPrefix(-1);
-  Name signer02("/localhost/pib/bob/Mgmt/KEY/ksk-1234/ID-CERT");
-
-  // TYPE_USER is handled separately
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_USER, target02, signer01), false);
-
-  // Test access control of local management key
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target01, signer01), false);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target02, signer01), false);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target03, signer01), false);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target04, signer01), false);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target05, signer01), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, target06, signer01), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, target07, signer01), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target05, signer02), false);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, target06, signer02), false);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, target07, signer02), false);
-}
-
-BOOST_AUTO_TEST_CASE(IsDeleteAllowedTest2)
-{
-  // This test case is to check the access control of regular key
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  PibDb db(tmpPath.string());
-  DeleteQueryProcessor& pro = pib.m_deleteProcessor;
-
-  Name parent("/test");
-  addIdentity(parent);
-  Name parentCertName = m_keyChain.getDefaultCertificateNameForIdentity(parent);
-  shared_ptr<IdentityCertificate> parentCert = m_keyChain.getCertificate(parentCertName);
-  Name parentSigner = parentCertName.getPrefix(-1);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name parentKeyName2 = m_keyChain.generateRsaKeyPair(parent);
-  shared_ptr<IdentityCertificate> parentCert2 = m_keyChain.selfSign(parentKeyName2);
-  Name parentSigner2 = parentCert2->getName().getPrefix(-1);
-
-  db.addIdentity(parent);
-  db.addKey(parentCert->getPublicKeyName(), parentCert->getPublicKeyInfo());
-  db.addKey(parentCert2->getPublicKeyName(), parentCert2->getPublicKeyInfo());
-  db.setDefaultKeyNameOfIdentity(parentCert->getPublicKeyName());
-  db.addCertificate(*parentCert);
-  db.setDefaultCertNameOfKey(parentCert->getName());
-  db.addCertificate(*parentCert2);
-  db.setDefaultCertNameOfKey(parentCert2->getName());
-
-  Name testId("/test/id");
-  addIdentity(testId);
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(testId);
-  shared_ptr<IdentityCertificate> testCert = m_keyChain.getCertificate(certName);
-  Name testKeyName = testCert->getPublicKeyName();
-  Name testSigner = certName.getPrefix(-1);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name secondKeyName = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> secondCert = m_keyChain.selfSign(secondKeyName);
-  Name secondCertName = secondCert->getName();
-  Name secondSigner = secondCertName.getPrefix(-1);
-
-  db.addIdentity(testId);
-  db.addKey(testKeyName, testCert->getPublicKeyInfo());
-  db.addKey(secondKeyName, secondCert->getPublicKeyInfo());
-  db.setDefaultKeyNameOfIdentity(testKeyName);
-  db.addCertificate(*testCert);
-  db.setDefaultCertNameOfKey(testCert->getName());
-  db.addCertificate(*secondCert);
-  db.setDefaultCertNameOfKey(secondCert->getName());
-
-  Name nonSigner("/non-signer/KEY/ksk-123/ID-CERT");
-
-  // one can delete itself
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, testSigner), true);
-  // parent can delete its child
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, parentSigner), true);
-  // non-default key cannot delete its identity
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, secondSigner), false);
-  // non-default key cannot delete its child
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, parentSigner2), false);
-  // one cannot delete its parent
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, parent, testSigner), false);
-
-  // one can delete its own key
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, testSigner), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, testSigner), true);
-  // parent can delete its child's key
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, parentSigner), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, parentSigner), true);
-  // non-default key cannot delete other key
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, secondSigner), false);
-  // non-default key can delete itself
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, secondSigner), true);
-  // non-default key cannot delete its child's key
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, parentSigner2), false);
-
-  // one can delete its own certificate
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, testSigner), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, testSigner), true);
-  // non-default key cannot delete other's certificate
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, secondSigner), false);
-  // non-default key can delete its own certificate
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, secondSigner), true);
-  // parent can delete its child's certificate
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, parentSigner), true);
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, parentSigner), true);
-  // non-default parent cannot delete its child's certificate
-  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, parentSigner2), false);
-}
-
-
-BOOST_AUTO_TEST_CASE(UpdateUserTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-
-  m_keyChain.addCertificate(pib.getMgmtCert());
-
-  PibDb db(tmpPath.string());
-
-  Name bob("/localhost/pib/bob/mgmt");
-  addIdentity(bob);
-  Name bobCertName = m_keyChain.getDefaultCertificateNameForIdentity(bob);
-  shared_ptr<IdentityCertificate> bobCert = m_keyChain.getCertificate(bobCertName);
-
-  // signer is correct, but user name is wrong, should fall
-  PibUser pibUser1;
-  pibUser1.setMgmtCert(*bobCert);
-  UpdateParam param1(pibUser1);
-  auto interest1 = generateSignedInterest(param1, owner, db.getMgmtCertificate()->getName());
-
-  face.sentData.clear();
-  face.receive(*interest1);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest1->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result;
-  BOOST_REQUIRE_NO_THROW(result.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result.getErrorCode(), ERR_WRONG_PARAM);
-
-  // user name is correct, but signer is wrong, should fail
-  PibUser pibUser2;
-  pibUser2.setMgmtCert(pib.getMgmtCert());
-  UpdateParam param2(pibUser2);
-  auto interest2 = generateSignedInterest(param2, owner, bobCertName);
-
-  face.sentData.clear();
-  face.receive(*interest2);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest2->getName()) == nullptr); // verification should fail, no response
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-
-  // update an existing user with a new mgmt key, signed by the old mgmt key.
-  advanceClocks(io, time::milliseconds(100));
-  Name ownerSecondKeyName =
-    m_keyChain.generateRsaKeyPair(Name("/localhost/pib/alice/mgmt"), false);
-  shared_ptr<IdentityCertificate> ownerSecondCert = m_keyChain.selfSign(ownerSecondKeyName);
-  m_keyChain.addCertificate(*ownerSecondCert);
-
-  PibUser pibUser3;
-  pibUser3.setMgmtCert(*ownerSecondCert);
-  UpdateParam param3(pibUser3);
-  auto interest3 = generateSignedInterest(param3, owner, db.getMgmtCertificate()->getName());
-
-  face.sentData.clear();
-  face.receive(*interest3);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest3->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result3;
-  BOOST_REQUIRE_NO_THROW(result3.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK(db.getMgmtCertificate()->wireEncode() == ownerSecondCert->wireEncode());
-
-  // Add an cert and set it as user default cert.
-  Name testId("/test/id");
-  Name testIdCertName = m_keyChain.createIdentity(testId);
-  shared_ptr<IdentityCertificate> testIdCert = m_keyChain.getCertificate(testIdCertName);
-  Name testIdKeyName = testIdCert->getPublicKeyName();
-  UpdateParam updateParam(*testIdCert, DEFAULT_OPT_USER);
-  auto interest4 = generateSignedInterest(updateParam, owner, ownerSecondCert->getName());
-
-  face.sentData.clear();
-  face.receive(*interest4);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_REQUIRE(cache.find(interest4->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result4;
-  BOOST_REQUIRE_NO_THROW(result4.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
-
-  BOOST_CHECK(pib.getDb().hasCertificate(testIdCertName));
-  BOOST_CHECK(pib.getDb().hasKey(testIdKeyName));
-  BOOST_CHECK(pib.getDb().hasIdentity(testId));
-
-  BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultCertNameOfKey(testIdKeyName));
-  BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultKeyNameOfIdentity(testId));
-  BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultIdentity());
-
-  BOOST_CHECK_EQUAL(pib.getDb().getDefaultCertNameOfKey(testIdKeyName), testIdCertName);
-  BOOST_CHECK_EQUAL(pib.getDb().getDefaultKeyNameOfIdentity(testId), testIdKeyName);
-  BOOST_CHECK_EQUAL(pib.getDb().getDefaultIdentity(), testId);
-}
-
-BOOST_AUTO_TEST_CASE(UpdateRegularKeyTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  PibDb db(tmpPath.string());
-
-  Name id0("/test/identity0");
-  Name certName000 = m_keyChain.createIdentity(id0);
-  shared_ptr<IdentityCertificate> cert000 = m_keyChain.getCertificate(certName000);
-  Name keyName00 = cert000->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert001 = m_keyChain.selfSign(keyName00);
-  Name certName001 = cert001->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name keyName01 = m_keyChain.generateRsaKeyPair(id0);
-  shared_ptr<IdentityCertificate> cert010 = m_keyChain.selfSign(keyName01);
-  Name certName010 = cert010->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert011 = m_keyChain.selfSign(keyName01);
-  Name certName011 = cert011->getName();
-  m_keyChain.addCertificate(*cert010);
-
-  advanceClocks(io, time::milliseconds(100));
-  Name id1("/test/identity1");
-  Name certName100 = m_keyChain.createIdentity(id1);
-  shared_ptr<IdentityCertificate> cert100 = m_keyChain.getCertificate(certName100);
-  Name keyName10 = cert100->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert101 = m_keyChain.selfSign(keyName10);
-  Name certName101 = cert101->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name keyName11 = m_keyChain.generateRsaKeyPair(id1);
-  shared_ptr<IdentityCertificate> cert110 = m_keyChain.selfSign(keyName11);
-  Name certName110 = cert110->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert111 = m_keyChain.selfSign(keyName11);
-  Name certName111 = cert111->getName();
-  m_keyChain.addCertificate(*cert111);
-
-
-  // Add a cert
-  BOOST_CHECK_EQUAL(db.hasIdentity(id0), false);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName00), false);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName000), false);
-  UpdateParam param1(*cert000);
-  auto interest1 = generateSignedInterest(param1, owner, ownerMgmtCert.getName());
-
-  face.sentData.clear();
-  face.receive(*interest1);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest1->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result1;
-  BOOST_REQUIRE_NO_THROW(result1.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result1.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id0), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName00), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName000), true);
-
-  db.addCertificate(*cert100);
-  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName10), true);
-  BOOST_CHECK_EQUAL(db.hasCertificate(certName100), true);
-
-  // Set default
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id0);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id0), keyName00);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName00), certName000);
-
-  UpdateParam param2(id1, DEFAULT_OPT_USER);
-  auto interest2 = generateSignedInterest(param2, owner, ownerMgmtCert.getName());
-
-  face.sentData.clear();
-  face.receive(*interest2);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest2->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result2;
-  BOOST_REQUIRE_NO_THROW(result2.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result2.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
-
-  db.addCertificate(*cert010);
-  UpdateParam param3(keyName01, cert010->getPublicKeyInfo(), DEFAULT_OPT_ID);
-  auto interest3 = generateSignedInterest(param3, owner, ownerMgmtCert.getName());
-
-  face.sentData.clear();
-  face.receive(*interest3);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest3->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result3;
-  BOOST_REQUIRE_NO_THROW(result3.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id0), keyName01);
-
-  db.addCertificate(*cert011);
-  UpdateParam param4(*cert011, DEFAULT_OPT_KEY);
-  auto interest4 = generateSignedInterest(param4, owner, ownerMgmtCert.getName());
-
-  face.sentData.clear();
-  face.receive(*interest4);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest4->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result4;
-  BOOST_REQUIRE_NO_THROW(result4.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName01), certName011);
-
-  // add key and certificate using regular keys.
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
-  UpdateParam param5(keyName11, cert110->getPublicKeyInfo());
-  auto interest5 = generateSignedInterest(param5, owner, cert100->getName());
-
-  face.sentData.clear();
-  face.receive(*interest5);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest5->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result5;
-  BOOST_REQUIRE_NO_THROW(result5.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result5.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
-
-  // add cert using its own key which has been added before
-  BOOST_CHECK_EQUAL(db.hasCertificate(cert101->getName()), false);
-  UpdateParam param6(*cert101);
-  auto interest6 = generateSignedInterest(param6, owner, cert100->getName());
-
-  face.sentData.clear();
-  face.receive(*interest6);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest6->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result6;
-  BOOST_REQUIRE_NO_THROW(result6.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result6.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.hasCertificate(cert101->getName()), true);
-}
-
-BOOST_AUTO_TEST_CASE(DeleteUserTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  PibDb db(tmpPath.string());
-
-  // Delete user should fail
-  DeleteParam param(Name(), TYPE_USER);
-  auto interest = generateSignedInterest(param, owner, ownerMgmtCert.getName());
-
-  face.receive(*interest);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result;
-  BOOST_REQUIRE_NO_THROW(result.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result.getErrorCode(), ERR_WRONG_PARAM);
-}
-
-BOOST_AUTO_TEST_CASE(DeleteRegularKeyTest)
-{
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-  advanceClocks(io, time::milliseconds(10), 10);
-  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  PibDb& db = pib.getDb();
-
-  Name testId("/test/identity");
-  Name testIdCertName00 = m_keyChain.createIdentity(testId);
-  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
-  Name testIdKeyName0 = cert00->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
-  Name testIdCertName01 = cert01->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName10 = cert10->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName11 = cert11->getName();
-  m_keyChain.addCertificate(*cert11);
-
-  db.addCertificate(*cert00);
-  db.addCertificate(*cert01);
-  db.addCertificate(*cert10);
-  db.addCertificate(*cert11);
-  db.setDefaultIdentity(testId);
-  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
-  db.setDefaultCertNameOfKey(testIdCertName00);
-  db.setDefaultCertNameOfKey(testIdCertName10);
-
-  // delete a certificate itself
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
-  DeleteParam param1(testIdCertName11, TYPE_CERT);
-  auto interest1 = generateSignedInterest(param1, owner, testIdCertName11);
-
-  face.sentData.clear();
-  face.receive(*interest1);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest1->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result1;
-  BOOST_REQUIRE_NO_THROW(result1.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result1.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
-
-  // delete a key itself
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
-  DeleteParam param2(testIdKeyName1, TYPE_KEY);
-  auto interest2 = generateSignedInterest(param2, owner, testIdCertName11);
-
-  face.sentData.clear();
-  face.receive(*interest2);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest2->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result2;
-  BOOST_REQUIRE_NO_THROW(result2.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result2.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
-
-  // delete an identity using non-default key, should fail
-  db.addCertificate(*cert11);
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
-  DeleteParam param3(testId, TYPE_ID);
-  auto interest3 = generateSignedInterest(param3, owner, testIdCertName11);
-
-  face.sentData.clear();
-  face.receive(*interest3);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest3->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result3;
-  BOOST_REQUIRE_NO_THROW(result3.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_WRONG_SIGNER);
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
-
-  // delete an identity using identity default key, should succeed
-  DeleteParam param4(testId, TYPE_ID);
-  auto interest4 = generateSignedInterest(param4, owner, testIdCertName00);
-
-  face.sentData.clear();
-  face.receive(*interest4);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  BOOST_CHECK(cache.find(interest4->getName()) != nullptr);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  PibError result4;
-  BOOST_REQUIRE_NO_THROW(result4.wireDecode(face.sentData[0].getContent().blockFromValue()));
-  BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
-  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
-}
-
-BOOST_AUTO_TEST_CASE(ReadCommandTest2)
-{
-  // Read Certificates;
-  owner = "alice";
-
-  Pib pib(face,
-          tmpPath.string(),
-          m_keyChain.getTpm().getTpmLocator(),
-          owner);
-
-  advanceClocks(io, time::milliseconds(10), 100);
-  auto ownerMgmtCert = pib.getMgmtCert();
-  m_keyChain.addCertificate(ownerMgmtCert);
-
-  Name testId("/test/identity");
-  Name testIdCertName00 = m_keyChain.createIdentity(testId);
-  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
-  Name testIdKeyName0 = cert00->getPublicKeyName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
-  Name testIdCertName01 = cert01->getName();
-
-  advanceClocks(io, time::milliseconds(100));
-  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
-  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName10 = cert10->getName();
-  advanceClocks(io, time::milliseconds(100));
-  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
-  Name testIdCertName11 = cert11->getName();
-
-
-  UpdateParam param00(*cert00);
-  UpdateParam param01(*cert01);
-  UpdateParam param10(*cert10);
-  UpdateParam param11(*cert11);
-  auto interest00 = generateSignedInterest(param00, owner, ownerMgmtCert.getName());
-  auto interest01 = generateSignedInterest(param01, owner, ownerMgmtCert.getName());
-  auto interest10 = generateSignedInterest(param10, owner, ownerMgmtCert.getName());
-  auto interest11 = generateSignedInterest(param11, owner, ownerMgmtCert.getName());
-
-  face.sentData.clear();
-  face.receive(*interest00);
-  advanceClocks(io, time::milliseconds(10), 10);
-  face.receive(*interest01);
-  advanceClocks(io, time::milliseconds(10), 10);
-  face.receive(*interest10);
-  advanceClocks(io, time::milliseconds(10), 10);
-  face.receive(*interest11);
-  advanceClocks(io, time::milliseconds(10), 10);
-
-  auto interest1 = make_shared<Interest>(testIdCertName11);
-  face.sentData.clear();
-  face.receive(*interest1);
-  advanceClocks(io, time::milliseconds(10), 10);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK(face.sentData[0].wireEncode() == cert11->wireEncode());
-
-  auto interest2 = make_shared<Interest>(testIdCertName11.getPrefix(-1));
-  face.sentData.clear();
-  face.receive(*interest2);
-  advanceClocks(io, time::milliseconds(10), 10);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK_EQUAL(face.sentData[0].getName().getPrefix(-1),
-                    cert11->getName().getPrefix(-1));
-
-  auto interest3 = make_shared<Interest>(testIdCertName11.getPrefix(-1));
-  pib.getDb().deleteCertificate(testIdCertName11);
-  face.sentData.clear();
-  face.receive(*interest3);
-  advanceClocks(io, time::milliseconds(10), 10);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
-  BOOST_CHECK(face.sentData[0].wireEncode() == cert10->wireEncode());
-
-  auto interest4 = make_shared<Interest>(testIdCertName11);
-  face.sentData.clear();
-  face.receive(*interest4);
-  advanceClocks(io, time::milliseconds(10), 10);
-  BOOST_REQUIRE_EQUAL(face.sentData.size(), 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestPib
-BOOST_AUTO_TEST_SUITE_END() // Pib
-
-} // namespace tests
-} // namespace pib
-} // namespace ndn
diff --git a/tests/pib/response-cache.t.cpp b/tests/pib/response-cache.t.cpp
deleted file mode 100644
index 0a6caaf..0000000
--- a/tests/pib/response-cache.t.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "tools/pib/response-cache.hpp"
-
-#include "tests/test-common.hpp"
-
-namespace ndn {
-namespace pib {
-namespace tests {
-
-BOOST_AUTO_TEST_SUITE(Pib)
-BOOST_AUTO_TEST_SUITE(TestResponseCache)
-
-BOOST_AUTO_TEST_CASE(Basic)
-{
-  ResponseCache cache;
-
-  Name dataName("/test/data");
-  dataName.appendVersion();
-  shared_ptr<Data> data = make_shared<Data>(dataName);
-
-  Name dataNameNoVersion("/test/data");
-  Name anotherDataName("/test/another");
-
-  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataNameNoVersion)), false);
-  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataName, true)), false);
-
-  cache.insert(*data);
-
-  BOOST_CHECK(static_cast<bool>(cache.find(dataNameNoVersion)));
-  BOOST_CHECK(static_cast<bool>(cache.find(dataName, true)));
-  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(anotherDataName)), false);
-  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(anotherDataName, true)), false);
-
-  cache.erase(dataNameNoVersion);
-
-  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataNameNoVersion)), false);
-  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataName, true)), false);
-}
-
-
-BOOST_AUTO_TEST_SUITE_END() // TestResponseCache
-BOOST_AUTO_TEST_SUITE_END() // Pib
-
-} // namespace tests
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/README.md b/tools/pib/README.md
deleted file mode 100644
index 0f87682..0000000
--- a/tools/pib/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# ndn-pib
-
-**ndn-pib** is a service to manage the public information of keys (e.g., identity, public key, and
-certificates). It provides a query interface to local applications for lookup and update this
-information and also publishes certificates in the network.
-
-Usage example:
-
-1. start NFD on local machine
-2. execute `ndn-pib [-h] -o username -d /database/dir -t tpm-locator`
-
-For more information, consult the manpage.
diff --git a/tools/pib/cert-publisher.cpp b/tools/pib/cert-publisher.cpp
deleted file mode 100644
index 890fc7a..0000000
--- a/tools/pib/cert-publisher.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "cert-publisher.hpp"
-
-namespace ndn {
-namespace pib {
-
-CertPublisher::CertPublisher(Face& face, PibDb& db)
-  : m_face(face)
-  , m_db(db)
-{
-  startPublishAll();
-
-  m_certDeletedConnection =
-    m_db.certificateDeleted.connect(bind(&CertPublisher::stopPublish, this, _1));
-  m_certInsertedConnection =
-    m_db.certificateInserted.connect(bind(&CertPublisher::startPublish, this, _1));
-}
-
-CertPublisher::~CertPublisher()
-{
-  for (const auto& it : m_registeredPrefixes)
-    m_face.unsetInterestFilter(it.second);
-}
-
-void
-CertPublisher::startPublishAll()
-{
-  // For now we have to register the prefix of certificates separately.
-  // The reason is that certificates do not share the same prefix that
-  // can aggregate the certificates publishing without attracting interests
-  // for non-PIB data.
-
-  std::vector<Name> identities = m_db.listIdentities();
-
-  for (const auto& identity : identities) {
-    std::vector<Name> keyNames = m_db.listKeyNamesOfIdentity(identity);
-
-    for (const auto& key : keyNames) {
-      std::vector<Name> certNames = m_db.listCertNamesOfKey(key);
-
-      for (const auto& certName : certNames)
-        startPublish(certName);
-    }
-  }
-}
-
-void
-CertPublisher::registerCertPrefix(const Name& certName)
-{
-  BOOST_ASSERT(!certName.empty());
-
-  const Name& prefix = certName.getPrefix(-1);
-
-  if (m_registeredPrefixes.find(prefix) == m_registeredPrefixes.end()) {
-    m_registeredPrefixes[prefix] =
-      m_face.setInterestFilter(certName.getPrefix(-1),
-        bind(&CertPublisher::processInterest, this, _1, _2),
-        [] (const Name& name) {},
-        [=] (const Name& name, const std::string& msg) {
-          if (m_registeredPrefixes.erase(prefix) == 0) {
-            // registration no longer needed - certificates deleted
-            return;
-          }
-          // retry
-          registerCertPrefix(certName);
-        });
-
-  }
-}
-
-void
-CertPublisher::processInterest(const InterestFilter& interestFilter,
-                               const Interest& interest)
-{
-  shared_ptr<const Data> certificate = m_responseCache.find(interest);
-  if (certificate != nullptr) {
-    m_face.put(*certificate);
-  }
-}
-
-void
-CertPublisher::startPublish(const Name& certName)
-{
-  m_responseCache.insert(*m_db.getCertificate(certName));
-  registerCertPrefix(certName);
-}
-
-void
-CertPublisher::stopPublish(const Name& certName)
-{
-  BOOST_ASSERT(!certName.empty());
-
-  m_responseCache.erase(certName);
-
-  // clear the listener if this is the only cert using the prefix
-  const Name& prefix = certName.getPrefix(-1); // strip version component
-
-  if (m_responseCache.find(prefix) != nullptr)
-    return;
-
-  auto it = m_registeredPrefixes.find(prefix);
-  BOOST_ASSERT(it != m_registeredPrefixes.end());
-  m_face.unsetInterestFilter(it->second);
-  m_registeredPrefixes.erase(it);
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/cert-publisher.hpp b/tools/pib/cert-publisher.hpp
deleted file mode 100644
index 14f1597..0000000
--- a/tools/pib/cert-publisher.hpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_CERT_PUBLISHER_HPP
-#define NDN_TOOLS_PIB_CERT_PUBLISHER_HPP
-
-#include "pib-db.hpp"
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
-
-namespace ndn {
-namespace pib {
-
-/// @brief implements the certificate publisher
-class CertPublisher : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param face The face pib used to receive queries and serve certificates.
-   * @param pibDb Database which holds the certificates.
-   */
-  CertPublisher(Face& face, PibDb& pibDb);
-
-  ~CertPublisher();
-
-private:
-  void
-  startPublishAll();
-
-  /**
-   * @brief add an interest filter for the certificate
-   */
-  void
-  registerCertPrefix(const Name& certName);
-
-  void
-  processInterest(const InterestFilter& interestFilter,
-                  const Interest& interest);
-
-  void
-  startPublish(const Name& certName);
-
-  /**
-   * @brief callback when a certificate is deleted
-   *
-   * The method will remove the cert from in-memory storage
-   * and also unset interest filter if the removed cert
-   * is the only one with the registered prefix.
-   *
-   * @param certName removed certificate name
-   */
-  void
-  stopPublish(const Name& certName);
-
-private:
-  Face& m_face;
-  PibDb& m_db;
-  util::InMemoryStoragePersistent m_responseCache;
-  std::map<Name, const RegisteredPrefixId*> m_registeredPrefixes;
-
-  util::signal::ScopedConnection m_certDeletedConnection;
-  util::signal::ScopedConnection m_certInsertedConnection;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_CERT_PUBLISHER_HPP
diff --git a/tools/pib/default-query-processor.cpp b/tools/pib/default-query-processor.cpp
deleted file mode 100644
index 22ec24f..0000000
--- a/tools/pib/default-query-processor.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "default-query-processor.hpp"
-#include "encoding/pib-encoding.hpp"
-
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-using std::string;
-
-const size_t DefaultQueryProcessor::DEFAULT_QUERY_LENGTH = 5;
-
-DefaultQueryProcessor::DefaultQueryProcessor(PibDb& db)
-  : m_db(db)
-{
-}
-
-std::pair<bool, Block>
-DefaultQueryProcessor::operator()(const Interest& interest)
-{
-  const Name& interestName = interest.getName();
-
-  // handle pib query: /localhost/pib/[UserName]/default/param
-  if (interestName.size() != DEFAULT_QUERY_LENGTH) {
-    // malformed interest, discard
-    return std::make_pair(false, Block());
-  }
-
-  DefaultParam param;
-
-  try {
-    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
-  }
-  catch (const tlv::Error& e) {
-    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  switch (param.getTargetType()) {
-  case TYPE_ID:
-    return processDefaultIdQuery(param);
-  case TYPE_KEY:
-    return processDefaultKeyQuery(param);
-  case TYPE_CERT:
-    return processDefaultCertQuery(param);
-  default:
-    {
-      PibError error(ERR_WRONG_PARAM,
-                     "target type is not supported: " +
-                     boost::lexical_cast<string>(param.getTargetType()));
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-}
-
-std::pair<bool, Block>
-DefaultQueryProcessor::processDefaultIdQuery(const DefaultParam& param)
-{
-  if (param.getOriginType() == TYPE_USER) {
-    try {
-      PibIdentity result(m_db.getDefaultIdentity());
-      return std::make_pair(true, result.wireEncode());
-    }
-    catch (PibDb::Error&) {
-      PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-  else {
-    PibError error(ERR_WRONG_PARAM,
-                   "origin type of id target must be USER(0), but gets: " +
-                   boost::lexical_cast<string>(param.getOriginType()));
-    return std::make_pair(true, error.wireEncode());
-  }
-}
-
-std::pair<bool, Block>
-DefaultQueryProcessor::processDefaultKeyQuery(const DefaultParam& param)
-{
-  Name identity;
-  if (param.getOriginType() == TYPE_ID)
-    identity = param.getOriginName();
-  else if (param.getOriginType() == TYPE_USER) {
-    try {
-      identity = m_db.getDefaultIdentity();
-    }
-    catch (PibDb::Error&) {
-      PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-  else {
-    PibError error(ERR_WRONG_PARAM,
-                   "origin type of key target must be ID(1) or USER(0), but gets: " +
-                   boost::lexical_cast<string>(param.getOriginType()));
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  try {
-    Name keyName = m_db.getDefaultKeyNameOfIdentity(identity);
-    shared_ptr<PublicKey> key = m_db.getKey(keyName);
-
-    if (key == nullptr) {
-      PibError error(ERR_NO_DEFAULT_KEY, "default key does not exist");
-      return std::make_pair(true, error.wireEncode());
-    }
-
-    PibPublicKey result(keyName, *key);
-    return std::make_pair(true, result.wireEncode());
-  }
-  catch (PibDb::Error& e) {
-    PibError error(ERR_NO_DEFAULT_KEY,
-                   "default key does not exist: " + string(e.what()));
-    return std::make_pair(true, error.wireEncode());
-  }
-}
-
-std::pair<bool, Block>
-DefaultQueryProcessor::processDefaultCertQuery(const DefaultParam& param)
-{
-  Name identity;
-  if (param.getOriginType() == TYPE_USER) {
-    try {
-      identity = m_db.getDefaultIdentity();
-    }
-    catch (PibDb::Error&) {
-      PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-  else if (param.getOriginType() == TYPE_ID)
-    identity = param.getOriginName();
-  else if (param.getOriginType() != TYPE_KEY) {
-    PibError error(ERR_WRONG_PARAM,
-                   "origin type of cert target must be KEY(2), ID(1) or USER(0), but gets: " +
-                   boost::lexical_cast<string>(param.getOriginType()));
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  Name keyName;
-  if (param.getOriginType() == TYPE_KEY) {
-    keyName = param.getOriginName();
-    if (keyName.size() < 1) {
-      PibError error(ERR_WRONG_PARAM,
-                     "key name must contain key id component");
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-  else {
-    try {
-      keyName = m_db.getDefaultKeyNameOfIdentity(identity);
-    }
-    catch (PibDb::Error&) {
-      PibError error(ERR_NO_DEFAULT_KEY, "default key does not exist");
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-
-  try {
-    Name certName = m_db.getDefaultCertNameOfKey(keyName);
-    shared_ptr<IdentityCertificate> certificate = m_db.getCertificate(certName);
-
-    if (certificate == nullptr) {
-      PibError error (ERR_NO_DEFAULT_CERT, "default cert does not exist");
-      return std::make_pair(true, error.wireEncode());
-    }
-
-    PibCertificate result(*certificate);
-    return std::make_pair(true, result.wireEncode());
-  }
-  catch (PibDb::Error&) {
-    PibError error(ERR_NO_DEFAULT_CERT, "default cert does not exist");
-    return std::make_pair(true, error.wireEncode());
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/default-query-processor.hpp b/tools/pib/default-query-processor.hpp
deleted file mode 100644
index e4a3ff3..0000000
--- a/tools/pib/default-query-processor.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_DEFAULT_QUERY_PROCESSOR_HPP
-#define NDN_TOOLS_PIB_DEFAULT_QUERY_PROCESSOR_HPP
-
-#include "pib-db.hpp"
-#include "encoding/default-param.hpp"
-#include <ndn-cxx/interest.hpp>
-#include <utility>
-
-namespace ndn {
-namespace pib {
-
-class DefaultQueryProcessor : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param db The pib database.
-   */
-  explicit
-  DefaultQueryProcessor(PibDb& db);
-
-  std::pair<bool, Block>
-  operator()(const Interest& interest);
-
-private:
-  std::pair<bool, Block>
-  processDefaultIdQuery(const DefaultParam& param);
-
-  std::pair<bool, Block>
-  processDefaultKeyQuery(const DefaultParam& param);
-
-  std::pair<bool, Block>
-  processDefaultCertQuery(const DefaultParam& param);
-
-private:
-  static const size_t DEFAULT_QUERY_LENGTH;
-
-  const PibDb&  m_db;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_DEFAULT_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/delete-query-processor.cpp b/tools/pib/delete-query-processor.cpp
deleted file mode 100644
index 46f04ea..0000000
--- a/tools/pib/delete-query-processor.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "delete-query-processor.hpp"
-#include "encoding/pib-encoding.hpp"
-#include "pib.hpp"
-
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-using std::string;
-
-const size_t DeleteQueryProcessor::DELETE_QUERY_LENGTH = 9;
-const Name DeleteQueryProcessor::PIB_PREFIX("/localhost/pib");
-
-DeleteQueryProcessor::DeleteQueryProcessor(PibDb& db)
-  : m_db(db)
-{
-}
-
-std::pair<bool, Block>
-DeleteQueryProcessor::operator()(const Interest& interest)
-{
-  const Name& interestName = interest.getName();
-
-  // handle pib query: /localhost/pib/[UserName]/delete/param/<signed_interest_related_components>
-  if (interestName.size() != DELETE_QUERY_LENGTH) {
-    // malformed interest, discard
-    return std::make_pair(false, Block());
-  }
-
-  try {
-    DeleteParam param;
-    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
-
-    SignatureInfo sigInfo;
-    sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
-
-    // sigInfo must have KeyLocator.Name if the interest passed validation.
-    Name signerName;
-    signerName = sigInfo.getKeyLocator().getName();
-
-    switch (param.getTargetType()) {
-    case TYPE_USER:
-      return std::make_pair(true, PibError(ERR_WRONG_PARAM, "not allowed to delete user").wireEncode());
-    case TYPE_ID:
-      return processDeleteIdQuery(param, signerName);
-    case TYPE_KEY:
-      return processDeleteKeyQuery(param, signerName);
-    case TYPE_CERT:
-      return processDeleteCertQuery(param, signerName);
-    default:
-      {
-        PibError error(ERR_WRONG_PARAM,
-                       "target type is not supported: " +
-                       boost::lexical_cast<string>(param.getTargetType()));
-        return std::make_pair(true, error.wireEncode());
-      }
-    }
-  }
-  catch (const PibDb::Error& e) {
-    PibError error(ERR_INTERNAL_ERROR, e.what());
-    return std::make_pair(true, error.wireEncode());
-  }
-  catch (const tlv::Error& e) {
-    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
-    return std::make_pair(true, error.wireEncode());
-  }
-}
-
-std::pair<bool, Block>
-DeleteQueryProcessor::processDeleteIdQuery(const DeleteParam& param, const Name& signerName)
-{
-  Name identity = param.getTargetName();
-  if (!isDeleteAllowed(TYPE_ID, identity, signerName)) {
-    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  m_db.deleteIdentity(identity);
-
-  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-}
-
-std::pair<bool, Block>
-DeleteQueryProcessor::processDeleteKeyQuery(const DeleteParam& param, const Name& signerName)
-{
-  const Name& keyName = param.getTargetName();
-  if (!isDeleteAllowed(TYPE_KEY, keyName, signerName)) {
-    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  m_db.deleteKey(keyName);
-
-  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-}
-
-std::pair<bool, Block>
-DeleteQueryProcessor::processDeleteCertQuery(const DeleteParam& param, const Name& signerName)
-{
-  const Name& certName = param.getTargetName();
-  if (!isDeleteAllowed(TYPE_CERT, certName, signerName)) {
-    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  m_db.deleteCertificate(certName);
-
-  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-}
-
-bool
-DeleteQueryProcessor::isDeleteAllowed(const pib::Type targetType,
-                                      const Name& targetName,
-                                      const Name& signer) const
-{
-  // sanity checking, user cannot be deleted.
-  if (targetType == TYPE_USER)
-    return false;
-
-  // Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
-  // that prefix will be rejected.
-  if (PIB_PREFIX.isPrefixOf(targetName))
-    return false;
-
-  // Rules for other items:
-  //
-  //    signer                   | deleting privilege
-  //    =========================+===============================================
-  //    local mgmt key           | any id, key, and cert
-  //    -------------------------+-----------------------------------------------
-  //    default key of an id     | any id, key, and cert under the id's namespace
-  //    -------------------------+-----------------------------------------------
-  //    non-default key of an id | any cert of the key
-
-  const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
-  const Name& signerId = signerKeyName.getPrefix(-1);
-
-  bool hasSignerDefaultKey = true;
-  Name signerDefaultKeyName;
-  try {
-    signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
-  }
-  catch (PibDb::Error&) {
-    hasSignerDefaultKey = false;
-  }
-
-  Name mgmtCertName;
-  try {
-    mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
-  }
-  catch (PibDb::Error&) {
-    return false;
-  }
-
-  if (signer == mgmtCertName) {
-    // signer is current management key, anything is allowed.
-    return true;
-  }
-  else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
-    // signer is an identity's default key
-    if (!signerId.isPrefixOf(targetName))
-      return false;
-    else
-      return true;
-  }
-  else {
-    // non-default key
-    if (targetType == TYPE_CERT) {
-      // check if it is for the key's cert
-      if (IdentityCertificate::certificateNameToPublicKeyName(targetName) == signerKeyName)
-        return true;
-    }
-    else if (targetType == TYPE_KEY) {
-      // check if it is for the key itself
-      if (targetName == signerKeyName)
-        return true;
-    }
-    return false;
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/delete-query-processor.hpp b/tools/pib/delete-query-processor.hpp
deleted file mode 100644
index 36ea17a..0000000
--- a/tools/pib/delete-query-processor.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_DELETE_QUERY_PROCESSOR_HPP
-#define NDN_TOOLS_PIB_DELETE_QUERY_PROCESSOR_HPP
-
-#include "pib-db.hpp"
-#include "encoding/delete-param.hpp"
-#include <ndn-cxx/interest.hpp>
-#include <utility>
-
-namespace ndn {
-namespace pib {
-
-class Pib;
-
-/// @brief Processing unit for PIB delete query
-class DeleteQueryProcessor : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param db The pib database.
-   */
-  explicit
-  DeleteQueryProcessor(PibDb& db);
-
-  std::pair<bool, Block>
-  operator()(const Interest& interest);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  /**
-   * @brief Determine if a delete command is allowed.
-   *
-   * @param targetType The type of the target that will be deleted.
-   * @param targetName The name of the target that will be deleted.
-   * @param signer     The name of the command signer.
-   */
-  bool
-  isDeleteAllowed(const pib::Type targetType,
-                  const Name& targetName,
-                  const Name& signer) const;
-
-private:
-  std::pair<bool, Block>
-  processDeleteIdQuery(const DeleteParam& param, const Name& signerName);
-
-  std::pair<bool, Block>
-  processDeleteKeyQuery(const DeleteParam& param, const Name& signerName);
-
-  std::pair<bool, Block>
-  processDeleteCertQuery(const DeleteParam& param, const Name& signerName);
-
-private:
-  static const size_t DELETE_QUERY_LENGTH;
-  static const Name PIB_PREFIX;
-
-  PibDb&  m_db;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_DELETE_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/encoding/default-param.cpp b/tools/pib/encoding/default-param.cpp
deleted file mode 100644
index 50c9b4b..0000000
--- a/tools/pib/encoding/default-param.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "default-param.hpp"
-#include <ndn-cxx/encoding/block-helpers.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-static_assert(std::is_base_of<tlv::Error, DefaultParam::Error>::value,
-              "DefaultParam::Error must inherit from tlv::Error");
-
-const std::string DefaultParam::VERB("default");
-
-DefaultParam::DefaultParam()
-  : m_targetType(TYPE_DEFAULT)
-  , m_originType(TYPE_DEFAULT)
-{
-}
-
-DefaultParam::DefaultParam(const pib::Type targetType,
-                           const pib::Type originType,
-                           const Name& originName)
-  : m_targetType(targetType)
-  , m_originType(originType)
-  , m_originName(originName)
-{
-}
-
-DefaultParam::DefaultParam(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-const Name&
-DefaultParam::getOriginName() const
-{
-  if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
-    return m_originName;
-  else
-    throw Error("DefaultParam::getOriginName: origin name does not exist");
-}
-
-template<bool T>
-size_t
-DefaultParam::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  switch (m_originType) {
-  case TYPE_ID:
-  case TYPE_KEY:
-  case TYPE_CERT:
-    {
-      totalLength += m_originName.wireEncode(block);
-      break;
-    }
-  case TYPE_USER:
-    break;
-  default:
-    throw Error("DefaultParam::wireEncode: unsupported PibType: " +
-                boost::lexical_cast<std::string>(m_originType));
-  }
-
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::DefaultParam);
-
-  return totalLength;
-}
-
-template size_t
-DefaultParam::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-DefaultParam::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-DefaultParam::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-DefaultParam::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw Error("The supplied block does not contain wire format");
-  }
-
-  m_wire = wire;
-  m_wire.parse();
-
-  if (m_wire.type() != tlv::pib::DefaultParam)
-    throw Error("Unexpected TLV type when decoding DefaultParam");
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-
-  // the first block must be PibType
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
-    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw Error("DefaultParam requires the first sub-TLV to be PibType");
-
-  // the second block must be PibType
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
-    m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw Error("DefaultParam requires the second sub-TLV to be PibType");
-
-  switch (m_originType) {
-  case TYPE_ID:
-  case TYPE_KEY:
-  case TYPE_CERT:
-    {
-      if (it != m_wire.elements_end()) {
-        // the third block, if exists, must be Name
-        m_originName.wireDecode(*it);
-        return;
-      }
-      else {
-        throw Error("DefaultParam requires the third sub-TLV to be Name");
-      }
-    }
-  case TYPE_USER:
-    return;
-  default:
-    throw Error("DefaultParam::wireDecode: unsupported PibType: " +
-                boost::lexical_cast<std::string>(m_originType));
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/encoding/default-param.hpp b/tools/pib/encoding/default-param.hpp
deleted file mode 100644
index 4c1993a..0000000
--- a/tools/pib/encoding/default-param.hpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_DEFAULT_PARAM_HPP
-#define NDN_TOOLS_PIB_DEFAULT_PARAM_HPP
-
-#include "pib-common.hpp"
-#include <ndn-cxx/name.hpp>
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief DefaultParam is the abstraction of PIB Default parameter.
- *
- *  PibDefaultParam := PIB-DEFAULT-PARAM-TYPE TLV-LENGTH
- *                     PibType    // target type
- *                     PibType    // origin type
- *                     Name?      // origin name
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Default-Parameters
- */
-
-class DefaultParam : noncopyable
-{
-public:
-  class Error : public tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
-  };
-
-  DefaultParam();
-
-  DefaultParam(const pib::Type targetType,
-               const pib::Type originType,
-               const Name& originName = Name());
-
-  explicit
-  DefaultParam(const Block& wire);
-
-  tlv::pib::ParamType
-  getParamType() const
-  {
-    return tlv::pib::DefaultParam;
-  }
-
-  pib::Type
-  getTargetType() const
-  {
-    return m_targetType;
-  }
-
-  pib::Type
-  getOriginType() const
-  {
-    return m_originType;
-  }
-
-  /**
-   * @brief Get target name
-   *
-   * @throws Error if origin name does not exist
-   */
-  const Name&
-  getOriginName() const;
-
-  /// @brief Encode to a wire format or estimate wire format
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  /**
-   * @brief Encode to a wire format
-   *
-   * @throws Error if encoding fails
-   */
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode GetParam from a wire encoded block
-   *
-   * @throws Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-public:
-  static const std::string VERB;
-
-private:
-  pib::Type m_targetType;
-  pib::Type m_originType;
-  Name m_originName;
-
-  mutable Block m_wire;
-};
-
-} // namespace pib
-} // namespace ndn
-
-
-
-#endif // NDN_TOOLS_PIB_DEFAULT_PARAM_HPP
diff --git a/tools/pib/encoding/delete-param.cpp b/tools/pib/encoding/delete-param.cpp
deleted file mode 100644
index 06be21e..0000000
--- a/tools/pib/encoding/delete-param.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "delete-param.hpp"
-#include <ndn-cxx/encoding/block-helpers.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-static_assert(std::is_base_of<tlv::Error, DeleteParam::Error>::value,
-              "DeleteParam::Error must inherit from tlv::Error");
-
-const std::string DeleteParam::VERB("delete");
-
-DeleteParam::DeleteParam()
-  : m_targetType(TYPE_DEFAULT)
-{
-}
-
-DeleteParam::DeleteParam(const Name& name, pib::Type type)
-  : m_targetType(type)
-  , m_targetName(name)
-{
-}
-
-DeleteParam::DeleteParam(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-template<bool T>
-size_t
-DeleteParam::wireEncode(EncodingImpl<T>& block) const
-{
-  if (m_targetType != TYPE_ID &&
-      m_targetType != TYPE_KEY &&
-      m_targetType != TYPE_CERT &&
-      m_targetType != TYPE_USER)
-    throw Error("DeleteParam::wireEncode: Wrong Type value: " +
-                boost::lexical_cast<std::string>(m_targetType));
-
-  size_t totalLength = 0;
-
-  totalLength += m_targetName.wireEncode(block);
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::DeleteParam);
-
-  return totalLength;
-}
-
-template size_t
-DeleteParam::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-DeleteParam::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-DeleteParam::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-DeleteParam::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw Error("The supplied block does not contain wire format");
-  }
-
-  m_wire = wire;
-  m_wire.parse();
-
-  if (m_wire.type() != tlv::pib::DeleteParam)
-    throw Error("Unexpected TLV type when decoding DeleteParam");
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-
-  // the first block must be Type
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
-    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw Error("DeleteParam requires the first sub-TLV to be Type");
-
-  // the second block must be Name
-  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
-    m_targetName.wireDecode(*it);
-    it++;
-  }
-  else
-    throw Error("DeleteParam requires the second sub-TLV to be Name");
-
-  if (it != m_wire.elements_end())
-    throw Error("DeleteParam must not contain more than two sub-TLVs");
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/encoding/delete-param.hpp b/tools/pib/encoding/delete-param.hpp
deleted file mode 100644
index 7fe1081..0000000
--- a/tools/pib/encoding/delete-param.hpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_DELETE_PARAM_HPP
-#define NDN_TOOLS_PIB_DELETE_PARAM_HPP
-
-#include "pib-common.hpp"
-#include <ndn-cxx/name.hpp>
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief DeleteParam is the abstraction of PIB Delete parameter.
- *
- * PibDeleteParam := PIB-DELETE-PARAM-TYPE TLV-LENGTH
- *                   PibType
- *                   Name
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Delete-Parameters
- */
-
-class DeleteParam : noncopyable
-{
-public:
-  class Error : public tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
-  };
-
-  DeleteParam();
-
-  explicit
-  DeleteParam(const Name& name, const pib::Type type = TYPE_ID);
-
-  explicit
-  DeleteParam(const Block& wire);
-
-  tlv::pib::ParamType
-  getParamType() const
-  {
-    return tlv::pib::DeleteParam;
-  }
-
-  pib::Type
-  getTargetType() const
-  {
-    return m_targetType;
-  }
-
-  const Name&
-  getTargetName() const
-  {
-    return m_targetName;
-  }
-
-  /// @brief Encode to a wire format or estimate wire format
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  /**
-   * @brief Encode to a wire format
-   *
-   * @throws Error if encoding fails
-   */
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode GetParam from a wire encoded block
-   *
-   * @throws Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-public:
-  static const std::string VERB;
-
-private:
-  pib::Type m_targetType;
-  Name m_targetName;
-
-  mutable Block m_wire;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_DELETE_PARAM_HPP
diff --git a/tools/pib/encoding/get-param.cpp b/tools/pib/encoding/get-param.cpp
deleted file mode 100644
index 53dd17f..0000000
--- a/tools/pib/encoding/get-param.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "get-param.hpp"
-#include <boost/lexical_cast.hpp>
-#include <ndn-cxx/encoding/block-helpers.hpp>
-
-namespace ndn {
-namespace pib {
-
-static_assert(std::is_base_of<tlv::Error, GetParam::Error>::value,
-              "GetParam::Error must inherit from tlv::Error");
-
-const std::string GetParam::VERB("get");
-
-GetParam::GetParam()
-  : m_targetType(TYPE_USER)
-{
-}
-
-GetParam::GetParam(const pib::Type targetType, const Name& targetName)
-  : m_targetType(targetType)
-  , m_targetName(targetName)
-{
-}
-
-GetParam::GetParam(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-const Name&
-GetParam::getTargetName() const
-{
-  if (m_targetType == TYPE_ID || m_targetType == TYPE_KEY || m_targetType == TYPE_CERT)
-    return m_targetName;
-  else
-    throw Error("GetParam::getTargetName: target name does not exist");
-}
-
-template<bool T>
-size_t
-GetParam::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  switch (m_targetType) {
-  case TYPE_ID:
-  case TYPE_KEY:
-  case TYPE_CERT:
-    {
-      totalLength += m_targetName.wireEncode(block);
-      break;
-    }
-  case TYPE_USER:
-    break;
-  default:
-    throw Error("GetParam::wireEncode: unsupported PibType: " +
-                boost::lexical_cast<std::string>(m_targetType));
-  }
-
-  // Encode Type
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::GetParam);
-
-  return totalLength;
-}
-
-template size_t
-GetParam::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-GetParam::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-GetParam::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-GetParam::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw Error("The supplied block does not contain wire format");
-  }
-
-  m_wire = wire;
-  m_wire.parse();
-
-  if (m_wire.type() != tlv::pib::GetParam)
-    throw Error("Unexpected TLV type when decoding GetParam");
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-
-  // the first block must be Type
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
-    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw Error("GetParam requires the first sub-TLV to be PibType");
-
-  switch (m_targetType) {
-  case TYPE_ID:
-  case TYPE_KEY:
-  case TYPE_CERT:
-    {
-      if (it != m_wire.elements_end()) {
-        // the second block, if exists, must be Name
-        m_targetName.wireDecode(*it);
-        return;
-      }
-      else {
-        throw Error("GetParam requires the second sub-TLV to be Name");
-      }
-    }
-  case TYPE_USER:
-    return;
-  default:
-    throw Error("GetParam::wireDecode: unsupported PibType: " +
-                boost::lexical_cast<std::string>(m_targetType));
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/encoding/get-param.hpp b/tools/pib/encoding/get-param.hpp
deleted file mode 100644
index a22d0c4..0000000
--- a/tools/pib/encoding/get-param.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_GET_PARAM_HPP
-#define NDN_TOOLS_PIB_GET_PARAM_HPP
-
-#include "pib-common.hpp"
-#include <ndn-cxx/name.hpp>
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief GetParam is the abstraction of PIB Get parameter.
- *
- * PibGetParam := PIB-GET-PARAM-TYPE TLV-LENGTH
- *                PibType
- *                Name?
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Get-Parameters
- */
-
-class GetParam : noncopyable
-{
-public:
-  class Error : public tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
-  };
-
-  GetParam();
-
-  GetParam(const pib::Type targetType, const Name& targetName);
-
-  explicit
-  GetParam(const Block& wire);
-
-  tlv::pib::ParamType
-  getParamType() const
-  {
-    return tlv::pib::GetParam;
-  }
-
-  pib::Type
-  getTargetType() const
-  {
-    return m_targetType;
-  }
-
-  /**
-   * @brief Get target name
-   *
-   * @throws Error if target name does not exist
-   */
-  const Name&
-  getTargetName() const;
-
-  /// @brief Encode to a wire format or estimate wire format
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  /**
-   * @brief Encode to a wire format
-   *
-   * @throws Error if encoding fails
-   */
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode GetParam from a wire encoded block
-   *
-   * @throws Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-public:
-  static const std::string VERB;
-
-private:
-  pib::Type m_targetType;
-  Name m_targetName;
-
-  mutable Block m_wire;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_GET_PARAM_HPP
diff --git a/tools/pib/encoding/list-param.cpp b/tools/pib/encoding/list-param.cpp
deleted file mode 100644
index 1f5c63b..0000000
--- a/tools/pib/encoding/list-param.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "list-param.hpp"
-#include <ndn-cxx/encoding/block-helpers.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-static_assert(std::is_base_of<tlv::Error, ListParam::Error>::value,
-              "ListParam::Error must inherit from tlv::Error");
-
-const std::string ListParam::VERB("list");
-
-ListParam::ListParam()
-  : m_originType(TYPE_USER)
-{
-}
-
-ListParam::ListParam(const pib::Type originType, const Name& originName)
-  : m_originType(originType)
-  , m_originName(originName)
-{
-}
-
-ListParam::ListParam(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-const Name&
-ListParam::getOriginName() const
-{
-  if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
-    return m_originName;
-  else
-    throw Error("ListParam::getOriginName: origin name does not exist");
-}
-
-template<bool T>
-size_t
-ListParam::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  switch (m_originType) {
-  case TYPE_ID:
-  case TYPE_KEY:
-  case TYPE_CERT:
-    {
-      totalLength += m_originName.wireEncode(block);
-      break;
-    }
-  case TYPE_USER:
-    break;
-  default:
-    throw Error("ListParam::wireEncode: unsupported PibType: " +
-                boost::lexical_cast<std::string>(m_originType));
-  }
-
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::ListParam);
-
-  return totalLength;
-}
-
-template size_t
-ListParam::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-ListParam::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-ListParam::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-ListParam::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw Error("The supplied block does not contain wire format");
-  }
-
-  m_wire = wire;
-  m_wire.parse();
-
-  if (m_wire.type() != tlv::pib::ListParam)
-    throw Error("Unexpected TLV type when decoding ListParam");
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-
-  // the first block must be PibType
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
-    m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw Error("ListParam requires the first sub-TLV to be PibType");
-
-  switch (m_originType) {
-  case TYPE_ID:
-  case TYPE_KEY:
-  case TYPE_CERT:
-    {
-      if (it != m_wire.elements_end()) {
-        // the second block, if exists, must be Name
-        m_originName.wireDecode(*it);
-        return;
-      }
-      else {
-        throw Error("ListParam requires the second sub-TLV to be Name");
-      }
-    }
-  case TYPE_USER:
-    return;
-  default:
-    throw Error("ListParam::wireDecode: unsupported PibType: " +
-                boost::lexical_cast<std::string>(m_originType));
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/encoding/list-param.hpp b/tools/pib/encoding/list-param.hpp
deleted file mode 100644
index 0e7cce1..0000000
--- a/tools/pib/encoding/list-param.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_LIST_PARAM_HPP
-#define NDN_TOOLS_PIB_LIST_PARAM_HPP
-
-#include "pib-common.hpp"
-#include <ndn-cxx/name.hpp>
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief ListParam is the abstraction of PIB List parameter.
- *
- *  PibListParam := PIB-LIST-PARAM-TYPE TLV-LENGTH
- *                  PibType    // origin type
- *                  Name?      // origin name
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
- */
-
-class ListParam : noncopyable
-{
-public:
-  class Error : public tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
-  };
-
-  ListParam();
-
-  ListParam(const pib::Type originType, const Name& originName);
-
-  explicit
-  ListParam(const Block& wire);
-
-  tlv::pib::ParamType
-  getParamType() const
-  {
-    return tlv::pib::ListParam;
-  }
-
-  pib::Type
-  getOriginType() const
-  {
-    return m_originType;
-  }
-
-  /**
-   * @brief Get target name
-   *
-   * @throws Error if origin name does not exist
-   */
-  const Name&
-  getOriginName() const;
-
-  /// @brief Encode to a wire format or estimate wire format
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  /**
-   * @brief Encode to a wire format
-   *
-   * @throws Error if encoding fails
-   */
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode GetParam from a wire encoded block
-   *
-   * @throws Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-public:
-  static const std::string VERB;
-
-private:
-  pib::Type m_originType;
-  Name m_originName;
-
-  mutable Block m_wire;
-};
-
-} // namespace pib
-} // namespace ndn
-
-
-
-#endif // NDN_TOOLS_PIB_LIST_PARAM_HPP
diff --git a/tools/pib/encoding/pib-common.hpp b/tools/pib/encoding/pib-common.hpp
deleted file mode 100644
index 3e29771..0000000
--- a/tools/pib/encoding/pib-common.hpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_PIB_COMMON_HPP
-#define NDN_TOOLS_PIB_PIB_COMMON_HPP
-
-namespace ndn {
-namespace pib {
-
-/// @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
-
-enum {
-  OFFSET_USER              = 2,
-  OFFSET_VERB              = 3,
-  OFFSET_PARAM             = 4,
-  OFFSET_TIMESTAMP         = 5,
-  OFFSET_NONCE             = 6,
-  OFFSET_SIG_INFO          = 7,
-  OFFSET_SIG_VALUE         = 8,
-
-  MIN_PIB_INTEREST_SIZE    = 5,
-  SIGNED_PIB_INTEREST_SIZE = 9
-};
-
-enum Type {
-  TYPE_USER    = 0,
-  TYPE_ID      = 1,
-  TYPE_KEY     = 2,
-  TYPE_CERT    = 3,
-  TYPE_DEFAULT = 255
-};
-
-enum DefaultOpt {
-  DEFAULT_OPT_NO   = 0,
-  DEFAULT_OPT_KEY  = 1, // 0x01
-  DEFAULT_OPT_ID   = 3, // 0x03
-  DEFAULT_OPT_USER = 7 // 0x07
-};
-
-enum DefaultOptMask {
-  DEFAULT_OPT_KEY_MASK  = 0x1,
-  DEFAULT_OPT_ID_MASK   = 0x2,
-  DEFAULT_OPT_USER_MASK = 0x4
-};
-
-enum ErrCode {
-  ERR_SUCCESS = 0,
-
-  // Invalid query
-  ERR_INCOMPLETE_COMMAND = 1,
-  ERR_WRONG_VERB         = 2,
-  ERR_WRONG_PARAM        = 3,
-  ERR_WRONG_SIGNER       = 4,
-  ERR_INTERNAL_ERROR     = 5,
-
-  // Non existing entity
-  ERR_NON_EXISTING_USER = 128,
-  ERR_NON_EXISTING_ID   = 129,
-  ERR_NON_EXISTING_KEY  = 130,
-  ERR_NON_EXISTING_CERT = 131,
-
-  // No default setting
-  ERR_NO_DEFAULT_ID     = 256,
-  ERR_NO_DEFAULT_KEY    = 257,
-  ERR_NO_DEFAULT_CERT   = 258,
-
-  // Delete default setting
-  ERR_DELETE_DEFAULT_SETTING = 384
-};
-
-} // namespace pib
-
-
-namespace tlv {
-namespace pib {
-
-enum ParamType {
-  GetParam          = 128, // 0x80
-  DefaultParam      = 129, // 0x81
-  ListParam         = 130, // 0x82
-  UpdateParam       = 131, // 0x83
-  DeleteParam       = 132  // 0x84
-};
-
-enum EntityType {
-  User              = 144, // 0x90
-  Identity          = 145, // 0x91
-  PublicKey         = 146, // 0x92
-  Certificate       = 147  // 0x93
-};
-
-// Other
-enum {
-  Bytes             = 148, // 0x94
-  DefaultOpt        = 149, // 0x95
-  NameList          = 150, // 0x96
-  Type              = 151, // 0x97
-  Error             = 152, // 0x98
-  TpmLocator        = 153, // 0x99
-
-  // ErrorCode
-  ErrorCode         = 252  // 0xfc
-};
-
-} // namespace pib
-} // namespace tlv
-} // namespace ndn
-
-
-#endif // NDN_TOOLS_PIB_PIB_COMMON_HPP
diff --git a/tools/pib/encoding/pib-encoding.cpp b/tools/pib/encoding/pib-encoding.cpp
deleted file mode 100644
index 559e1aa..0000000
--- a/tools/pib/encoding/pib-encoding.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "pib-encoding.hpp"
-#include <ndn-cxx/encoding/block-helpers.hpp>
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <vector>
-#include <string>
-
-namespace ndn {
-namespace pib {
-
-using std::vector;
-using std::string;
-
-PibIdentity::PibIdentity()
-{
-}
-
-PibIdentity::PibIdentity(const Name& identity)
-  : m_identity(identity)
-{
-}
-
-PibIdentity::PibIdentity(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-template<bool T>
-size_t
-PibIdentity::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = m_identity.wireEncode(block);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::Identity);
-
-  return totalLength;
-}
-
-template size_t
-PibIdentity::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-PibIdentity::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-PibIdentity::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-PibIdentity::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw tlv::Error("The supplied block does not contain wire format");
-  }
-
-  if (wire.type() != tlv::pib::Identity)
-    throw tlv::Error("Unexpected TLV type when decoding PibIdentity");
-
-  m_wire = wire;
-  m_identity.wireDecode(m_wire.blockFromValue());
-}
-
-
-
-PibPublicKey::PibPublicKey()
-  : m_isValueSet(false)
-{
-}
-
-PibPublicKey::PibPublicKey(const Name& keyName, const PublicKey& key)
-  : m_isValueSet(true)
-  , m_keyName(keyName)
-  , m_key(key)
-{
-}
-
-PibPublicKey::PibPublicKey(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-const Name&
-PibPublicKey::getKeyName() const
-{
-  if (m_isValueSet)
-    return m_keyName;
-  else
-    throw tlv::Error("PibPublicKey::getKeyName: keyName is not set");
-}
-
-const PublicKey&
-PibPublicKey::getPublicKey() const
-{
-  if (m_isValueSet)
-    return m_key;
-  else
-    throw tlv::Error("PibPublicKey::getPublicKey: key is not set");
-}
-
-template<bool T>
-size_t
-PibPublicKey::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = block.prependByteArrayBlock(tlv::pib::Bytes,
-                                                   m_key.get().buf(), m_key.get().size());
-  totalLength += m_keyName.wireEncode(block);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::PublicKey);
-
-  return totalLength;
-}
-
-template size_t
-PibPublicKey::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-PibPublicKey::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-PibPublicKey::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-PibPublicKey::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw tlv::Error("The supplied block does not contain wire format");
-  }
-
-  if (wire.type() != tlv::pib::PublicKey)
-    throw tlv::Error("Unexpected TLV type when decoding PibPublicKey");
-
-  m_wire = wire;
-  m_wire.parse();
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
-    m_keyName.wireDecode(*it);
-    it++;
-  }
-  else
-    throw tlv::Error("PibPublicKey requires the first sub-TLV to be Name");
-
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
-    m_key = PublicKey(it->value(), it->value_size());
-    it++;
-  }
-  else
-    throw tlv::Error("PibPublicKey requires the second sub-TLV to be Bytes");
-
-  m_isValueSet = true;
-  if (it != m_wire.elements_end())
-    throw tlv::Error("PibPublicKey must contain only two sub-TLVs");
-}
-
-
-PibCertificate::PibCertificate()
-  : m_isValueSet(false)
-{
-}
-
-PibCertificate::PibCertificate(const IdentityCertificate& certificate)
-  : m_isValueSet(true)
-  , m_certificate(certificate)
-{
-}
-
-PibCertificate::PibCertificate(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-const IdentityCertificate&
-PibCertificate::getCertificate() const
-{
-  if (m_isValueSet)
-    return m_certificate;
-  else
-    throw tlv::Error("PibCertificate::getCertificate: certificate is not set");
-}
-
-template<bool T>
-size_t
-PibCertificate::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = block.prependBlock(m_certificate.wireEncode());
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::Certificate);
-
-  return totalLength;
-}
-
-template size_t
-PibCertificate::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-PibCertificate::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-PibCertificate::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-PibCertificate::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw tlv::Error("The supplied block does not contain wire format");
-  }
-
-  if (wire.type() != tlv::pib::Certificate)
-    throw tlv::Error("Unexpected TLV type when decoding PibCertificate");
-
-  m_wire = wire;
-  m_certificate.wireDecode(m_wire.blockFromValue());
-
-  m_isValueSet = true;
-}
-
-
-PibNameList::PibNameList()
-{
-}
-
-PibNameList::PibNameList(const std::vector<Name>& names)
-  : m_names(names)
-{
-}
-
-PibNameList::PibNameList(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-template<bool T>
-size_t
-PibNameList::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  for (vector<Name>::const_reverse_iterator it = m_names.rbegin();
-       it != m_names.rend(); it++) {
-    totalLength += it->wireEncode(block);
-  }
-
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::NameList);
-  return totalLength;
-}
-
-template size_t
-PibNameList::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-PibNameList::wireEncode<false>(EncodingImpl<false>& block) const;
-
-
-const Block&
-PibNameList::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-PibNameList::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw tlv::Error("The supplied block does not contain wire format");
-  }
-
-  if (wire.type() != tlv::pib::NameList)
-    throw tlv::Error("Unexpected TLV type when decoding PibNameList");
-
-  m_wire = wire;
-  m_wire.parse();
-  for (Block::element_const_iterator it = m_wire.elements_begin();
-       it != m_wire.elements_end(); it++) {
-    if (it->type() == tlv::Name) {
-      Name name;
-      name.wireDecode(*it);
-      m_names.push_back(name);
-    }
-  }
-}
-
-PibError::PibError()
-  : m_errCode(ERR_SUCCESS)
-{
-}
-
-PibError::PibError(const pib::ErrCode errCode, const std::string& msg)
-  : m_errCode(errCode)
-  , m_msg(msg)
-{
-}
-
-PibError::PibError(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-template<bool T>
-size_t
-PibError::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-  totalLength += block.prependByteArrayBlock(tlv::pib::Bytes,
-                                             reinterpret_cast<const uint8_t*>(m_msg.c_str()),
-                                             m_msg.size());
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::ErrorCode, m_errCode);
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::Error);
-  return totalLength;
-}
-
-template size_t
-PibError::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-PibError::wireEncode<false>(EncodingImpl<false>& block) const;
-
-
-const Block&
-PibError::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-PibError::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw tlv::Error("The supplied block does not contain wire format");
-  }
-
-  if (wire.type() != tlv::pib::Error)
-    throw tlv::Error("Unexpected TLV type when decoding Error");
-
-  m_wire = wire;
-  m_wire.parse();
-  Block::element_const_iterator it = m_wire.elements_begin();
-
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::ErrorCode) {
-    m_errCode = static_cast<pib::ErrCode>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw tlv::Error("PibError requires the first sub-TLV to be ErrorCode");
-
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
-    m_msg = string(reinterpret_cast<const char*>(it->value()), it->value_size());
-    it++;
-  }
-  else
-    throw tlv::Error("PibError requires the second sub-TLV to be Bytes");
-}
-
-PibUser::PibUser()
-{
-}
-
-PibUser::PibUser(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-void
-PibUser::setMgmtCert(const IdentityCertificate& mgmtCert)
-{
-  m_wire.reset();
-  m_mgmtCert = mgmtCert;
-}
-
-void
-PibUser::setTpmLocator(const std::string& tpmLocator)
-{
-  m_wire.reset();
-  m_tpmLocator = tpmLocator;
-}
-
-template<bool T>
-size_t
-PibUser::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  if (!m_tpmLocator.empty())
-    totalLength = block.prependByteArrayBlock(tlv::pib::TpmLocator,
-                                              reinterpret_cast<const uint8_t*>(m_tpmLocator.c_str()),
-                                              m_tpmLocator.size());
-
-  totalLength += block.prependBlock(m_mgmtCert.wireEncode());
-
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::User);
-
-  return totalLength;
-}
-
-template size_t
-PibUser::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-PibUser::wireEncode<false>(EncodingImpl<false>& block) const;
-
-
-const Block&
-PibUser::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-PibUser::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw tlv::Error("The supplied block does not contain wire format");
-  }
-
-  if (wire.type() != tlv::pib::User)
-    throw tlv::Error("Unexpected TLV type when decoding Content");
-
-  m_wire = wire;
-  m_wire.parse();
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-  if (it != m_wire.elements_end() && it->type() == tlv::Data) {
-    m_mgmtCert.wireDecode(*it);
-    it++;
-  }
-  else
-    throw tlv::Error("PibError requires the first sub-TLV to be Data");
-
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::TpmLocator) {
-    m_tpmLocator = string(reinterpret_cast<const char*>(it->value()), it->value_size());
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/encoding/pib-encoding.hpp b/tools/pib/encoding/pib-encoding.hpp
deleted file mode 100644
index 458348f..0000000
--- a/tools/pib/encoding/pib-encoding.hpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_PIB_ENCODING_HPP
-#define NDN_TOOLS_PIB_PIB_ENCODING_HPP
-
-#include "pib-common.hpp"
-#include <ndn-cxx/security/identity-certificate.hpp>
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief Abstraction of pib::Identity TLV.
- *
- * This class is copyable since it is used by a variety of pib parameters
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
- */
-class PibIdentity
-{
-public:
-  PibIdentity();
-
-  explicit
-  PibIdentity(const Name& identity);
-
-  explicit
-  PibIdentity(const Block& wire);
-
-  const Name&
-  getIdentity() const
-  {
-    return m_identity;
-  }
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode PibIdentity from a wire encoded block
-   *
-   * @throws tlv::Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-private:
-  Name m_identity;
-
-  mutable Block m_wire;
-};
-
-/**
- * @brief Abstraction of pib::PublicKey TLV.
- *
- * This class is copyable since it is used by a variety of pib parameters
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
- */
-class PibPublicKey
-{
-public:
-  PibPublicKey();
-
-  PibPublicKey(const Name& keyName, const PublicKey& key);
-
-  explicit
-  PibPublicKey(const Block& wire);
-
-  const Name&
-  getKeyName() const;
-
-  const PublicKey&
-  getPublicKey() const;
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode PibPublicKey from a wire encoded block
-   *
-   * @throws tlv::Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-private:
-  bool m_isValueSet;
-  Name m_keyName;
-  PublicKey m_key;
-
-  mutable Block m_wire;
-};
-
-/**
- * @brief Abstraction of pib::Certificate TLV.
- *
- * This class is copyable since it is used by a variety of pib parameters
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
- */
-class PibCertificate
-{
-public:
-  PibCertificate();
-
-  explicit
-  PibCertificate(const IdentityCertificate& certificate);
-
-  explicit
-  PibCertificate(const Block& wire);
-
-  const IdentityCertificate&
-  getCertificate() const;
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode PibCertificate from a wire encoded block
-   *
-   * @throws tlv::Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-private:
-  bool m_isValueSet;
-  IdentityCertificate m_certificate;
-
-  mutable Block m_wire;
-};
-
-/**
- * @brief Abstraction of pib::NameList TLV.
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
- */
-class PibNameList : noncopyable
-{
-public:
-  PibNameList();
-
-  explicit
-  PibNameList(const std::vector<Name>& names);
-
-  explicit
-  PibNameList(const Block& wire);
-
-  const std::vector<Name>&
-  getNameList() const
-  {
-    return m_names;
-  }
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode PibCertificate from a wire encoded block
-   *
-   * @throws tlv::Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-private:
-  std::vector<Name> m_names;
-
-  mutable Block m_wire;
-};
-
-/**
- * @brief Abstraction of pib::Error TLV.
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
- */
-class PibError : noncopyable
-{
-public:
-  PibError();
-
-  explicit
-  PibError(const pib::ErrCode errCode, const std::string& msg = "");
-
-  explicit
-  PibError(const Block& wire);
-
-  pib::ErrCode
-  getErrorCode() const
-  {
-    return m_errCode;
-  }
-
-  const std::string&
-  getErrorMsg() const
-  {
-    return m_msg;
-  }
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode PibCertificate from a wire encoded block
-   *
-   * @throws tlv::Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-private:
-  pib::ErrCode m_errCode;
-  std::string m_msg;
-
-  mutable Block m_wire;
-};
-
-/**
- * @brief Abstraction of pib::User TLV.
- *
- * This class is copyable since it is used by a variety of pib parameters
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
- */
-class PibUser
-{
-public:
-  PibUser();
-
-  explicit
-  PibUser(const Block& wire);
-
-  void
-  setMgmtCert(const IdentityCertificate& mgmtCert);
-
-  const IdentityCertificate&
-  getMgmtCert() const
-  {
-    return m_mgmtCert;
-  }
-
-  void
-  setTpmLocator(const std::string& tpmLocator);
-
-  const std::string&
-  getTpmLocator() const
-  {
-    return m_tpmLocator;
-  }
-
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode PibCertificate from a wire encoded block
-   *
-   * @throws tlv::Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-private:
-  IdentityCertificate m_mgmtCert;
-  std::string m_tpmLocator;
-
-  mutable Block m_wire;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_PIB_ENCODING_HPP
diff --git a/tools/pib/encoding/update-param.cpp b/tools/pib/encoding/update-param.cpp
deleted file mode 100644
index d5b7041..0000000
--- a/tools/pib/encoding/update-param.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "update-param.hpp"
-#include <ndn-cxx/encoding/block-helpers.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-static_assert(std::is_base_of<tlv::Error, UpdateParam::Error>::value,
-              "UpdateParam::Error must inherit from tlv::Error");
-
-const std::string UpdateParam::VERB("update");
-
-UpdateParam::UpdateParam()
-  : m_defaultOpt(DEFAULT_OPT_NO)
-{
-}
-
-UpdateParam::UpdateParam(const PibUser& user)
-  : m_entityType(tlv::pib::User)
-  , m_user(user)
-  , m_defaultOpt(DEFAULT_OPT_NO)
-{
-}
-
-UpdateParam::UpdateParam(const Name& identity, DefaultOpt defaultOpt)
-  : m_entityType(tlv::pib::Identity)
-  , m_identity(identity)
-  , m_defaultOpt(defaultOpt)
-{
-}
-
-UpdateParam::UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt)
-  : m_entityType(tlv::pib::PublicKey)
-  , m_key(keyName, key)
-  , m_defaultOpt(defaultOpt)
-{
-}
-
-UpdateParam::UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt)
-  : m_entityType(tlv::pib::Certificate)
-  , m_certificate(certificate)
-  , m_defaultOpt(defaultOpt)
-{
-}
-
-UpdateParam::UpdateParam(const Block& wire)
-{
-  wireDecode(wire);
-}
-
-const PibUser&
-UpdateParam::getUser() const
-{
-  if (m_entityType == tlv::pib::User)
-      return m_user;
-  else
-    throw Error("UpdateParam::getUser: entityType must be User");
-}
-
-const PibIdentity&
-UpdateParam::getIdentity() const
-{
-  if (m_entityType == tlv::pib::Identity)
-    return m_identity;
-  else
-    throw Error("UpdateParam::getIdentity: entityType must be Identity");
-}
-
-const PibPublicKey&
-UpdateParam::getPublicKey() const
-{
-  if (m_entityType == tlv::pib::PublicKey)
-    return m_key;
-  else
-    throw Error("UpdateParam::getPublicKey: entityType must be PublicKey");
-}
-
-const PibCertificate&
-UpdateParam::getCertificate() const
-{
-  if (m_entityType == tlv::pib::Certificate)
-    return m_certificate;
-  else
-    throw Error("UpdateParam::getCertificate: entityType must be Certificate");
-}
-
-template<bool T>
-size_t
-UpdateParam::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::DefaultOpt, m_defaultOpt);
-
-  // Encode Entity
-  switch (m_entityType) {
-  case tlv::pib::Identity:
-    {
-      totalLength += m_identity.wireEncode(block);
-      break;
-    }
-  case tlv::pib::PublicKey:
-    {
-      totalLength += m_key.wireEncode(block);
-      break;
-    }
-  case tlv::pib::Certificate:
-    {
-      totalLength += m_certificate.wireEncode(block);
-      break;
-    }
-  case tlv::pib::User:
-    {
-      totalLength += m_user.wireEncode(block);
-      break;
-    }
-  default:
-    throw Error("UpdateParam::wireEncode: unsupported entity type: " +
-                boost::lexical_cast<std::string>(m_entityType));
-  }
-
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(tlv::pib::UpdateParam);
-
-  return totalLength;
-}
-
-template size_t
-UpdateParam::wireEncode<true>(EncodingImpl<true>& block) const;
-
-template size_t
-UpdateParam::wireEncode<false>(EncodingImpl<false>& block) const;
-
-const Block&
-UpdateParam::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-void
-UpdateParam::wireDecode(const Block& wire)
-{
-  if (!wire.hasWire()) {
-    throw Error("The supplied block does not contain wire format");
-  }
-
-  m_wire = wire;
-  m_wire.parse();
-
-  if (m_wire.type() != tlv::pib::UpdateParam)
-    throw Error("Unexpected TLV type when decoding UpdateParam");
-
-  Block::element_const_iterator it = m_wire.elements_begin();
-
-  // the first block must be Entity
-  if (it != m_wire.elements_end()) {
-    switch (it->type()) {
-    case tlv::pib::Identity:
-      {
-        m_entityType = tlv::pib::Identity;
-        m_identity.wireDecode(*it);
-        break;
-      }
-    case tlv::pib::PublicKey:
-      {
-        m_entityType = tlv::pib::PublicKey;
-        m_key.wireDecode(*it);
-        break;
-      }
-    case tlv::pib::Certificate:
-      {
-        m_entityType = tlv::pib::Certificate;
-        m_certificate.wireDecode(*it);
-        break;
-      }
-    case tlv::pib::User:
-      {
-        m_entityType = tlv::pib::User;
-        m_user.wireDecode(*it);
-        break;
-      }
-    default:
-      throw Error("The first sub-TLV of UpdateParam is not an entity type");
-    }
-
-    it++;
-  }
-  else
-    throw Error("UpdateParam requires the first sub-TLV to be an entity type");
-
-  // the second block must be DefaultOpt
-  if (it != m_wire.elements_end() && it->type() == tlv::pib::DefaultOpt) {
-    m_defaultOpt = static_cast<pib::DefaultOpt>(readNonNegativeInteger(*it));
-    it++;
-  }
-  else
-    throw Error("UpdateParam requires the second sub-TLV to be DefaultOpt");
-
-  if (it != m_wire.elements_end())
-    throw Error("UpdateParam must not contain more than two sub-TLVs");
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/encoding/update-param.hpp b/tools/pib/encoding/update-param.hpp
deleted file mode 100644
index 739faf9..0000000
--- a/tools/pib/encoding/update-param.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_UPDATE_PARAM_HPP
-#define NDN_TOOLS_PIB_UPDATE_PARAM_HPP
-
-#include "pib-common.hpp"
-#include "pib-encoding.hpp"
-#include <ndn-cxx/name.hpp>
-#include <ndn-cxx/security/identity-certificate.hpp>
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief UpdateParam is the abstraction of PIB Update parameter.
- *
- * PibUpdateParam := PIB-UPDATE-PARAM-TYPE TLV-LENGTH
- *                   (PibIdentity | PibPublicKey | PibCertificate)
- *                   PibDefaultOpt
- *
- * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Update-Parameters
- */
-
-class UpdateParam : noncopyable
-{
-public:
-  class Error : public tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
-  };
-
-  UpdateParam();
-
-  explicit
-  UpdateParam(const PibUser& user);
-
-  explicit
-  UpdateParam(const Name& identity, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
-
-  UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
-
-  explicit
-  UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
-
-  explicit
-  UpdateParam(const Block& wire);
-
-  tlv::pib::ParamType
-  getParamType() const
-  {
-    return tlv::pib::UpdateParam;
-  }
-
-  tlv::pib::EntityType
-  getEntityType() const
-  {
-    return m_entityType;
-  }
-
-  const PibUser&
-  getUser() const;
-
-  const PibIdentity&
-  getIdentity() const;
-
-  const PibPublicKey&
-  getPublicKey() const;
-
-  const PibCertificate&
-  getCertificate() const;
-
-  pib::DefaultOpt
-  getDefaultOpt() const
-  {
-    return m_defaultOpt;
-  }
-
-  /// @brief Encode to a wire format or estimate wire format
-  template<bool T>
-  size_t
-  wireEncode(EncodingImpl<T>& block) const;
-
-  /// @brief Encode to a wire format
-  const Block&
-  wireEncode() const;
-
-  /**
-   * @brief Decode GetParam from a wire encoded block
-   *
-   * @throws Error if decoding fails
-   */
-  void
-  wireDecode(const Block& wire);
-
-public:
-  static const std::string VERB;
-
-private:
-  tlv::pib::EntityType m_entityType;
-  PibUser m_user;
-  PibIdentity m_identity;
-  PibPublicKey m_key;
-  PibCertificate m_certificate;
-  pib::DefaultOpt m_defaultOpt;
-
-  mutable Block m_wire;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_UPDATE_PARAM_HPP
diff --git a/tools/pib/get-query-processor.cpp b/tools/pib/get-query-processor.cpp
deleted file mode 100644
index 922d4c7..0000000
--- a/tools/pib/get-query-processor.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "get-query-processor.hpp"
-#include "encoding/pib-encoding.hpp"
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-const Name GetQueryProcessor::PIB_PREFIX("/localhost/pib");
-const size_t GetQueryProcessor::GET_QUERY_LENGTH = 5;
-
-GetQueryProcessor::GetQueryProcessor(PibDb& db)
-  : m_db(db)
-{
-}
-
-std::pair<bool, Block>
-GetQueryProcessor::operator()(const Interest& interest)
-{
-  const Name& interestName = interest.getName();
-
-  // handle pib query: /localhost/pib/[UserName]/get/param
-  if (interestName.size() != GET_QUERY_LENGTH) {
-    // malformed interest, discard
-    return std::make_pair(false, Block());
-  }
-
-  GetParam param;
-
-  try {
-    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
-  }
-  catch (const tlv::Error& e) {
-    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + std::string(e.what()));
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  switch (param.getTargetType()) {
-  case TYPE_ID:
-    return processGetIdQuery(param);
-  case TYPE_KEY:
-    return processGetKeyQuery(param);
-  case TYPE_CERT:
-    return processGetCertQuery(param);
-  case TYPE_USER:
-    if (interest.getName().get(2).toUri() != m_db.getOwnerName())
-      return std::make_pair(false, Block());
-    else
-      return processGetUserQuery(param);
-  default:
-    {
-      PibError error(ERR_WRONG_PARAM, "requested type is not supported:" +
-                     boost::lexical_cast<std::string>(param.getTargetType()));
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-}
-
-std::pair<bool, Block>
-GetQueryProcessor::processGetIdQuery(const GetParam& param)
-{
-  if (!m_db.hasIdentity(param.getTargetName())) {
-    PibError error(ERR_NON_EXISTING_ID, "requested id does not exist");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  PibIdentity result(param.getTargetName());
-  return std::make_pair(true, result.wireEncode());
-}
-
-std::pair<bool, Block>
-GetQueryProcessor::processGetKeyQuery(const GetParam& param)
-{
-  if (param.getTargetName().empty()) {
-    PibError error(ERR_WRONG_PARAM, "key name does not have id-component");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  shared_ptr<PublicKey> key = m_db.getKey(param.getTargetName());
-  if (key == nullptr) {
-    PibError error(ERR_NON_EXISTING_KEY, "requested key does not exist");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  PibPublicKey result(param.getTargetName(), *key);
-  return std::make_pair(true, result.wireEncode());
-}
-
-std::pair<bool, Block>
-GetQueryProcessor::processGetCertQuery(const GetParam& param)
-{
-  shared_ptr<IdentityCertificate> certificate = m_db.getCertificate(param.getTargetName());
-  if (certificate == nullptr) {
-    PibError error(ERR_NON_EXISTING_CERT, "requested certificate does not exist");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  PibCertificate result(*certificate);
-  return std::make_pair(true, result.wireEncode());
-}
-
-std::pair<bool, Block>
-GetQueryProcessor::processGetUserQuery(const GetParam& param)
-{
-  PibUser result;
-  result.setMgmtCert(*m_db.getMgmtCertificate());
-  result.setTpmLocator(m_db.getTpmLocator());
-  return std::make_pair(true, result.wireEncode());
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/get-query-processor.hpp b/tools/pib/get-query-processor.hpp
deleted file mode 100644
index 7606c4a..0000000
--- a/tools/pib/get-query-processor.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_GET_QUERY_PROCESSOR_HPP
-#define NDN_TOOLS_PIB_GET_QUERY_PROCESSOR_HPP
-
-#include "pib-db.hpp"
-#include "encoding/get-param.hpp"
-#include <ndn-cxx/interest.hpp>
-#include <utility>
-
-namespace ndn {
-namespace pib {
-
-/// @brief implements the PIB service
-class GetQueryProcessor : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param db The pib database.
-   * @param owner Owner of the pib database.
-   */
-  explicit
-  GetQueryProcessor(PibDb& db);
-
-  std::pair<bool, Block>
-  operator()(const Interest& interest);
-
-private:
-  std::pair<bool, Block>
-  processGetUserQuery(const GetParam& param);
-
-  std::pair<bool, Block>
-  processGetIdQuery(const GetParam& param);
-
-  std::pair<bool, Block>
-  processGetKeyQuery(const GetParam& param);
-
-  std::pair<bool, Block>
-  processGetCertQuery(const GetParam& param);
-
-private:
-  static const Name PIB_PREFIX;
-  static const size_t GET_QUERY_LENGTH;
-
-  const PibDb&  m_db;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_GET_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/key-cache.cpp b/tools/pib/key-cache.cpp
deleted file mode 100644
index 1740a89..0000000
--- a/tools/pib/key-cache.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "key-cache.hpp"
-
-namespace ndn {
-namespace pib {
-
-KeyCacheEntry::KeyCacheEntry(const Name& name, shared_ptr<PublicKey> key)
-  : name(name)
-  , key(key)
-{
-  BOOST_ASSERT(static_cast<bool>(key));
-}
-
-KeyCache::KeyCache(size_t capacity)
-  : m_capacity(capacity)
-{
-}
-
-void
-KeyCache::insert(const Name& name, shared_ptr<PublicKey> key)
-{
-  // check if key exist
-  KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
-  if (it != m_keys.get<byName>().end()) {
-    adjustLru(it);
-    return;
-  }
-
-  // evict key when capacity is reached
-  if (size() >= m_capacity)
-    evictKey();
-
-  // insert entry
-  m_keys.insert(KeyCacheEntry(name, key));
-}
-
-shared_ptr<PublicKey>
-KeyCache::find(const Name& name) const
-{
-  // check if key exist
-  KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
-  if (it == m_keys.get<byName>().end())
-    return shared_ptr<PublicKey>();
-  else {
-    // adjust lru
-    shared_ptr<PublicKey> key = it->key;
-    adjustLru(it);
-    return key;
-  }
-}
-
-void
-KeyCache::erase(const Name& name)
-{
-  // check if key exist
-  KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
-  if (it != m_keys.get<byName>().end()) {
-    m_keys.erase(it);
-  }
-}
-
-size_t
-KeyCache::size() const
-{
-  return m_keys.size();
-}
-
-void
-KeyCache::evictKey()
-{
-  if (!m_keys.get<byUsedTime>().empty()) {
-    KeyContainer::index<byUsedTime>::type::iterator it = m_keys.get<byUsedTime>().begin();
-    m_keys.erase(m_keys.project<0>(it));
-  }
-}
-
-void
-KeyCache::adjustLru(KeyContainer::iterator it) const
-{
-  KeyCacheEntry entry = std::move(*it);
-  m_keys.erase(it);
-  m_keys.insert(entry);
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/key-cache.hpp b/tools/pib/key-cache.hpp
deleted file mode 100644
index bcc4d8d..0000000
--- a/tools/pib/key-cache.hpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_KEY_CACHE_HPP
-#define NDN_TOOLS_PIB_KEY_CACHE_HPP
-
-#include <ndn-cxx/name.hpp>
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/security/public-key.hpp>
-
-#include <stack>
-
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index/hashed_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/key_extractors.hpp>
-
-namespace ndn {
-namespace pib {
-
-struct KeyCacheEntry
-{
-  KeyCacheEntry(const Name& name, shared_ptr<PublicKey> key);
-
-  Name name;
-  shared_ptr<PublicKey> key;
-};
-
-class byName;
-class byUsedTime;
-
-typedef boost::multi_index::multi_index_container<
-  KeyCacheEntry,
-  boost::multi_index::indexed_by<
-    boost::multi_index::hashed_unique<
-      boost::multi_index::tag<byName>,
-      boost::multi_index::member<KeyCacheEntry, Name, &KeyCacheEntry::name>,
-      std::hash<Name>
-    >,
-
-    boost::multi_index::sequenced<
-      boost::multi_index::tag<byUsedTime>
-    >
-  >
-> KeyContainer;
-
-class KeyCache : noncopyable
-{
-public:
-  explicit
-  KeyCache(size_t capacity = getDefaultCapacity());
-
-  void
-  insert(const Name& name, shared_ptr<PublicKey> key);
-
-  shared_ptr<PublicKey>
-  find(const Name& name) const;
-
-  void
-  erase(const Name& name);
-
-  size_t
-  size() const;
-
-private:
-  static size_t
-  getDefaultCapacity()
-  {
-    return 100;
-  }
-
-  void
-  evictKey();
-
-  void
-  adjustLru(KeyContainer::iterator it) const;
-
-  void
-  freeEntry(KeyContainer::iterator it);
-
-private:
-  size_t m_capacity;
-  mutable KeyContainer m_keys;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_KEY_CACHE_HPP
diff --git a/tools/pib/list-query-processor.cpp b/tools/pib/list-query-processor.cpp
deleted file mode 100644
index 29190e4..0000000
--- a/tools/pib/list-query-processor.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "list-query-processor.hpp"
-#include "encoding/pib-encoding.hpp"
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-using std::string;
-using std::vector;
-
-const size_t ListQueryProcessor::LIST_QUERY_LENGTH = 5;
-
-ListQueryProcessor::ListQueryProcessor(PibDb& db)
-  : m_db(db)
-{
-}
-
-std::pair<bool, Block>
-ListQueryProcessor::operator()(const Interest& interest)
-{
-  const Name& interestName = interest.getName();
-
-  // handle pib query: /localhost/pib/[UserName]/list/param
-  if (interestName.size() != MIN_PIB_INTEREST_SIZE) {
-    // malformed interest, discard
-    return std::make_pair(false, Block());
-  }
-
-  ListParam param;
-
-  try {
-    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
-  }
-  catch (const tlv::Error& e) {
-    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  vector<Name> nameList;
-  switch (param.getOriginType()) {
-  case TYPE_USER:
-    {
-      nameList = m_db.listIdentities();
-      break;
-    }
-  case TYPE_ID:
-    {
-      nameList = m_db.listKeyNamesOfIdentity(param.getOriginName());
-      break;
-    }
-  case TYPE_KEY:
-    {
-      const Name& keyName = param.getOriginName();
-      if (keyName.empty()) {
-        PibError error(ERR_WRONG_PARAM,
-                       "key name must contain key id component");
-        return std::make_pair(true, error.wireEncode());
-      }
-
-      nameList = m_db.listCertNamesOfKey(keyName);
-      break;
-    }
-  default:
-    {
-      PibError error(ERR_WRONG_PARAM,
-                     "origin type is not supported: " +
-                     boost::lexical_cast<string>(param.getOriginType()));
-      return std::make_pair(true, error.wireEncode());
-    }
-  }
-
-  PibNameList result(nameList);
-  return std::make_pair(true, result.wireEncode());
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/list-query-processor.hpp b/tools/pib/list-query-processor.hpp
deleted file mode 100644
index 903c47b..0000000
--- a/tools/pib/list-query-processor.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_LIST_QUERY_PROCESSOR_HPP
-#define NDN_TOOLS_PIB_LIST_QUERY_PROCESSOR_HPP
-
-#include "pib-db.hpp"
-#include "encoding/list-param.hpp"
-#include <ndn-cxx/interest.hpp>
-#include <utility>
-
-namespace ndn {
-namespace pib {
-
-class ListQueryProcessor : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param db The pib database.
-   */
-  explicit
-  ListQueryProcessor(PibDb& db);
-
-  std::pair<bool, Block>
-  operator()(const Interest& interest);
-
-private:
-  static const size_t LIST_QUERY_LENGTH;
-
-  const PibDb&  m_db;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_LIST_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/ndn-pib.cpp b/tools/pib/ndn-pib.cpp
deleted file mode 100644
index 4a4922b..0000000
--- a/tools/pib/ndn-pib.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "pib.hpp"
-
-#include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/util/config-file.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/variables_map.hpp>
-#include <boost/program_options/parsers.hpp>
-#include <boost/filesystem.hpp>
-
-namespace ndn {
-namespace pib {
-
-int
-main(int argc, char** argv)
-{
-  namespace po = boost::program_options;
-  namespace fs = boost::filesystem;
-
-  std::string owner;
-  std::string dbDir;
-  std::string tpmLocator;
-  Face face;
-
-  std::cerr << "hello" << std::endl;
-
-  po::options_description description(
-    "General Usage\n"
-    "  ndn-pib [-h] -o owner -d database_dir -t tpm_locator\n"
-    "General options");
-
-  description.add_options()
-    ("help,h",     "produce help message")
-    ("owner,o",    po::value<std::string>(&owner),
-                   "Name of the owner, PIB will listen to /localhost/pib/[owner].")
-    ("database,d", po::value<std::string>(&dbDir),
-                   "Absolute path to the directory of PIB database, /<database_dir>/pib.db")
-    ("tpm,t",      po::value<std::string>(&tpmLocator),
-                   "URI of the tpm. e.g., tpm-file:/var")
-    ;
-
-  po::variables_map vm;
-  try {
-    po::store(po::parse_command_line(argc, argv, description), vm);
-    po::notify(vm);
-  }
-  catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
-  }
-
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
-    return 0;
-  }
-
-  try {
-    if (vm.count("owner") == 0 && vm.count("database") == 0 && vm.count("tpm") == 0) {
-      if (std::getenv("HOME")) {
-        fs::path pibDir(std::getenv("HOME"));
-        pibDir /= ".ndn/pib";
-        dbDir = pibDir.string();
-      }
-      else {
-        std::cerr << "ERROR: HOME variable is not set" << std::endl;
-        return 1;
-      }
-
-      tpmLocator = KeyChain::getDefaultTpmLocator();
-
-      if (std::getenv("USER")) {
-        owner = std::string(std::getenv("USER"));
-      }
-      else {
-        std::cerr << "ERROR: HOME variable is not set" << std::endl;
-        return 1;
-      }
-    }
-    else if (vm.count("owner") == 0 || vm.count("database") == 0 ||
-             vm.count("tpm") == 0) {
-      std::cerr << description << std::endl;
-      return 1;
-    }
-
-    Pib pib(face, dbDir, tpmLocator, owner);
-    face.processEvents();
-  }
-  catch (std::runtime_error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
-  }
-
-
-  return 0;
-}
-
-} // namespace pib
-} // namespace ndn
-
-int
-main(int argc, char** argv)
-{
-  return ndn::pib::main(argc, argv);
-}
diff --git a/tools/pib/pib-db.cpp b/tools/pib/pib-db.cpp
deleted file mode 100644
index 330af14..0000000
--- a/tools/pib/pib-db.cpp
+++ /dev/null
@@ -1,825 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "pib-db.hpp"
-#include <sqlite3.h>
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string.hpp>
-
-namespace ndn {
-namespace pib {
-
-using std::string;
-using std::vector;
-using std::set;
-
-const Name PibDb::NON_EXISTING_IDENTITY("/localhost/reserved/non-existing-identity");
-const Name PibDb::NON_EXISTING_KEY("/localhost/reserved/non-existing-key");
-const Name PibDb::NON_EXISTING_CERTIFICATE("/localhost/reserved/non-existing-certificate");
-
-const Name PibDb::LOCALHOST_PIB("/localhost/pib");
-const name::Component PibDb::MGMT_LABEL("mgmt");
-
-
-static const string INITIALIZATION =
-  "CREATE TABLE IF NOT EXISTS                    \n"
-  "  mgmt(                                       \n"
-  "    id                    INTEGER PRIMARY KEY,\n"
-  "    owner                 BLOB NOT NULL,      \n"
-  "    tpm_locator           BLOB,               \n"
-  "    local_management_cert BLOB NOT NULL       \n"
-  "  );                                          \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  mgmt_insert_trigger                         \n"
-  "  BEFORE INSERT ON mgmt                       \n"
-  "  FOR EACH ROW                                \n"
-  "  BEGIN                                       \n"
-  "    DELETE FROM mgmt;                         \n"
-  "  END;                                        \n"
-  "                                              \n"
-  "CREATE TABLE IF NOT EXISTS                    \n"
-  "  identities(                                 \n"
-  "    id                    INTEGER PRIMARY KEY,\n"
-  "    identity              BLOB NOT NULL,      \n"
-  "    is_default            INTEGER DEFAULT 0   \n"
-  "  );                                          \n"
-  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
-  "  identityIndex ON identities(identity);      \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  identity_default_before_insert_trigger      \n"
-  "  BEFORE INSERT ON identities                 \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NEW.is_default=1                       \n"
-  "  BEGIN                                       \n"
-  "    UPDATE identities SET is_default=0;       \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  identity_default_after_insert_trigger       \n"
-  "  AFTER INSERT ON identities                  \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NOT EXISTS                             \n"
-  "    (SELECT id                                \n"
-  "       FROM identities                        \n"
-  "       WHERE is_default=1)                    \n"
-  "  BEGIN                                       \n"
-  "    UPDATE identities                         \n"
-  "      SET is_default=1                        \n"
-  "      WHERE identity=NEW.identity;            \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  identity_default_update_trigger             \n"
-  "  BEFORE UPDATE ON identities                 \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NEW.is_default=1 AND OLD.is_default=0  \n"
-  "  BEGIN                                       \n"
-  "    UPDATE identities SET is_default=0;       \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  identity_delete_trigger                     \n"
-  "  AFTER DELETE ON identities                  \n"
-  "  FOR EACH ROW                                \n"
-  "  BEGIN                                       \n"
-  "    SELECT identityDeleted (OLD.identity);    \n"
-  "  END;                                        \n"
-  "                                              \n"
-  "CREATE TABLE IF NOT EXISTS                    \n"
-  "  keys(                                       \n"
-  "    id                    INTEGER PRIMARY KEY,\n"
-  "    identity_id           INTEGER NOT NULL,   \n"
-  "    key_name              BLOB NOT NULL,      \n"
-  "    key_type              INTEGER NOT NULL,   \n"
-  "    key_bits              BLOB NOT NULL,      \n"
-  "    is_default            INTEGER DEFAULT 0,  \n"
-  "    FOREIGN KEY(identity_id)                  \n"
-  "      REFERENCES identities(id)               \n"
-  "      ON DELETE CASCADE                       \n"
-  "      ON UPDATE CASCADE                       \n"
-  "  );                                          \n"
-  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
-  "  keyIndex ON keys(key_name);                 \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  key_default_before_insert_trigger           \n"
-  "  BEFORE INSERT ON keys                       \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NEW.is_default=1                       \n"
-  "  BEGIN                                       \n"
-  "    UPDATE keys                               \n"
-  "      SET is_default=0                        \n"
-  "      WHERE identity_id=NEW.identity_id;      \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  key_default_after_insert_trigger            \n"
-  "  AFTER INSERT ON keys                        \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NOT EXISTS                             \n"
-  "    (SELECT id                                \n"
-  "       FROM keys                              \n"
-  "       WHERE is_default=1                     \n"
-  "         AND identity_id=NEW.identity_id)     \n"
-  "  BEGIN                                       \n"
-  "    UPDATE keys                               \n"
-  "      SET is_default=1                        \n"
-  "      WHERE key_name=NEW.key_name;            \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  key_default_update_trigger                  \n"
-  "  BEFORE UPDATE ON keys                       \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NEW.is_default=1 AND OLD.is_default=0  \n"
-  "  BEGIN                                       \n"
-  "    UPDATE keys                               \n"
-  "      SET is_default=0                        \n"
-  "      WHERE identity_id=NEW.identity_id;      \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  key_delete_trigger                          \n"
-  "  AFTER DELETE ON keys                        \n"
-  "  FOR EACH ROW                                \n"
-  "  BEGIN                                       \n"
-  "    SELECT keyDeleted (OLD.key_name);         \n"
-  "  END;                                        \n"
-  "                                              \n"
-  "CREATE TABLE IF NOT EXISTS                    \n"
-  "  certificates(                               \n"
-  "    id                    INTEGER PRIMARY KEY,\n"
-  "    key_id                INTEGER NOT NULL,   \n"
-  "    certificate_name      BLOB NOT NULL,      \n"
-  "    certificate_data      BLOB NOT NULL,      \n"
-  "    is_default            INTEGER DEFAULT 0,  \n"
-  "    FOREIGN KEY(key_id)                       \n"
-  "      REFERENCES keys(id)                     \n"
-  "      ON DELETE CASCADE                       \n"
-  "      ON UPDATE CASCADE                       \n"
-  "  );                                          \n"
-  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
-  "  certIndex ON certificates(certificate_name);\n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  cert_default_before_insert_trigger          \n"
-  "  BEFORE INSERT ON certificates               \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NEW.is_default=1                       \n"
-  "  BEGIN                                       \n"
-  "    UPDATE certificates                       \n"
-  "      SET is_default=0                        \n"
-  "      WHERE key_id=NEW.key_id;                \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  cert_default_after_insert_trigger           \n"
-  "  AFTER INSERT ON certificates                \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NOT EXISTS                             \n"
-  "    (SELECT id                                \n"
-  "       FROM certificates                      \n"
-  "       WHERE is_default=1                     \n"
-  "         AND key_id=NEW.key_id)               \n"
-  "  BEGIN                                       \n"
-  "    UPDATE certificates                       \n"
-  "      SET is_default=1                        \n"
-  "      WHERE certificate_name=NEW.certificate_name;\n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  cert_default_update_trigger                 \n"
-  "  BEFORE UPDATE ON certificates               \n"
-  "  FOR EACH ROW                                \n"
-  "  WHEN NEW.is_default=1 AND OLD.is_default=0  \n"
-  "  BEGIN                                       \n"
-  "    UPDATE certificates                       \n"
-  "      SET is_default=0                        \n"
-  "      WHERE key_id=NEW.key_id;                \n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  cert_delete_trigger                         \n"
-  "  AFTER DELETE ON certificates                \n"
-  "  FOR EACH ROW                                \n"
-  "  BEGIN                                       \n"
-  "    SELECT certDeleted (OLD.certificate_name);\n"
-  "  END;                                        \n"
-  "CREATE TRIGGER IF NOT EXISTS                  \n"
-  "  cert_insert_trigger                         \n"
-  "  AFTER INSERT ON certificates                \n"
-  "  FOR EACH ROW                                \n"
-  "  BEGIN                                       \n"
-  "    SELECT certInserted (NEW.certificate_name);\n"
-  "  END;                                        \n";
-
-
-/**
- * A utility function to call the normal sqlite3_bind_text where the value and length are
- * value.c_str() and value.size().
- */
-static int
-sqlite3_bind_string(sqlite3_stmt* statement,
-                    int index,
-                    const string& value,
-                    void(*destructor)(void*))
-{
-  return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
-}
-
-/**
- * A utility function to call the normal sqlite3_bind_blob where the value and length are
- * block.wire() and block.size().
- */
-static int
-sqlite3_bind_block(sqlite3_stmt* statement,
-                   int index,
-                   const Block& block,
-                   void(*destructor)(void*))
-{
-  return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
-}
-
-/**
- * A utility function to generate string by calling the normal sqlite3_column_text.
- */
-static string
-sqlite3_column_string(sqlite3_stmt* statement, int column)
-{
-  return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
-                sqlite3_column_bytes(statement, column));
-}
-
-/**
- * A utility function to generate block by calling the normal sqlite3_column_text.
- */
-static Block
-sqlite3_column_block(sqlite3_stmt* statement, int column)
-{
-  return Block(sqlite3_column_blob(statement, column), sqlite3_column_bytes(statement, column));
-}
-
-PibDb::PibDb(const string& dbDir)
-{
-  // Determine the path of PIB DB
-  boost::filesystem::path dir;
-  if (dbDir == "") {
-    dir = boost::filesystem::path(getenv("HOME")) / ".ndn";
-    boost::filesystem::create_directories(dir);
-  }
-  else {
-    dir = boost::filesystem::path(dbDir);
-    boost::filesystem::create_directories(dir);
-  }
-  // Open PIB
-  int result = sqlite3_open_v2((dir / "pib.db").c_str(), &m_database,
-                               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
-#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
-                               "unix-dotfile"
-#else
-                               nullptr
-#endif
-                               );
-
-  if (result != SQLITE_OK)
-    throw Error("PIB DB cannot be opened/created: " + dbDir);
-
-
-  // enable foreign key
-  sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
-
-  // initialize PIB specific tables
-  char* errorMessage = nullptr;
-  result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
-  if (result != SQLITE_OK && errorMessage != nullptr) {
-    sqlite3_free(errorMessage);
-    throw Error("PIB DB cannot be initialized");
-  }
-
-  // create delete trigger functions
-  createDbDeleteTrigger();
-
-  getOwnerName();
-}
-
-void
-PibDb::createDbDeleteTrigger()
-{
-  int res = 0;
-
-  res = sqlite3_create_function(m_database, "identityDeleted", -1, SQLITE_UTF8,
-                                reinterpret_cast<void*>(this),
-                                PibDb::identityDeletedFun, nullptr, nullptr);
-  if (res != SQLITE_OK)
-    throw Error("Cannot create function ``identityDeleted''");
-
-  res = sqlite3_create_function(m_database, "keyDeleted", -1, SQLITE_UTF8,
-                                reinterpret_cast<void*>(this),
-                                PibDb::keyDeletedFun, nullptr, nullptr);
-  if (res != SQLITE_OK)
-    throw Error("Cannot create function ``keyDeleted''");
-
-  res = sqlite3_create_function(m_database, "certDeleted", -1, SQLITE_UTF8,
-                                reinterpret_cast<void*>(this),
-                                PibDb::certDeletedFun, nullptr, nullptr);
-  if (res != SQLITE_OK)
-    throw Error("Cannot create function ``certDeleted''");
-
-  res = sqlite3_create_function(m_database, "certInserted", -1, SQLITE_UTF8,
-                                reinterpret_cast<void*>(this),
-                                PibDb::certInsertedFun, nullptr, nullptr);
-  if (res != SQLITE_OK)
-    throw Error("Cannot create function ``certInserted''");
-}
-
-void
-PibDb::identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
-{
-  BOOST_ASSERT(argc == 1);
-
-  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
-  Name identity(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
-
-  pibDb->identityDeleted(identity);
-}
-
-void
-PibDb::keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
-{
-  BOOST_ASSERT(argc == 1);
-
-  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
-  Name keyName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
-
-  pibDb->keyDeleted(keyName);
-}
-
-void
-PibDb::certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
-{
-  BOOST_ASSERT(argc == 1);
-
-  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
-  Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
-
-  pibDb->certificateDeleted(certName);
-}
-
-void
-PibDb::certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
-{
-  BOOST_ASSERT(argc == 1);
-
-  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
-  Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
-
-  pibDb->certificateInserted(certName);
-}
-
-void
-PibDb::updateMgmtCertificate(const IdentityCertificate& certificate)
-{
-  const Name& keyName = certificate.getPublicKeyName();
-
-  // Name of mgmt key should be "/localhost/pib/[UserName]/mgmt/[KeyID]"
-  if (keyName.size() != 5 ||
-      keyName.compare(0, 2, LOCALHOST_PIB) ||
-      keyName.get(3) != MGMT_LABEL)
-    throw Error("PibDb::updateMgmtCertificate: certificate does not follow the naming convention");
-
-  string owner = keyName.get(2).toUri();
-  sqlite3_stmt* statement;
-  if (!m_owner.empty()) {
-    if (m_owner != owner)
-      throw Error("PibDb::updateMgmtCertificate: owner name does not match");
-    else {
-      sqlite3_prepare_v2(m_database,
-                         "UPDATE mgmt SET local_management_cert=? WHERE owner=?",
-                         -1, &statement, nullptr);
-    }
-  }
-  else {
-    sqlite3_prepare_v2(m_database,
-                       "INSERT INTO mgmt (local_management_cert, owner) VALUES (?, ?)",
-                       -1, &statement, nullptr);
-  }
-
-  sqlite3_bind_block(statement, 1, certificate.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, owner, SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  m_owner = owner;
-
-  mgmtCertificateChanged();
-}
-
-string
-PibDb::getOwnerName() const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database, "SELECT owner FROM mgmt", -1, &statement, nullptr);
-
-  if (sqlite3_step(statement) == SQLITE_ROW) {
-    m_owner = sqlite3_column_string(statement, 0);
-  }
-
-  sqlite3_finalize(statement);
-  return m_owner;
-}
-
-shared_ptr<IdentityCertificate>
-PibDb::getMgmtCertificate() const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database, "SELECT local_management_cert FROM mgmt", -1, &statement, nullptr);
-
-  shared_ptr<IdentityCertificate> certificate;
-  if (sqlite3_step(statement) == SQLITE_ROW) {
-    certificate = make_shared<IdentityCertificate>();
-    certificate->wireDecode(sqlite3_column_block(statement, 0));
-  }
-
-  sqlite3_finalize(statement);
-  return certificate;
-}
-
-void
-PibDb::setTpmLocator(const std::string& tpmLocator)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE mgmt SET tpm_locator=? WHERE owner=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, m_owner, SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-std::string
-PibDb::getTpmLocator() const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM mgmt", -1, &statement, nullptr);
-
-  string tpmLocator;
-  if (sqlite3_step(statement) == SQLITE_ROW) {
-    tpmLocator = sqlite3_column_string(statement, 0);
-  }
-
-  sqlite3_finalize(statement);
-  return tpmLocator;
-}
-
-int64_t
-PibDb::addIdentity(const Name& identity)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT INTO identities (identity) values (?)",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  return sqlite3_last_insert_rowid(m_database);
-}
-
-void
-PibDb::deleteIdentity(const Name& identity)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "DELETE FROM identities WHERE identity=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-bool
-PibDb::hasIdentity(const Name& identity) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT id FROM identities WHERE identity=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-  int result = sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  if (result == SQLITE_ROW)
-    return true;
-  else
-    return false;
-}
-
-void
-PibDb::setDefaultIdentity(const Name& identity)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE identities SET is_default=1 WHERE identity=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-Name
-PibDb::getDefaultIdentity() const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT identity FROM identities WHERE is_default=1",
-                     -1, &statement, nullptr);
-
-  Name identity = NON_EXISTING_IDENTITY;
-  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
-    identity = Name(sqlite3_column_block(statement, 0));
-  }
-  sqlite3_finalize(statement);
-  return identity;
-}
-
-vector<Name>
-PibDb::listIdentities() const
-{
-  vector<Name> identities;
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database, "SELECT identity FROM identities", -1, &statement, nullptr);
-
-  identities.clear();
-  while (sqlite3_step(statement) == SQLITE_ROW) {
-    Name name(sqlite3_column_block(statement, 0));
-    identities.push_back(name);
-  }
-  sqlite3_finalize(statement);
-
-  return identities;
-}
-
-int64_t
-PibDb::addKey(const Name& keyName, const PublicKey& key)
-{
-  if (keyName.empty())
-    return 0;
-
-  Name&& identity = keyName.getPrefix(-1);
-  if (!hasIdentity(identity))
-    addIdentity(identity);
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT INTO keys (identity_id, key_name, key_type, key_bits) \
-                      values ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_bind_block(statement, 2, keyName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_bind_int(statement, 3, static_cast<int>(key.getKeyType()));
-  sqlite3_bind_blob(statement, 4, key.get().buf(), key.get().size(), SQLITE_STATIC);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  return sqlite3_last_insert_rowid(m_database);
-}
-
-shared_ptr<PublicKey>
-PibDb::getKey(const Name& keyName) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT key_bits FROM keys WHERE key_name=?"
-                     , -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-
-  shared_ptr<PublicKey> key;
-  if (sqlite3_step(statement) == SQLITE_ROW) {
-      key = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
-                                   sqlite3_column_bytes(statement, 0));
-  }
-  sqlite3_finalize(statement);
-  return key;
-}
-
-void
-PibDb::deleteKey(const Name& keyName)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "DELETE FROM keys WHERE key_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-bool
-PibDb::hasKey(const Name& keyName) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT id FROM keys WHERE key_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-
-  int result = sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  if (result == SQLITE_ROW)
-    return true;
-  else
-    return false;
-}
-
-void
-PibDb::setDefaultKeyNameOfIdentity(const Name& keyName)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE keys SET is_default=1 WHERE key_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-Name
-PibDb::getDefaultKeyNameOfIdentity(const Name& identity) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
-                      WHERE identities.identity=? AND keys.is_default=1",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-
-  Name keyName = NON_EXISTING_KEY;
-  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
-    keyName = Name(sqlite3_column_block(statement, 0));
-  }
-
-  sqlite3_finalize(statement);
-  return keyName;
-}
-
-vector<Name>
-PibDb::listKeyNamesOfIdentity(const Name& identity) const
-{
-  vector<Name> keyNames;
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
-                      WHERE identities.identity=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
-
-  keyNames.clear();
-  while (sqlite3_step(statement) == SQLITE_ROW) {
-    Name keyName(sqlite3_column_block(statement, 0));
-    keyNames.push_back(keyName);
-  }
-
-  sqlite3_finalize(statement);
-  return keyNames;
-}
-
-
-int64_t
-PibDb::addCertificate(const IdentityCertificate& certificate)
-{
-  const Name& certName = certificate.getName();
-  const Name& keyName = certificate.getPublicKeyName();
-
-  if (!hasKey(keyName))
-    addKey(keyName, certificate.getPublicKeyInfo());
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT INTO certificates \
-                      (key_id, certificate_name, certificate_data) \
-                      values ((SELECT id FROM keys WHERE key_name=?), ?, ?)",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_bind_block(statement, 2, certName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_bind_block(statement, 3, certificate.wireEncode(), SQLITE_STATIC);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  return sqlite3_last_insert_rowid(m_database);
-}
-
-shared_ptr<IdentityCertificate>
-PibDb::getCertificate(const Name& certificateName) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT certificate_data FROM certificates WHERE certificate_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
-
-  shared_ptr<IdentityCertificate> certificate;
-  if (sqlite3_step(statement) == SQLITE_ROW) {
-    certificate = make_shared<IdentityCertificate>();
-    certificate->wireDecode(sqlite3_column_block(statement, 0));
-  }
-
-  sqlite3_finalize(statement);
-  return certificate;
-}
-
-void
-PibDb::deleteCertificate(const Name& certificateName)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "DELETE FROM certificates WHERE certificate_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-bool
-PibDb::hasCertificate(const Name& certificateName) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT id FROM certificates WHERE certificate_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
-  int result = sqlite3_step(statement);
-  sqlite3_finalize(statement);
-
-  if (result == SQLITE_ROW)
-    return true;
-  else
-    return false;
-}
-
-void
-PibDb::setDefaultCertNameOfKey(const Name& certificateName)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE certificates SET is_default=1 WHERE certificate_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-Name
-PibDb::getDefaultCertNameOfKey(const Name& keyName) const
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT certificate_name\
-                      FROM certificates JOIN keys ON certificates.key_id=keys.id\
-                      WHERE keys.key_name=? AND certificates.is_default=1",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-
-  Name certName = NON_EXISTING_CERTIFICATE;
-  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
-    certName = Name(sqlite3_column_block(statement, 0));
-  }
-  sqlite3_finalize(statement);
-  return certName;
-}
-
-vector<Name>
-PibDb::listCertNamesOfKey(const Name& keyName) const
-{
-  vector<Name> certNames;
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT certificate_name\
-                      FROM certificates JOIN keys ON certificates.key_id=keys.id\
-                      WHERE keys.key_name=?",
-                     -1, &statement, nullptr);
-  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
-
-  certNames.clear();
-  while (sqlite3_step(statement) == SQLITE_ROW) {
-    Name name(sqlite3_column_block(statement, 0));
-    certNames.push_back(name);
-  }
-  sqlite3_finalize(statement);
-
-  return certNames;
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/pib-db.hpp b/tools/pib/pib-db.hpp
deleted file mode 100644
index 2362eb9..0000000
--- a/tools/pib/pib-db.hpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_PIB_DB_HPP
-#define NDN_TOOLS_PIB_PIB_DB_HPP
-
-#include "core/common.hpp"
-#include <ndn-cxx/security/identity-certificate.hpp>
-#include <ndn-cxx/util/signal.hpp>
-
-#include <set>
-#include <vector>
-
-struct sqlite3;
-struct sqlite3_context;
-struct Mem;
-typedef Mem sqlite3_value;
-
-namespace ndn {
-namespace pib {
-
-/// @brief Callback to report changes on user info.
-typedef function<void(const std::string&)> UserChangedEventHandler;
-
-/// @brief Callback to report that a key is deleted.
-typedef function<void(const std::string&, const Name&,
-                      const name::Component&)> KeyDeletedEventHandler;
-
-/**
- * @brief PibDb is a class to manage the database of PIB service.
- *
- * only public key related information is stored in this database.
- * Detail information can be found at:
- * http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
- */
-class PibDb : noncopyable
-{
-public:
-  util::signal::Signal<PibDb> mgmtCertificateChanged;
-  util::signal::Signal<PibDb, Name> certificateDeleted;
-  util::signal::Signal<PibDb, Name> keyDeleted;
-  util::signal::Signal<PibDb, Name> identityDeleted;
-  util::signal::Signal<PibDb, Name> certificateInserted;
-
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  explicit
-  PibDb(const std::string& dbDir = "");
-
-public: // Owner management
-  /**
-   * @brief Update owner's management certificate
-   *
-   * Since owner name is encoded in the management certificate,
-   * this method can also set the owner name if it is not set.
-   * If the owner name is set but does not match the one in the
-   * supplied certificate, it throws @p Error.
-   *
-   * @throws Error if supplied certificate is wrong
-   */
-  void
-  updateMgmtCertificate(const IdentityCertificate& certificate);
-
-  /**
-   * @brief Get owner name
-   *
-   * return empty string when owner name is not set.
-   */
-  std::string
-  getOwnerName() const;
-
-  /** @brief Get the management cert
-   *
-   * return nullptr when the management cert is not set
-   */
-  shared_ptr<IdentityCertificate>
-  getMgmtCertificate() const;
-
-  /// @brief Set TPM locator
-  void
-  setTpmLocator(const std::string& tpmLocator);
-
-  /**
-   * @brief Get TPM locator
-   *
-   * return empty string when tpmLocator is not set.
-   */
-  std::string
-  getTpmLocator() const;
-
-public: // Identity management
-
-  /**
-   * @brief Add an identity
-   *
-   * @return row id of the added identity, 0 if insert fails.
-   */
-  int64_t
-  addIdentity(const Name& identity);
-
-  /// @brief Delete an identity
-  void
-  deleteIdentity(const Name& identity);
-
-  /// @brief Check if an identity exists
-  bool
-  hasIdentity(const Name& identity) const;
-
-  /// @brief Get all identities
-  std::vector<Name>
-  listIdentities() const;
-
-  /// @brief Set the default identity
-  void
-  setDefaultIdentity(const Name& identity);
-
-  /**
-   * @brief Get the default identity
-   *
-   * @return default identity or /localhost/reserved/non-existing-identity if no default identity
-   */
-  Name
-  getDefaultIdentity() const;
-
-public: // Key management
-
-  /// @brief Add key
-  int64_t
-  addKey(const Name& keyName, const PublicKey& key);
-
-  /// @brief Delete key
-  void
-  deleteKey(const Name& keyName);
-
-  /// @brief Check if a key exists
-  bool
-  hasKey(const Name& keyName) const;
-
-  /**
-   * @brief Get key
-   *
-   * @return shared pointer to the key, nullptr if the key does not exit
-   */
-  shared_ptr<PublicKey>
-  getKey(const Name& keyName) const;
-
-  /// @brief Get all the key names of an identity
-  std::vector<Name>
-  listKeyNamesOfIdentity(const Name& identity) const;
-
-  /// @brief Set an identity's default key name
-  void
-  setDefaultKeyNameOfIdentity(const Name& keyName);
-
-  /**
-   * @brief Get the default key name of an identity
-   *
-   * @return default key name or /localhost/reserved/non-existing-key if no default key
-   */
-  Name
-  getDefaultKeyNameOfIdentity(const Name& identity) const;
-
-public: // Certificate management
-
-  /// @brief Add a certificate
-  int64_t
-  addCertificate(const IdentityCertificate& certificate);
-
-  /// @brief Delete a certificate
-  void
-  deleteCertificate(const Name& certificateName);
-
-  /// @brief Check if the certificate exist
-  bool
-  hasCertificate(const Name& certificateName) const;
-
-  /**
-   * @brief Get a certificate
-   *
-   * @return shared pointer to the certificate, nullptr if the certificate does not exist
-   */
-  shared_ptr<IdentityCertificate>
-  getCertificate(const Name& certificateName) const;
-
-  /// @brief Get all the cert names of a key
-  std::vector<Name>
-  listCertNamesOfKey(const Name& keyName) const;
-
-  /// @brief Set a key's default certificate name
-  void
-  setDefaultCertNameOfKey(const Name& certificateName);
-
-  /**
-   * @brief Get a key's default certificate name
-   *
-   * @return default certificate name or /localhost/reserved/non-existing-certificate if no default
-   *         certificate.
-   */
-  Name
-  getDefaultCertNameOfKey(const Name& keyName) const;
-
-private:
-  void
-  createDbDeleteTrigger();
-
-private:
-  static void
-  identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
-
-  static void
-  keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
-
-  static void
-  certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
-
-  static void
-  certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
-
-public:
-  static const Name NON_EXISTING_IDENTITY;
-  static const Name NON_EXISTING_KEY;
-  static const Name NON_EXISTING_CERTIFICATE;
-
-private:
-  static const Name LOCALHOST_PIB;
-  static const name::Component MGMT_LABEL;
-
-private:
-  sqlite3* m_database;
-
-  mutable std::string m_owner;
-};
-
-} // namespace pib
-} // namespace ndn
-
-
-#endif // NDN_TOOLS_PIB_PIB_DB_HPP
diff --git a/tools/pib/pib-validator.cpp b/tools/pib/pib-validator.cpp
deleted file mode 100644
index 27b7873..0000000
--- a/tools/pib/pib-validator.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "pib-validator.hpp"
-#include "encoding/pib-common.hpp"
-#include "encoding/update-param.hpp"
-#include <set>
-#include <string>
-
-namespace ndn {
-namespace pib {
-
-using std::set;
-using std::string;
-
-PibValidator::PibValidator(const PibDb& db, size_t maxCacheSize)
-  : m_db(db)
-  , m_isMgmtReady(false)
-{
-  m_owner = m_db.getOwnerName();
-  m_mgmtCert = m_db.getMgmtCertificate();
-
-  if (!m_owner.empty() && m_mgmtCert != nullptr)
-    m_isMgmtReady = true;
-
-  m_mgmtChangeConnection =
-    const_cast<PibDb&>(m_db).mgmtCertificateChanged.connect([this] () {
-        m_owner = m_db.getOwnerName();
-        m_mgmtCert = m_db.getMgmtCertificate();
-        if (!m_owner.empty() && m_mgmtCert != nullptr)
-          m_isMgmtReady = true;
-      });
-
-  m_keyDeletedConnection =
-    const_cast<PibDb&>(m_db).keyDeleted.connect([this] (Name keyName) {
-        m_keyCache.erase(keyName);
-      });
-}
-
-PibValidator::~PibValidator()
-{
-}
-
-void
-PibValidator::checkPolicy(const Interest& interest,
-                          int nSteps,
-                          const OnInterestValidated& onValidated,
-                          const OnInterestValidationFailed& onValidationFailed,
-                          std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  if (!m_isMgmtReady)
-    return onValidationFailed(interest.shared_from_this(), "PibDb is not initialized");
-
-  const Name& interestName = interest.getName();
-
-  if (interestName.size() != SIGNED_PIB_INTEREST_SIZE) {
-    return onValidationFailed(interest.shared_from_this(),
-                              "Interest is not signed: " + interest.getName().toUri());
-  }
-
-  // Check if the user exists in PIB
-  string user = interestName.get(OFFSET_USER).toUri();
-  if (user != m_owner)
-    return onValidationFailed(interest.shared_from_this(), "Wrong user: " + user);
-
-  // Verify signature
-  try {
-    Signature signature(interestName[OFFSET_SIG_INFO].blockFromValue(),
-                        interestName[OFFSET_SIG_VALUE].blockFromValue());
-    // KeyLocator is required to contain the name of signing certificate (w/o version)
-    if (!signature.hasKeyLocator())
-      return onValidationFailed(interest.shared_from_this(), "No valid KeyLocator");
-
-    const KeyLocator& keyLocator = signature.getKeyLocator();
-    if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
-      return onValidationFailed(interest.shared_from_this(), "Key Locator is not a name");
-
-    // Check if PIB has the corresponding public key
-    shared_ptr<PublicKey> publicKey;
-
-    if (keyLocator.getName() == m_mgmtCert->getName().getPrefix(-1)) {
-      // the signing key is mgmt key.
-      publicKey = make_shared<PublicKey>(m_mgmtCert->getPublicKeyInfo());
-    }
-    else {
-      // the signing key is normal key.
-      Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocator.getName());
-
-      shared_ptr<PublicKey> key = m_keyCache.find(keyName);
-      if (key != nullptr) {
-        // the signing key is cached.
-        publicKey = key;
-      }
-      else {
-        // the signing key is not cached.
-        publicKey = m_db.getKey(keyName);
-        if (publicKey == nullptr) {
-          // the signing key does not exist in PIB.
-          return onValidationFailed(interest.shared_from_this(), "Public key is not trusted");
-        }
-        else {
-          // the signing key is retrieved from PIB.
-          m_keyCache.insert(keyName, publicKey);
-        }
-      }
-    }
-
-    if (verifySignature(interest, signature, *publicKey))
-      onValidated(interest.shared_from_this());
-    else
-      onValidationFailed(interest.shared_from_this(), "Cannot verify signature");
-
-  }
-  catch (KeyLocator::Error&) {
-    return onValidationFailed(interest.shared_from_this(),
-                              "No valid KeyLocator");
-  }
-  catch (Signature::Error&) {
-    return onValidationFailed(interest.shared_from_this(),
-                              "No valid signature");
-  }
-  catch (IdentityCertificate::Error&) {
-    return onValidationFailed(interest.shared_from_this(),
-                              "Cannot determine the signing key");
-  }
-  catch (tlv::Error&) {
-    return onValidationFailed(interest.shared_from_this(),
-                              "Cannot decode signature");
-  }
-}
-
-void
-PibValidator::checkPolicy(const Data& data,
-                          int nSteps,
-                          const OnDataValidated& onValidated,
-                          const OnDataValidationFailed& onValidationFailed,
-                          std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  // Pib does not express any interest, therefor should not validate any data.
-  onValidationFailed(data.shared_from_this(),
-                     "PibValidator should not receive data packet");
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/pib-validator.hpp b/tools/pib/pib-validator.hpp
deleted file mode 100644
index 0bdf357..0000000
--- a/tools/pib/pib-validator.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_PIB_VALIDATOR_HPP
-#define NDN_TOOLS_PIB_PIB_VALIDATOR_HPP
-
-#include "pib-db.hpp"
-#include "key-cache.hpp"
-
-#include <ndn-cxx/security/validator.hpp>
-
-namespace ndn {
-namespace pib {
-
-/*
- * @brief The validator to verify the command interests to PIB service
- *
- * @sa https://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
- */
-class PibValidator : public Validator
-{
-  struct UserKeyCache;
-
-public:
-  explicit
-  PibValidator(const PibDb& pibDb,
-               size_t maxCacheSize = 1000);
-
-  ~PibValidator();
-
-protected:
-  void
-  checkPolicy(const Interest& interest,
-              int nSteps,
-              const OnInterestValidated& onValidated,
-              const OnInterestValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
-
-  void
-  checkPolicy(const Data& data,
-              int nSteps,
-              const OnDataValidated& onValidated,
-              const OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
-
-private:
-  const PibDb& m_db;
-
-  bool m_isMgmtReady;
-  std::string m_owner;
-  shared_ptr<IdentityCertificate> m_mgmtCert;
-
-  KeyCache m_keyCache;
-
-  util::signal::ScopedConnection m_mgmtChangeConnection;
-  util::signal::ScopedConnection m_keyDeletedConnection;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_PIB_VALIDATOR_HPP
diff --git a/tools/pib/pib.cpp b/tools/pib/pib.cpp
deleted file mode 100644
index 042bf2e..0000000
--- a/tools/pib/pib.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "pib.hpp"
-
-#include "encoding/pib-encoding.hpp"
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/util/crypto.hpp>
-#include <ndn-cxx/util/concepts.hpp>
-
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-using std::string;
-using std::vector;
-using std::set;
-
-const Name Pib::PIB_PREFIX("/localhost/pib");
-const Name Pib::EMPTY_SIGNER_NAME;
-const name::Component Pib::MGMT_LABEL("mgmt");
-
-// \todo make this a static method in KeyChain
-static inline void
-signWithDigestSha256(Data& data)
-{
-  DigestSha256 sig;
-  data.setSignature(sig);
-  Block sigValue(tlv::SignatureValue,
-                 crypto::sha256(data.wireEncode().value(),
-                                data.wireEncode().value_size() -
-                                data.getSignature().getValue().size()));
-  data.setSignatureValue(sigValue);
-  data.wireEncode();
-}
-
-Pib::Pib(Face& face,
-         const std::string& dbDir,
-         const std::string& tpmLocator,
-         const std::string& owner)
-  : m_db(dbDir)
-  , m_tpm(nullptr)
-  , m_owner(owner)
-  , m_validator(m_db)
-  , m_face(face)
-  , m_certPublisher(m_face, m_db)
-  , m_getProcessor(m_db)
-  , m_defaultProcessor(m_db)
-  , m_listProcessor(m_db)
-  , m_updateProcessor(m_db, *this)
-  , m_deleteProcessor(m_db)
-{
-  if (!m_db.getOwnerName().empty() && m_db.getOwnerName() != owner)
-    throw Error("owner argument differs from OwnerName in database");
-
-  if (!m_db.getTpmLocator().empty() && m_db.getTpmLocator() != tpmLocator)
-    throw Error("tpmLocator argument differs from TpmLocator in database");
-
-  initializeTpm(tpmLocator);
-  initializeMgmtCert();
-  m_db.setTpmLocator(tpmLocator);
-
-  registerPrefix();
-}
-
-Pib::~Pib()
-{
-  m_face.unsetInterestFilter(m_pibMgmtFilterId);
-  m_face.unsetInterestFilter(m_pibGetFilterId);
-  m_face.unsetInterestFilter(m_pibDefaultFilterId);
-  m_face.unsetInterestFilter(m_pibListFilterId);
-  m_face.unsetInterestFilter(m_pibUpdateFilterId);
-  m_face.unsetInterestFilter(m_pibDeleteFilterId);
-
-  m_face.unsetInterestFilter(m_pibPrefixId);
-}
-
-void
-Pib::setMgmtCert(std::shared_ptr<IdentityCertificate> mgmtCert)
-{
-  if (mgmtCert != nullptr)
-    m_mgmtCert = mgmtCert;
-}
-
-void
-Pib::initializeTpm(const string& tpmLocator)
-{
-  m_tpm = KeyChain::createTpm(tpmLocator);
-}
-
-void
-Pib::initializeMgmtCert()
-{
-  shared_ptr<IdentityCertificate> mgmtCert = m_db.getMgmtCertificate();
-
-  if (mgmtCert == nullptr ||
-      !m_tpm->doesKeyExistInTpm(mgmtCert->getPublicKeyName(), KeyClass::PRIVATE)) {
-    // If mgmt cert is set, or corresponding private key of the current mgmt cert is missing,
-    // generate new mgmt cert
-
-    // key name: /localhost/pib/[UserName]/mgmt/dsk-...
-    Name mgmtKeyName = PIB_PREFIX;
-    mgmtKeyName.append(m_owner).append(MGMT_LABEL);
-    std::ostringstream oss;
-    oss << "dsk-" << time::toUnixTimestamp(time::system_clock::now()).count();
-    mgmtKeyName.append(oss.str());
-
-    // self-sign pib root key
-    m_mgmtCert = prepareCertificate(mgmtKeyName, RsaKeyParams(),
-                                    time::system_clock::now(),
-                                    time::system_clock::now() + time::days(7300));
-
-    // update management certificate in database
-    m_db.updateMgmtCertificate(*m_mgmtCert);
-  }
-  else
-    m_mgmtCert = mgmtCert;
-}
-
-shared_ptr<IdentityCertificate>
-Pib::prepareCertificate(const Name& keyName, const KeyParams& keyParams,
-                        const time::system_clock::TimePoint& notBefore,
-                        const time::system_clock::TimePoint& notAfter,
-                        const Name& signerName)
-{
-  // Generate mgmt key
-  m_tpm->generateKeyPairInTpm(keyName, keyParams);
-  shared_ptr<PublicKey> publicKey = m_tpm->getPublicKeyFromTpm(keyName);
-
-  // Set mgmt cert
-  auto certificate = make_shared<IdentityCertificate>();
-  Name certName = keyName.getPrefix(-1);
-  certName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
-  certificate->setName(certName);
-  certificate->setNotBefore(notBefore);
-  certificate->setNotAfter(notAfter);
-  certificate->setPublicKeyInfo(*publicKey);
-  CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
-  certificate->addSubjectDescription(subjectName);
-  certificate->encode();
-
-
-  Name signingKeyName;
-  KeyLocator keyLocator;
-  if (signerName == EMPTY_SIGNER_NAME) {
-    // Self-sign mgmt cert
-    keyLocator = KeyLocator(certificate->getName().getPrefix(-1));
-    signingKeyName = keyName;
-  }
-  else {
-    keyLocator = KeyLocator(signerName.getPrefix(-1));
-    signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signerName);
-  }
-
-  SignatureSha256WithRsa signature(keyLocator);
-  certificate->setSignature(signature);
-  EncodingBuffer encoder;
-  certificate->wireEncode(encoder, true);
-  Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
-                                          signingKeyName, DigestAlgorithm::SHA256);
-  certificate->wireEncode(encoder, signatureValue);
-
-  return certificate;
-}
-
-void
-Pib::registerPrefix()
-{
-  // register pib prefix
-  Name pibPrefix = PIB_PREFIX;
-  pibPrefix.append(m_owner);
-  m_pibPrefixId =
-    m_face.registerPrefix(pibPrefix,
-                          [] (const Name& name) {},
-                          [] (const Name& name, const string& msg) {
-                            throw Error("cannot register pib prefix");
-                          });
-
-  // set interest filter for management certificate
-  m_pibMgmtFilterId =
-    m_face.setInterestFilter(Name(pibPrefix).append(MGMT_LABEL),
-                             [this] (const InterestFilter&, const Interest& interest) {
-                               if (m_mgmtCert != nullptr) {
-                                 m_face.put(*m_mgmtCert);
-                               }
-                             });
-
-  // set interest filter for get command
-  m_pibGetFilterId = registerProcessor(Name(pibPrefix).append(GetParam::VERB), m_getProcessor);
-
-  // set interest filter for default command
-  m_pibDefaultFilterId = registerProcessor(Name(pibPrefix).append(DefaultParam::VERB),
-                                           m_defaultProcessor);
-
-  // set interest filter for list command
-  m_pibListFilterId = registerProcessor(Name(pibPrefix).append(ListParam::VERB),
-                                        m_listProcessor);
-
-  // set interest filter for update command
-  m_pibUpdateFilterId = registerSignedCommandProcessor(Name(pibPrefix).append(UpdateParam::VERB),
-                                                       m_updateProcessor);
-
-  // set interest filter for delete command
-  m_pibDeleteFilterId = registerSignedCommandProcessor(Name(pibPrefix).append(DeleteParam::VERB),
-                                                       m_deleteProcessor);
-}
-
-template<class Processor>
-const InterestFilterId*
-Pib::registerProcessor(const Name& prefix, Processor& process)
-{
-  return m_face.setInterestFilter(prefix,
-                                  [&] (const InterestFilter&, const Interest& interest) {
-                                    processCommand(process, interest);
-                                  });
-}
-
-template<class Processor>
-const InterestFilterId*
-Pib::registerSignedCommandProcessor(const Name& prefix, Processor& process)
-{
-  const InterestFilterId* filterId =
-    m_face.setInterestFilter(prefix,
-      [&] (const InterestFilter&, const Interest& interest) {
-        m_validator.validate(interest,
-                             [&] (const shared_ptr<const Interest>& interest) {
-                               processCommand(process, *interest);
-                             },
-                             [] (const shared_ptr<const Interest>&, const string&) {});
-      });
-
-  return filterId;
-}
-
-template<class Processor>
-void
-Pib::processCommand(Processor& process, const Interest& interest)
-{
-  std::pair<bool, Block> result = process(interest);
-  if (result.first)
-    returnResult(Name(interest.getName()).appendVersion(),
-                 result.second);
-}
-
-void
-Pib::returnResult(const Name& dataName, const Block& content)
-{
-  shared_ptr<Data> data = make_shared<Data>(dataName);
-
-  data->setFreshnessPeriod(time::milliseconds::zero());
-  data->setContent(content);
-  signWithDigestSha256(*data);
-
-  // Put data into response cache
-  m_responseCache.insert(*data);
-
-  // Put data to face.
-  m_face.put(*data);
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/pib.hpp b/tools/pib/pib.hpp
deleted file mode 100644
index 55e26bf..0000000
--- a/tools/pib/pib.hpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_PIB_HPP
-#define NDN_TOOLS_PIB_PIB_HPP
-
-#include "pib-db.hpp"
-#include "pib-validator.hpp"
-#include "cert-publisher.hpp"
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
-
-#include "get-query-processor.hpp"
-#include "default-query-processor.hpp"
-#include "list-query-processor.hpp"
-#include "update-query-processor.hpp"
-#include "delete-query-processor.hpp"
-
-#include <ndn-cxx/security/sec-tpm.hpp>
-
-namespace ndn {
-namespace pib {
-
-/// @brief implements the PIB service
-class Pib : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param face The face pib used to receive queries and serve certificates.
-   * @param dbDir Absolute path to the directory of the pib database.
-   * @param tpmLocator URI to locate the TPM for pib service.
-   * @param owner Owner of the pib database.
-   */
-  Pib(Face& face,
-      const std::string& dbDir,
-      const std::string& tpmLocator,
-      const std::string& owner);
-
-  ~Pib();
-
-  void
-  setMgmtCert(std::shared_ptr<IdentityCertificate> mgmtCert);
-
-PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  PibDb&
-  getDb()
-  {
-    return m_db;
-  }
-
-  SecTpm&
-  getTpm()
-  {
-    return *m_tpm;
-  }
-
-  util::InMemoryStoragePersistent&
-  getResponseCache()
-  {
-    return m_responseCache;
-  }
-
-  const std::string&
-  getOwner() const
-  {
-    return m_owner;
-  }
-
-  const IdentityCertificate&
-  getMgmtCert() const
-  {
-    BOOST_ASSERT(m_mgmtCert != nullptr);
-    return *m_mgmtCert;
-  }
-
-private: // initialization
-  /// @brief initialize the PIB's own TPM.
-  void
-  initializeTpm(const std::string& tpmLocator);
-
-  /// @brief initialize management certificate
-  void
-  initializeMgmtCert();
-
-  std::shared_ptr<IdentityCertificate>
-  prepareCertificate(const Name& keyName, const KeyParams& keyParams,
-                     const time::system_clock::TimePoint& notBefore,
-                     const time::system_clock::TimePoint& notAfter,
-                     const Name& signerName = EMPTY_SIGNER_NAME);
-
-  /// @brief register prefix for PIB query and management certificate
-  void
-  registerPrefix();
-
-  template<class Processor>
-  const InterestFilterId*
-  registerProcessor(const Name& prefix, Processor& process);
-
-  template<class Processor>
-  const InterestFilterId*
-  registerSignedCommandProcessor(const Name& prefix, Processor& process);
-
-  template<class Processor>
-  void
-  processCommand(Processor& process, const Interest& interest);
-
-  void
-  returnResult(const Name& dataName, const Block& content);
-
-private:
-
-  static const Name EMPTY_SIGNER_NAME;
-  static const Name PIB_PREFIX;
-  static const name::Component MGMT_LABEL;
-
-  PibDb m_db;
-  std::unique_ptr<SecTpm> m_tpm;
-  std::string m_owner;
-  std::shared_ptr<IdentityCertificate> m_mgmtCert;
-
-  PibValidator m_validator;
-
-  Face& m_face;
-  CertPublisher m_certPublisher;
-  util::InMemoryStoragePersistent m_responseCache;
-
-  const RegisteredPrefixId* m_pibPrefixId;
-  const InterestFilterId* m_pibMgmtFilterId;
-  const InterestFilterId* m_pibGetFilterId;
-  const InterestFilterId* m_pibDefaultFilterId;
-  const InterestFilterId* m_pibListFilterId;
-  const InterestFilterId* m_pibUpdateFilterId;
-  const InterestFilterId* m_pibDeleteFilterId;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
-  GetQueryProcessor m_getProcessor;
-  DefaultQueryProcessor m_defaultProcessor;
-  ListQueryProcessor m_listProcessor;
-  UpdateQueryProcessor m_updateProcessor;
-  DeleteQueryProcessor m_deleteProcessor;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_PIB_HPP
diff --git a/tools/pib/response-cache.cpp b/tools/pib/response-cache.cpp
deleted file mode 100644
index 1fb5ade..0000000
--- a/tools/pib/response-cache.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "response-cache.hpp"
-
-namespace ndn {
-namespace pib {
-
-using std::map;
-
-ResponseCache::ResponseCache()
-{
-}
-
-
-shared_ptr<const Data>
-ResponseCache::find(const Name& dataName, bool hasVersion) const
-{
-  if (!hasVersion) {
-    Storage::const_iterator it = m_storage.find(dataName);
-    if (it != m_storage.end())
-      return it->second;
-    else
-      return shared_ptr<const Data>();
-  }
-  else {
-    Storage::const_iterator it = m_storage.find(dataName.getPrefix(-1));
-    if (it != m_storage.end() && it->second->getName() == dataName)
-      return it->second;
-    else
-      return shared_ptr<const Data>();
-  }
-}
-
-void
-ResponseCache::insert(const Data& data)
-{
-  data.getName().at(-1).toVersion(); // ensures last component is version
-  m_storage[data.getName().getPrefix(-1)] = data.shared_from_this();
-}
-
-void
-ResponseCache::erase(const Name& dataNameWithoutVersion)
-{
-  m_storage.erase(dataNameWithoutVersion);
-}
-
-void
-ResponseCache::clear()
-{
-  m_storage.clear();
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/response-cache.hpp b/tools/pib/response-cache.hpp
deleted file mode 100644
index 94ecfbb..0000000
--- a/tools/pib/response-cache.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-
-#ifndef NDN_TOOLS_PIB_RESPONSE_CACHE_HPP
-#define NDN_TOOLS_PIB_RESPONSE_CACHE_HPP
-
-#include <ndn-cxx/data.hpp>
-#include <map>
-
-
-namespace ndn {
-namespace pib {
-
-/**
- * @brief ResponseCache is an abstraction of a cache of response made before
- *
- * ResponseCache is used to reduce the number of PibDb lookup and Data signing
- * operations.
- *
- * Eventually, it should be replaced by a formal application level cache. This
- * one is only a temporary module and is used for test.
- */
-class ResponseCache : noncopyable
-{
-public:
-  ResponseCache();
-
-  shared_ptr<const Data>
-  find(const Name& dataName, bool hasVersion = false) const;
-
-  /**
-   * @brief Insert a data packet into cache
-   *
-   * Name of the inserted data must end with a version component
-   *
-   * @param data Data to insert. It MUST have been created with make_shared.
-   */
-  void
-  insert(const Data& data);
-
-  void
-  erase(const Name& dataNameWithoutVersion);
-
-  void
-  clear();
-
-private:
-  typedef std::map<Name, shared_ptr<const Data> > Storage;
-
-  Storage m_storage;
-};
-
-} // namespace ndn
-} // namespace pib
-
-#endif // NDN_TOOLS_PIB_RESPONSE_CACHE_HPP
diff --git a/tools/pib/update-query-processor.cpp b/tools/pib/update-query-processor.cpp
deleted file mode 100644
index 7e42c55..0000000
--- a/tools/pib/update-query-processor.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-
-#include "update-query-processor.hpp"
-#include "encoding/pib-encoding.hpp"
-#include "pib.hpp"
-
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace pib {
-
-using std::string;
-
-const size_t UpdateQueryProcessor::UPDATE_QUERY_LENGTH = 9;
-const Name UpdateQueryProcessor::PIB_PREFIX("/localhost/pib");
-
-UpdateQueryProcessor::UpdateQueryProcessor(PibDb& db, Pib& pib)
-  : m_db(db)
-  , m_pib(pib)
-{
-}
-
-std::pair<bool, Block>
-UpdateQueryProcessor::operator()(const Interest& interest)
-{
-  const Name& interestName = interest.getName();
-
-  // handle pib query: /localhost/pib/[UserName]/update/param/<signed_interest_related_components>
-  if (interestName.size() != UPDATE_QUERY_LENGTH) {
-    // malformed interest, discard
-    return std::make_pair(false, Block());
-  }
-
-  try {
-    UpdateParam param;
-    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
-
-    SignatureInfo sigInfo;
-    sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
-
-    // sigInfo must have KeyLocator.Name if the interest passed validation.
-    Name signerName;
-    signerName = sigInfo.getKeyLocator().getName();
-
-    switch (param.getEntityType()) {
-    case tlv::pib::User:
-      return processUpdateUserQuery(param, signerName);
-    case tlv::pib::Identity:
-      return processUpdateIdQuery(param, signerName);
-    case tlv::pib::PublicKey:
-      return processUpdateKeyQuery(param, signerName);
-    case tlv::pib::Certificate:
-      return processUpdateCertQuery(param, signerName);
-    default:
-      {
-        PibError error(ERR_WRONG_PARAM,
-                       "entity type is not supported: " +
-                       boost::lexical_cast<string>(param.getEntityType()));
-        return std::make_pair(true, error.wireEncode());
-      }
-    }
-  }
-  catch (const PibDb::Error& e) {
-    PibError error(ERR_INTERNAL_ERROR, e.what());
-    return std::make_pair(true, error.wireEncode());
-  }
-  catch (const tlv::Error& e) {
-    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
-    return std::make_pair(true, error.wireEncode());
-  }
-}
-
-std::pair<bool, Block>
-UpdateQueryProcessor::processUpdateUserQuery(const UpdateParam& param, const Name& signerName)
-{
-  Name expectedId = m_db.getMgmtCertificate()->getPublicKeyName().getPrefix(-1);
-  Name targetId = param.getUser().getMgmtCert().getPublicKeyName().getPrefix(-1);
-  Name signerId = IdentityCertificate::certificateNameToPublicKeyName(signerName).getPrefix(-1);
-
-  if (expectedId == targetId && expectedId == signerId) {
-    m_db.updateMgmtCertificate(param.getUser().getMgmtCert());
-    m_pib.setMgmtCert(make_shared<IdentityCertificate>(param.getUser().getMgmtCert()));
-    return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-  }
-
-  PibError error(ERR_WRONG_PARAM, "not allowed to update user");
-  return std::make_pair(true, error.wireEncode());
-}
-
-std::pair<bool, Block>
-UpdateQueryProcessor::processUpdateIdQuery(const UpdateParam& param, const Name& signerName)
-{
-  const Name& identity = param.getIdentity().getIdentity();
-  if (!isUpdateAllowed(TYPE_ID, identity, signerName, param.getDefaultOpt())) {
-    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  // add the identity
-  m_db.addIdentity(identity);
-
-  // set the identity as user default if it is requested.
-  const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
-  if (DEFAULT_OPT_USER_MASK & defaultOpt) {
-    m_db.setDefaultIdentity(identity);
-  }
-
-  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-}
-
-std::pair<bool, Block>
-UpdateQueryProcessor::processUpdateKeyQuery(const UpdateParam& param, const Name& signerName)
-{
-  const Name& keyName = param.getPublicKey().getKeyName();
-  if (!isUpdateAllowed(TYPE_KEY, keyName, signerName, param.getDefaultOpt())) {
-    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  Name identity = keyName.getPrefix(-1);
-
-  // add the key
-  m_db.addKey(keyName, param.getPublicKey().getPublicKey());
-
-  const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
-  if (DEFAULT_OPT_ID_MASK & defaultOpt) // set the key as identity default if requested.
-    m_db.setDefaultKeyNameOfIdentity(keyName);
-  if (DEFAULT_OPT_USER_MASK & defaultOpt) // set the identity as user default if requested.
-    m_db.setDefaultIdentity(identity);
-
-  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-}
-
-std::pair<bool, Block>
-UpdateQueryProcessor::processUpdateCertQuery(const UpdateParam& param, const Name& signerName)
-{
-  const IdentityCertificate& cert = param.getCertificate().getCertificate();
-  const Name& certName = cert.getName();
-  if (!isUpdateAllowed(TYPE_CERT, certName, signerName, param.getDefaultOpt())) {
-    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
-    return std::make_pair(true, error.wireEncode());
-  }
-
-  const Name& keyName = cert.getPublicKeyName();
-  Name identity = keyName.getPrefix(-1);
-
-  // add certificate
-  m_db.addCertificate(cert);
-
-  const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
-  if (DEFAULT_OPT_KEY_MASK & defaultOpt) // set the cert as key default if requested.
-    m_db.setDefaultCertNameOfKey(certName);
-  if (DEFAULT_OPT_ID_MASK & defaultOpt) // set the key as identity default if requested.
-    m_db.setDefaultKeyNameOfIdentity(keyName);
-  if (DEFAULT_OPT_USER_MASK & defaultOpt) // set the identity as user default if requested.
-    m_db.setDefaultIdentity(identity);
-
-  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
-}
-
-bool
-UpdateQueryProcessor::isUpdateAllowed(const pib::Type targetType,
-                                      const Name& targetName,
-                                      const Name& signer,
-                                      const pib::DefaultOpt defaultOpt) const
-{
-  // Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
-  // that prefix will be rejected.
-  if (PIB_PREFIX.isPrefixOf(targetName))
-    return false;
-
-  // A request is wrong if
-  // 1) it wants to change the default setting of an identity, but the target is not key nor cert
-  // 2) it wants to change the default setting of a key, but the target is not cert
-  if ((defaultOpt == DEFAULT_OPT_ID && (targetType != TYPE_KEY && targetType != TYPE_CERT)) ||
-      (defaultOpt == DEFAULT_OPT_KEY && targetType != TYPE_CERT))
-    return false;
-
-
-  // Rules for other items:
-  //
-  //    signer          | adding privilege         | default setting privilege
-  //    ================+==========================+============================================
-  //    local mgmt key  | any id, key, and cert    | the default id,
-  //                    |                          | the default key of any id,
-  //                    |                          | the default cert of any key of any id
-  //    ----------------+--------------------------+--------------------------------------------
-  //    default key of  | any id, key, and cert    | the default key of the id and its sub ids,
-  //    an id           | under the id's namespace | the default cert of any key of the id
-  //                    |                          | and its sub ids
-  //    ----------------+--------------------------+--------------------------------------------
-  //    non-default key | any cert of the key      | the default cert of the key
-  //    of an id
-
-  const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
-  const Name& signerId = signerKeyName.getPrefix(-1);
-
-  bool hasSignerDefaultKey = true;
-  Name signerDefaultKeyName;
-  try {
-    signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
-  }
-  catch (PibDb::Error&) {
-    hasSignerDefaultKey = false;
-  }
-
-  Name mgmtCertName;
-  try {
-    mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
-  }
-  catch (PibDb::Error&) {
-    return false;
-  }
-
-  if (signer == mgmtCertName) {
-    // signer is current management key, anything is allowed.
-    return true;
-  }
-  else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
-    // signer is an identity's default key
-    if (!signerId.isPrefixOf(targetName))
-      return false;
-
-    // check default setting
-    // user default setting is not allowed
-    if (defaultOpt == DEFAULT_OPT_USER)
-      return false;
-    else
-      return true;
-  }
-  else {
-    // non-default key
-    if (targetType != TYPE_CERT)
-      return false;
-
-    // check if it is for the key's cert
-    if (IdentityCertificate::certificateNameToPublicKeyName(targetName) != signerKeyName)
-      return false;
-
-    if (defaultOpt == DEFAULT_OPT_USER || defaultOpt == DEFAULT_OPT_ID)
-      return false;
-    else
-      return true;
-  }
-}
-
-} // namespace pib
-} // namespace ndn
diff --git a/tools/pib/update-query-processor.hpp b/tools/pib/update-query-processor.hpp
deleted file mode 100644
index 226023c..0000000
--- a/tools/pib/update-query-processor.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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.
- *
- * ndn-tools 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
- * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef NDN_TOOLS_PIB_UPDATE_QUERY_PROCESSOR_HPP
-#define NDN_TOOLS_PIB_UPDATE_QUERY_PROCESSOR_HPP
-
-#include "pib-db.hpp"
-#include "encoding/update-param.hpp"
-#include <ndn-cxx/interest.hpp>
-#include <utility>
-
-namespace ndn {
-namespace pib {
-
-class Pib;
-
-/// @brief Processing unit for PIB update query
-class UpdateQueryProcessor : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Constructor
-   *
-   * @param db The pib database.
-   */
-  UpdateQueryProcessor(PibDb& db, Pib& pib);
-
-  std::pair<bool, Block>
-  operator()(const Interest& interest);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  /**
-   * @brief Determine if an update command is allowed.
-   *
-   * @param targetType The type of the target that will be updated.
-   * @param targetName The name of the target that will be updated.
-   * @param signer     The name of the command signer.
-   * @param defaultOpt The default settings that is requested to update.
-   */
-  bool
-  isUpdateAllowed(const pib::Type targetType,
-                  const Name& targetName,
-                  const Name& signer,
-                  const pib::DefaultOpt defaultOpt) const;
-
-private:
-  std::pair<bool, Block>
-  processUpdateUserQuery(const UpdateParam& param, const Name& signerName);
-
-  std::pair<bool, Block>
-  processUpdateIdQuery(const UpdateParam& param, const Name& signerName);
-
-  std::pair<bool, Block>
-  processUpdateKeyQuery(const UpdateParam& param, const Name& signerName);
-
-  std::pair<bool, Block>
-  processUpdateCertQuery(const UpdateParam& param, const Name& signerName);
-
-private:
-  static const size_t UPDATE_QUERY_LENGTH;
-  static const Name PIB_PREFIX;
-
-  PibDb&  m_db;
-  Pib& m_pib;
-};
-
-} // namespace pib
-} // namespace ndn
-
-#endif // NDN_TOOLS_PIB_UPDATE_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/wscript b/tools/pib/wscript
deleted file mode 100644
index 344cbaf..0000000
--- a/tools/pib/wscript
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-top = '../..'
-
-def build(bld):
-    bld(features=['cxx'],
-        name="pib-objects",
-        target="pib-objects",
-        source=bld.path.ant_glob('**/*.cpp', excl=['ndn-pib.cpp']),
-        use='core-objects',
-        install_path=None)
-
-    bld(features=['cxx', 'cxxprogram'],
-        target='../../bin/ndn-pib',
-        source='ndn-pib.cpp',
-        use='pib-objects')
diff --git a/tools/wscript b/tools/wscript
index e682e51..b374494 100644
--- a/tools/wscript
+++ b/tools/wscript
@@ -19,8 +19,6 @@
     enabled_tools = set() # --enable-X
     disabled_tools = set() # --disable-X
 
-    Options.options.disable_pib = True
-
     for subdir in conf.path.ant_glob('*', dir=True, src=False):
         tool = subdir.path_from(conf.path)
         all_tools.add(tool)
