diff --git a/docs/ChronoChat.rst b/docs/ChronoChat.rst
deleted file mode 100644
index d5614f4..0000000
--- a/docs/ChronoChat.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-ChronoChat - A Serverless Chat Application in NDN
-=================================================
-
-ChatRoom
---------
-
-The sync prefix of a chatroom is defined as: ``/ndn/broadcast/ChronoChat/[chatroom]``.
-
-
-..
-   Invitation
-   ----------
-
-   Every application listen to a invitation prefix: ``/<routing_hint>/<user_prefix>/CHRONOCHAT-INVITATION``
diff --git a/docs/FAQ.rst b/docs/FAQ.rst
deleted file mode 100644
index cde88d8..0000000
--- a/docs/FAQ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-FAQ
-===
diff --git a/docs/index.rst b/docs/index.rst
index 19931e9..872ace5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,32 +1,14 @@
 ChronoSync - A synchronization Protocol in NDN
 ==============================================
 
-..
-   NFD is a network forwarder that implements and evolves together with the Named Data
-   Networking (NDN) `protocol <http://named-data.net/doc/ndn-tlv/>`__. After the initial
-   release, NFD will become a core component of the `NDN Platform
-   <http://named-data.net/codebase/platform/>`__ and will follow the same release cycle.
-
-ChronoSync Documentation
-------------------------
-
 .. toctree::
    :hidden:
    :maxdepth: 3
 
    DesignDoc
-   FAQ
-   ChronoChat
-
-..
-   INSTALL
 
 * :doc:`DesignDoc`
 
-* :doc:`FAQ`
-
-* :doc:`ChronoChat`
-
 **Additional documentation**
 
 * `API documentation (doxygen) <doxygen/annotated.html>`_
@@ -39,8 +21,6 @@
 License
 -------
 
-..
-   NFD is an open and free software package licensed under GPL 3.0 license and is the
-   centerpiece of our committement to making NDN's core technology open and free to all
-   Internet users and developers. For more information about the licensing details and
-   limitation, refer to `COPYING.md <https://github.com/named-data/NFD/blob/master/COPYING.md>`_.
+ChronoSync 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.
diff --git a/obsolete/sync-intro-certificate.h b/obsolete/sync-intro-certificate.h
deleted file mode 100644
index d6783ce..0000000
--- a/obsolete/sync-intro-certificate.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012-2014 University of California, Los Angeles
- *
- * This file is part of ChronoSync, synchronization library for distributed realtime
- * applications for NDN.
- *
- * ChronoSync 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.
- *
- * ChronoSync 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
- * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
- */
-
-#ifndef SYNC_INTRO_CERTIFICATE_H
-#define SYNC_INTRO_CERTIFICATE_H
-
-#include <ndn-cxx/security/identity-certificate.hpp>
-#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
-
-namespace Sync {
-
-class IntroCertificate : public ndn::Data
-{
-  /**
-   * Naming convention of IntroCertificate:
-   * /<sync_prefix>/CHRONOS-INTRO-CERT/introducee_certname/introducer_certname/version
-   * Content: introducee's identity certificate;
-   * KeyLocator: introducer's identity certificate;
-   */
-public:
-  struct Error : public ndn::Data::Error { Error(const std::string &what) : ndn::Data::Error(what) {} };
-
-  IntroCertificate()
-  {}
-
-  /**
-   * @brief Construct IntroCertificate from IdentityCertificate
-   *
-   * @param syncPrefix
-   * @param introduceeCert
-   * @param introducerName
-   */
-  IntroCertificate(const ndn::Name& syncPrefix,
-                   const ndn::IdentityCertificate& introduceeCert,
-                   const ndn::Name& introducerCertName); //without version number
-
-  /**
-   * @brief Construct IntroCertificate using a plain data.
-   *
-   * if data is not actually IntroCertificate, Error will be thrown out.
-   *
-   * @param data
-   * @throws ndn::IntroCertificate::Error.
-   */
-  IntroCertificate(const ndn::Data& data);
-
-  virtual
-  ~IntroCertificate() {};
-
-  const ndn::IdentityCertificate&
-  getIntroduceeCert() const
-  {
-    return m_introduceeCert;
-  }
-
-  const ndn::Name&
-  getIntroducerCertName() const
-  {
-    return m_introducerCertName;
-  }
-
-  const ndn::Name&
-  getIntroduceeCertName() const
-  {
-    return m_introduceeCertName;
-  }
-
-private:
-  ndn::Name m_syncPrefix;
-  ndn::IdentityCertificate m_introduceeCert;
-  ndn::Name m_introducerCertName;
-  ndn::Name m_introduceeCertName;
-};
-
-inline
-IntroCertificate::IntroCertificate(const ndn::Name& syncPrefix,
-                                   const ndn::IdentityCertificate& introduceeCert,
-                                   const ndn::Name& introducerCertName)
-  : m_syncPrefix(syncPrefix)
-  , m_introduceeCert(introduceeCert)
-  , m_introducerCertName(introducerCertName)
-  , m_introduceeCertName(introduceeCert.getName().getPrefix(-1))
-{
-  // Naming convention /<sync_prefix>/CHRONOS-INTRO-CERT/introducee_certname/introducer_certname/version
-  ndn::Name dataName = m_syncPrefix;
-  dataName.append("CHRONOS-INTRO-CERT")
-    .append(m_introduceeCertName.wireEncode())
-    .append(m_introducerCertName.wireEncode())
-    .appendVersion();
-
-  setName(dataName);
-  setContent(m_introduceeCert.wireEncode());
-}
-
-inline
-IntroCertificate::IntroCertificate(const ndn::Data& data)
-  : Data(data)
-{
-  // Naming convention /<sync_prefix>/CHRONOS-INTRO-CERT/introducee_certname/introducer_certname/version
-  ndn::Name dataName = data.getName();
-
-  if(dataName.size() < 4 || dataName.get(-4).toUri() != "CHRONOS-INTRO-CERT")
-    throw Error("Not a Sync::IntroCertificate");
-
-  try
-    {
-      m_introduceeCert.wireDecode(data.getContent().blockFromValue());
-      m_introducerCertName.wireDecode(dataName.get(-2).blockFromValue());
-      m_introduceeCertName.wireDecode(dataName.get(-3).blockFromValue());
-      m_syncPrefix = dataName.getPrefix(-4);
-    }
-  catch(ndn::IdentityCertificate::Error& e)
-    {
-      throw Error("Cannot decode introducee cert");
-    }
-  catch(ndn::Name::Error& e)
-    {
-      throw Error("Cannot decode name");
-    }
-  catch(ndn::Block::Error& e)
-    {
-      throw Error("Cannot decode block name");
-    }
-
-  if(m_introduceeCertName != m_introduceeCert.getName().getPrefix(-1))
-    throw Error("Invalid Sync::IntroCertificate (inconsistent introducee name)");
-
-  ndn::Name keyLocatorName;
-  try
-    {
-      ndn::SignatureSha256WithRsa sig(data.getSignature());
-      keyLocatorName = sig.getKeyLocator().getName();
-    }
-  catch(ndn::KeyLocator::Error& e)
-    {
-      throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#1)");
-    }
-  catch(ndn::SignatureSha256WithRsa::Error& e)
-    {
-      throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#2)");
-    }
-
-  if(m_introducerCertName != keyLocatorName)
-    throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#3)");
-}
-
-
-} // namespace Sync
-
-#endif //SYNC_INTRO_CERTIFICATE_H
diff --git a/obsolete/sync-validator.cc b/obsolete/sync-validator.cc
deleted file mode 100644
index e5cc0f5..0000000
--- a/obsolete/sync-validator.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012-2014 University of California, Los Angeles
- *
- * This file is part of ChronoSync, synchronization library for distributed realtime
- * applications for NDN.
- *
- * ChronoSync 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.
- *
- * ChronoSync 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
- * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
- */
-
-#include "sync-validator.h"
-#include "sync-logging.h"
-#include <ndn-cxx/security/certificate-cache-ttl.hpp>
-#include <queue>
-
-using namespace ndn;
-
-INIT_LOGGER ("SyncValidator")
-
-namespace Sync {
-
-using ndn::shared_ptr;
-
-const shared_ptr<CertificateCache> SyncValidator::DefaultCertificateCache = shared_ptr<CertificateCache>();
-const shared_ptr<SecRuleRelative> SyncValidator::DefaultDataRule = shared_ptr<SecRuleRelative>();
-
-SyncValidator::SyncValidator(const Name& prefix,
-                             const IdentityCertificate& anchor,
-                             Face& face,
-                             const PublishCertCallback& publishCertCallback,
-                             shared_ptr<SecRuleRelative> rule,
-                             shared_ptr<CertificateCache> certificateCache,
-                             const int stepLimit)
-  : Validator(face)
-  , m_prefix(prefix)
-  , m_anchor(anchor)
-  , m_stepLimit(stepLimit)
-  , m_certificateCache(certificateCache)
-  , m_publishCertCallback(publishCertCallback)
-  , m_dataRule(rule)
-{
-  if(!static_cast<bool>(m_certificateCache))
-    m_certificateCache = make_shared<CertificateCacheTtl>(boost::ref(m_face.getIoService()));
-
-  Name certPrefix = prefix;
-  certPrefix.append("CHRONOS-INTRO-CERT");
-  m_prefixId = m_face.setInterestFilter(certPrefix,
-                                         bind(&SyncValidator::onCertInterest, this, _1, _2),
-                                         bind(&SyncValidator::onCertRegisterFailed, this, _1, _2));
-
-  setAnchor(m_anchor);
-}
-
-void
-SyncValidator::deriveTrustNodes()
-{
-  std::queue<Name> nodeQueue;
-
-  // Clear existing trust nodes.
-  m_trustedNodes.clear();
-
-  // Add the trust anchor.
-  IntroNode origin(m_anchor);
-  m_trustedNodes[origin.name()] = m_anchor.getPublicKeyInfo();
-  nodeQueue.push(origin.name());
-
-  // BFS trusted nodes.
-  while(!nodeQueue.empty())
-    {
-      // Get next trusted node to process.
-      Nodes::const_iterator it = m_introNodes.find(nodeQueue.front());
-      const PublicKey& publicKey = m_trustedNodes[nodeQueue.front()];
-
-      if(it != m_introNodes.end())
-        {
-          // If the trusted node exists in the graph.
-          IntroNode::const_iterator eeIt = it->second.introduceeBegin();
-          IntroNode::const_iterator eeEnd = it->second.introduceeEnd();
-          for(; eeIt != eeEnd; eeIt++)
-            {
-              // Check the nodes introduced by the trusted node.
-              Edges::const_iterator edgeIt = m_introCerts.find(*eeIt);
-              if(edgeIt != m_introCerts.end()
-                 && m_trustedNodes.find(edgeIt->second.getIntroduceeCertName()) == m_trustedNodes.end()
-                 && verifySignature(edgeIt->second, publicKey))
-                {
-                  // If the introduced node can be validated, add it into trusted node set and the node queue.
-                  m_trustedNodes[edgeIt->second.getIntroduceeCertName()] = edgeIt->second.getIntroduceeCert().getPublicKeyInfo();
-                  nodeQueue.push(edgeIt->second.getIntroduceeCertName());
-                }
-            }
-        }
-      nodeQueue.pop();
-    }
-}
-
-void
-SyncValidator::checkPolicy (const Data& data,
-                            int stepCount,
-                            const OnDataValidated& onValidated,
-                            const OnDataValidationFailed& onValidationFailed,
-                            std::vector<shared_ptr<ValidationRequest> >& nextSteps)
-{
-  if(m_stepLimit == stepCount)
-    return onValidationFailed(data.shared_from_this(),
-                              "Maximum steps of validation reached: " + data.getName().toUri());
-
-  if(m_prefix.isPrefixOf(data.getName()) || (static_cast<bool>(m_dataRule) && m_dataRule->satisfy(data)))
-    {
-      try
-        {
-          SignatureSha256WithRsa sig(data.getSignature());
-          Name keyLocatorName = sig.getKeyLocator().getName();
-
-          TrustNodes::const_iterator it = m_trustedNodes.find(keyLocatorName);
-          if(m_trustedNodes.end() != it)
-            {
-              if(verifySignature(data, sig, it->second))
-                return onValidated(data.shared_from_this());
-              else
-                return onValidationFailed(data.shared_from_this(),
-                                          "Cannot verify signature: " + data.getName().toUri());
-            }
-          else
-            {
-              _LOG_DEBUG("I am: " << m_anchor.getName().get(0).toUri() << " for " << data.getName());
-
-              Name interestName = m_prefix;
-              interestName.append("CHRONOS-INTRO-CERT").append(keyLocatorName.wireEncode());
-              Interest interest(interestName);
-              interest.setInterestLifetime(time::milliseconds(500));
-
-              OnDataValidated onKeyValidated = bind(&SyncValidator::onCertificateValidated, this,
-                                                    _1, data.shared_from_this(), onValidated, onValidationFailed);
-
-              OnDataValidationFailed onKeyValidationFailed = bind(&SyncValidator::onCertificateValidationFailed, this,
-                                                                  _1, _2, data.shared_from_this(), onValidationFailed);
-
-              shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest,
-                                                                                      onKeyValidated,
-                                                                                      onKeyValidationFailed,
-                                                                                      1,
-                                                                                      stepCount + 1);
-              nextSteps.push_back(nextStep);
-
-              return;
-            }
-        }
-      catch(SignatureSha256WithRsa::Error& e)
-        {
-          return onValidationFailed(data.shared_from_this(),
-                                    "Not SignatureSha256WithRsa signature: " + std::string(e.what()));
-        }
-      catch(KeyLocator::Error& e)
-        {
-          return onValidationFailed(data.shared_from_this(),
-                                    "Key Locator is not a name: " + data.getName().toUri());
-        }
-    }
-  else
-    return onValidationFailed(data.shared_from_this(),
-                              "No rule or rule is not satisfied: " + data.getName().toUri());
-}
-
-void
-SyncValidator::checkPolicy (const Interest& interest,
-                            int stepCount,
-                            const OnInterestValidated& onValidated,
-                            const OnInterestValidationFailed& onValidationFailed,
-                            std::vector<shared_ptr<ValidationRequest> >& nextSteps)
-{
-  onValidationFailed(interest.shared_from_this(),  "No policy for signed interest checking");
-}
-
-void
-SyncValidator::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
-                                      const shared_ptr<const Data>& data,
-                                      const OnDataValidated& onValidated,
-                                      const OnDataValidationFailed& onValidationFailed)
-{
-  try
-    {
-      IntroCertificate introCert(*signCertificate);
-      addParticipant(introCert);
-
-      if(verifySignature(*data, introCert.getIntroduceeCert().getPublicKeyInfo()))
-        return onValidated(data);
-      else
-        return onValidationFailed(data,
-                                  "Cannot verify signature: " + data->getName().toUri());
-    }
-  catch(IntroCertificate::Error& e)
-    {
-      return onValidationFailed(data,
-                                "Intro cert decoding error: " + std::string(e.what()));
-    }
-}
-
-void
-SyncValidator::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
-                                             const std::string& failureInfo,
-                                             const shared_ptr<const Data>& data,
-                                             const OnDataValidationFailed& onValidationFailed)
-{
-  onValidationFailed(data, failureInfo);
-}
-
-void
-SyncValidator::onCertInterest(const Name& prefix, const Interest& interest)
-{
-  Name name = interest.getName();
-  Edges::const_iterator it = m_introCerts.begin();
-  for(; it != m_introCerts.end(); it++)
-    {
-      if(name.isPrefixOf(it->first))
-        {
-          m_face.put(it->second);
-          return;
-        }
-    }
-}
-
-void
-SyncValidator::onCertRegisterFailed(const Name& prefix, const std::string& msg)
-{
-  _LOG_DEBUG("SyncValidator::onCertRegisterFailed: " << msg);
-}
-
-} // namespace Sync
diff --git a/obsolete/sync-validator.h b/obsolete/sync-validator.h
deleted file mode 100644
index 9e5f4df..0000000
--- a/obsolete/sync-validator.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012-2014 University of California, Los Angeles
- *
- * This file is part of ChronoSync, synchronization library for distributed realtime
- * applications for NDN.
- *
- * ChronoSync 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.
- *
- * ChronoSync 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
- * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
- */
-
-#ifndef SYNC_VALIDATOR_H
-#define SYNC_VALIDATOR_H
-
-#include "sync-intro-certificate.h"
-#include <ndn-cxx/security/validator.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/security/sec-rule-relative.hpp>
-#include <ndn-cxx/security/certificate-cache.hpp>
-#include <map>
-
-namespace Sync {
-
-class SyncValidator : public ndn::Validator
-{
-public:
-  typedef ndn::function< void (const uint8_t*, size_t, int) > PublishCertCallback;
-
-  struct Error : public ndn::Validator::Error { Error(const std::string &what) : ndn::Validator::Error(what) {} };
-
-  static const ndn::shared_ptr<ndn::CertificateCache> DefaultCertificateCache;
-  static const ndn::shared_ptr<ndn::SecRuleRelative> DefaultDataRule;
-
-  SyncValidator(const ndn::Name& prefix,
-                const ndn::IdentityCertificate& anchor,
-                ndn::Face& face,
-                const PublishCertCallback& publishCertCallback,
-                ndn::shared_ptr<ndn::SecRuleRelative> rule = DefaultDataRule,
-                ndn::shared_ptr<ndn::CertificateCache> certificateCache = DefaultCertificateCache,
-                const int stepLimit = 10);
-
-  virtual
-  ~SyncValidator()
-  {
-    m_face.unsetInterestFilter(m_prefixId);
-  }
-
-  /**
-   * @brief Set the trust anchor
-   *
-   * The anchor should be the participant's own certificate.
-   * This anchor node is the origin of the derived trust graph.
-   * Once the new anchor is set, derive the TrustNode set.
-   *
-   * @param anchor.
-   */
-  inline void
-  setAnchor(const ndn::IdentityCertificate& anchor);
-
-  /**
-   * @brief Add a node into the trust graph.
-   *
-   * The method also create an edge from trust anchor to the node.
-   *
-   * @param introducee.
-   * @return IntroCertificate for the introducee.
-   */
-  inline ndn::shared_ptr<const IntroCertificate>
-  addParticipant(const ndn::IdentityCertificate& introducee);
-
-  /**
-   * @brief Add an edge into the trust graph.
-   *
-   * Create nodes if it is one of the edge's ends and does not exist in the graph.
-   *
-   * @param introCert.
-   */
-  inline void
-  addParticipant(const IntroCertificate& introCert);
-
-  inline void
-  getIntroCertNames(std::vector<ndn::Name>& list);
-
-  inline const IntroCertificate&
-  getIntroCertificate(const ndn::Name& name);
-
-#ifdef _TEST
-  bool
-  canTrust(const ndn::Name& certName)
-  {
-    return (m_trustedNodes.find(certName.getPrefix(-1)) != m_trustedNodes.end());
-  }
-#endif //_DEBUG
-
-protected:
-  /***********************
-   * From ndn::Validator *
-   ***********************/
-  virtual void
-  checkPolicy (const ndn::Data& data,
-               int stepCount,
-               const ndn::OnDataValidated& onValidated,
-               const ndn::OnDataValidationFailed& onValidationFailed,
-               std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps);
-
-  virtual void
-  checkPolicy (const ndn::Interest& interest,
-               int stepCount,
-               const ndn::OnInterestValidated& onValidated,
-               const ndn::OnInterestValidationFailed& onValidationFailed,
-               std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps);
-private:
-  void
-  deriveTrustNodes();
-
-
-  void
-  onCertificateValidated(const ndn::shared_ptr<const ndn::Data>& signCertificate,
-                         const ndn::shared_ptr<const ndn::Data>& data,
-                         const ndn::OnDataValidated& onValidated,
-                         const ndn::OnDataValidationFailed& onValidationFailed);
-
-  void
-  onCertificateValidationFailed(const ndn::shared_ptr<const ndn::Data>& signCertificate,
-                                const std::string& failureInfo,
-                                const ndn::shared_ptr<const ndn::Data>& data,
-                                const ndn::OnDataValidationFailed& onValidationFailed);
-
-  void
-  onCertInterest (const ndn::Name& prefix, const ndn::Interest& interest);
-
-  void
-  onCertRegisterFailed(const ndn::Name& prefix, const std::string& msg);
-
-private:
-  class IntroNode;
-
-  // Syncprefix
-  ndn::Name m_prefix;
-
-  // The map
-  typedef std::map<const ndn::Name, IntroNode> Nodes;
-  typedef std::map<const ndn::Name, IntroCertificate> Edges;
-  Nodes m_introNodes;
-  Edges m_introCerts;
-
-  // The derived trust info
-  typedef std::map<const ndn::Name, ndn::PublicKey> TrustNodes;
-  ndn::IdentityCertificate m_anchor;
-  TrustNodes m_trustedNodes;
-
-  // others
-  int m_stepLimit;
-  ndn::shared_ptr<ndn::CertificateCache> m_certificateCache;
-  ndn::KeyChain m_keychain;
-  const ndn::RegisteredPrefixId* m_prefixId;
-  PublishCertCallback m_publishCertCallback;
-  ndn::shared_ptr<ndn::SecRuleRelative> m_dataRule;
-
-  class IntroNode
-  {
-  public:
-    typedef std::vector<ndn::Name>::const_iterator const_iterator;
-
-    IntroNode()
-    {}
-
-    IntroNode(const ndn::IdentityCertificate& idCert)
-      : m_nodeName(idCert.getName().getPrefix(-1))
-    {}
-
-    IntroNode(const IntroCertificate& introCert, bool isIntroducer)
-    {
-      if(isIntroducer)
-        {
-          m_nodeName = introCert.getIntroducerCertName();
-          m_introduceeCerts.push_back(introCert.getName());
-        }
-      else
-        {
-          m_nodeName = introCert.getIntroduceeCertName();
-          m_introducerCerts.push_back(introCert.getName());
-        }
-    }
-
-    ~IntroNode()
-    {}
-
-    const ndn::Name&
-    name() const
-    {
-      return m_nodeName;
-    }
-
-    const_iterator
-    introducerBegin() const
-    {
-      return m_introducerCerts.begin();
-    }
-
-    const_iterator
-    introducerEnd() const
-    {
-      return m_introducerCerts.end();
-    }
-
-    const_iterator
-    introduceeBegin() const
-    {
-      return m_introduceeCerts.begin();
-    }
-
-    const_iterator
-    introduceeEnd() const
-    {
-      return m_introduceeCerts.end();
-    }
-
-    void
-    addIntroCertAsIntroducer(const ndn::Name& introCertName)
-    {
-      if(std::find(m_introduceeCerts.begin(), m_introduceeCerts.end(), introCertName) == m_introduceeCerts.end())
-        m_introduceeCerts.push_back(introCertName);
-    }
-
-    void
-    addIntroCertAsIntroducee(const ndn::Name& introCertName)
-    {
-      if(std::find(m_introducerCerts.begin(), m_introducerCerts.end(), introCertName) == m_introducerCerts.end())
-        m_introducerCerts.push_back(introCertName);
-    }
-
-  private:
-    ndn::Name m_nodeName;
-    std::vector<ndn::Name> m_introducerCerts;
-    std::vector<ndn::Name> m_introduceeCerts;
-  };
-
-};
-
-inline void
-SyncValidator::setAnchor(const ndn::IdentityCertificate& anchor)
-{
-  m_anchor = anchor;
-
-  // Add anchor into trust graph if it does not exist.
-  IntroNode origin(m_anchor);
-  Nodes::const_iterator nodeIt = m_introNodes.find(origin.name());
-  if(nodeIt == m_introNodes.end())
-    m_introNodes[origin.name()] = origin;
-
-  deriveTrustNodes();
-}
-
-inline void
-SyncValidator::addParticipant(const IntroCertificate& introCert)
-{
-  // Check if the edge has been added before.
-  ndn::Name certName = introCert.getName();
-  Edges::const_iterator edgeIt = m_introCerts.find(certName);
-  if(edgeIt != m_introCerts.end())
-    return; // the edge has been added before.
-
-  m_introCerts[certName] = introCert;
-
-  // Check if the introducer has been added.
-  Nodes::iterator nodeIt = m_introNodes.find(introCert.getIntroducerCertName());
-  if(nodeIt == m_introNodes.end())
-    {
-      IntroNode node(introCert, true);
-      m_introNodes[node.name()] = node;
-    }
-  else
-    nodeIt->second.addIntroCertAsIntroducer(certName);
-
-  // Check if the introducee has been added.
-  nodeIt = m_introNodes.find(introCert.getIntroduceeCertName());
-  if(nodeIt == m_introNodes.end())
-    {
-      IntroNode node(introCert, false);
-      m_introNodes[node.name()] = node;
-    }
-  else
-    nodeIt->second.addIntroCertAsIntroducee(certName);
-
-  // Check if the introducer is one of the trusted nodes.
-  TrustNodes::const_iterator trustNodeIt = m_trustedNodes.find(introCert.getIntroducerCertName());
-  if(trustNodeIt != m_trustedNodes.end() && verifySignature(introCert, trustNodeIt->second))
-    // If the introducee, add it into trusted node set.
-    m_trustedNodes[introCert.getIntroduceeCertName()] = introCert.getIntroduceeCert().getPublicKeyInfo();
-}
-
-inline ndn::shared_ptr<const IntroCertificate>
-SyncValidator::addParticipant(const ndn::IdentityCertificate& introducee)
-{
-  ndn::shared_ptr<IntroCertificate> introCert
-    = ndn::shared_ptr<IntroCertificate>(new IntroCertificate(m_prefix, introducee, m_anchor.getName().getPrefix(-1)));
-
-  m_keychain.sign(*introCert, m_anchor.getName());
-
-  addParticipant(*introCert);
-
-  // Publish certificate as normal data.
-  ndn::Block block = introCert->wireEncode();
-  m_publishCertCallback(block.wire(), block.size(), 1000);
-
-  return introCert;
-}
-
-inline void
-SyncValidator::getIntroCertNames(std::vector<ndn::Name>& list)
-{
-  Edges::const_iterator it = m_introCerts.begin();
-  Edges::const_iterator end = m_introCerts.end();
-  for(; it != end; it++)
-    list.push_back(it->first);
-}
-
-inline const IntroCertificate&
-SyncValidator::getIntroCertificate(const ndn::Name& name)
-{
-  Edges::const_iterator it = m_introCerts.find(name);
-  if(it != m_introCerts.end())
-    return it->second;
-  else
-    throw Error("No cert");
-}
-
-} // namespace Sync
-
-#endif //SYNC_VALIDATOR_H
diff --git a/obsolete/tests/test-sync-validator.cpp.outdated b/obsolete/tests/test-sync-validator.cpp.outdated
deleted file mode 100644
index 7c8c300..0000000
--- a/obsolete/tests/test-sync-validator.cpp.outdated
+++ /dev/null
@@ -1,349 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012-2014 University of California, Los Angeles
- *
- * This file is part of ChronoSync, synchronization library for distributed realtime
- * applications for NDN.
- *
- * ChronoSync 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.
- *
- * ChronoSync 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
- * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <boost/test/unit_test.hpp>
-#include "sync-validator.h"
-
-#include <boost/lexical_cast.hpp>
-#include <boost/asio.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-
-BOOST_AUTO_TEST_SUITE(TestSyncValidator)
-
-void
-onValidated(const ndn::shared_ptr<const ndn::Data>& data)
-{
-  BOOST_CHECK(true);
-}
-
-void
-onValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
-                   const std::string& failureInfo)
-{
-  BOOST_CHECK(false);
-}
-
-void
-onValidated2(const ndn::shared_ptr<const ndn::Data>& data)
-{
-  BOOST_CHECK(false);
-}
-
-void
-onValidationFailed2(const ndn::shared_ptr<const ndn::Data>& data,
-                    const std::string& failureInfo)
-{
-  BOOST_CHECK(true);
-}
-
-void
-publishData(const uint8_t* buf, size_t len, int freshness)
-{
-}
-
-BOOST_AUTO_TEST_CASE (Graph)
-{
-  using namespace Sync;
-  using namespace ndn;
-
-  Name prefix("/Sync/TestSyncValidator/AddEdge");
-  KeyChain keychain;
-
-  Name identity1("/TestSyncValidator/AddEdge-1/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName1 = keychain.createIdentity(identity1);
-  shared_ptr<IdentityCertificate> anchor = keychain.getCertificate(certName1);
-
-  Name identity2("/TestSyncValidator/AddEdge-2/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName2 = keychain.createIdentity(identity2);
-  shared_ptr<IdentityCertificate> introducer = keychain.getCertificate(certName2);
-
-  Name identity3("/TestSyncValidator/AddEdge-3/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName3 = keychain.createIdentity(identity3);
-  shared_ptr<IdentityCertificate> introducee = keychain.getCertificate(certName3);
-
-  Name identity4("/TestSyncValidator/AddEdge-4/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName4 = keychain.createIdentity(identity4);
-  shared_ptr<IdentityCertificate> introducer2 = keychain.getCertificate(certName4);
-
-  Name identity5("/TestSyncValidator/AddEdge-5/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName5 = keychain.createIdentity(identity5);
-  shared_ptr<IdentityCertificate> introducee2 = keychain.getCertificate(certName5);
-
-  shared_ptr<boost::asio::io_service> ioService = make_shared<boost::asio::io_service>();
-  shared_ptr<Face> face = make_shared<Face>(ref(*ioService));
-  shared_ptr<SecRuleRelative> rule;
-  SyncValidator validator(prefix, *anchor, *face,
-                          bind(&publishData, _1, _2, _3),
-                          rule);
-
-  validator.addParticipant(*introducer);
-  BOOST_CHECK(validator.canTrust(certName2));
-
-  IntroCertificate introCert(prefix, *introducee, certName2.getPrefix(-1));
-  keychain.sign(introCert, certName2);
-  validator.addParticipant(introCert);
-  BOOST_CHECK(validator.canTrust(certName3));
-
-  IntroCertificate introCert1(prefix, *anchor, certName3.getPrefix(-1));
-  keychain.sign(introCert1, certName3);
-  validator.addParticipant(introCert1);
-  validator.setAnchor(*introducer);
-  BOOST_CHECK(validator.canTrust(certName2));
-  BOOST_CHECK(validator.canTrust(certName3));
-  BOOST_CHECK(validator.canTrust(certName1));
-
-  IntroCertificate introCert2(prefix, *introducee2, certName4.getPrefix(-1));
-  keychain.sign(introCert2, certName4);
-  validator.addParticipant(introCert2);
-  BOOST_CHECK(validator.canTrust(certName5) == false);
-  BOOST_CHECK(validator.canTrust(certName4) == false);
-
-  IntroCertificate introCert3(prefix, *introducee, certName5.getPrefix(-1));
-  keychain.sign(introCert3, certName5);
-  validator.addParticipant(introCert3);
-  BOOST_CHECK(validator.canTrust(certName5) == false);
-  BOOST_CHECK(validator.canTrust(certName4) == false);
-
-  validator.setAnchor(*introducee2);
-  BOOST_CHECK(validator.canTrust(certName1));
-  BOOST_CHECK(validator.canTrust(certName2));
-  BOOST_CHECK(validator.canTrust(certName3));
-  BOOST_CHECK(validator.canTrust(certName4) == false);
-  BOOST_CHECK(validator.canTrust(certName5));
-
-
-  keychain.deleteIdentity(identity1);
-  keychain.deleteIdentity(identity2);
-  keychain.deleteIdentity(identity3);
-  keychain.deleteIdentity(identity4);
-  keychain.deleteIdentity(identity5);
-}
-
-BOOST_AUTO_TEST_CASE (OfflineValidate)
-{
-  using namespace Sync;
-  using namespace ndn;
-
-  Name prefix("/Sync/TestSyncValidator/OfflineValidate");
-  KeyChain keychain;
-
-  Name identity1("/TestSyncValidator/OfflineValidate-1/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName1 = keychain.createIdentity(identity1);
-  shared_ptr<IdentityCertificate> anchor = keychain.getCertificate(certName1);
-
-  Name identity2("/TestSyncValidator/OfflineValidate-2/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName2 = keychain.createIdentity(identity2);
-  shared_ptr<IdentityCertificate> introducer = keychain.getCertificate(certName2);
-
-  Name identity3("/TestSyncValidator/OfflineValidate-3/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName3 = keychain.createIdentity(identity3);
-  shared_ptr<IdentityCertificate> introducee = keychain.getCertificate(certName3);
-
-  Name identity4("/TestSyncValidator/OfflineValidate-4/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName4 = keychain.createIdentity(identity4);
-  shared_ptr<IdentityCertificate> introducer2 = keychain.getCertificate(certName4);
-
-  Name identity5("/TestSyncValidator/OfflineValidate-5/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName5 = keychain.createIdentity(identity5);
-  shared_ptr<IdentityCertificate> introducee2 = keychain.getCertificate(certName5);
-
-  shared_ptr<boost::asio::io_service> ioService = make_shared<boost::asio::io_service>();
-  shared_ptr<Face> face = make_shared<Face>(ref(*ioService));
-  shared_ptr<SecRuleRelative> rule;
-  SyncValidator validator(prefix, *anchor, *face,
-                          bind(&publishData, _1, _2, _3),
-                          rule);
-
-  validator.addParticipant(*introducer);
-  BOOST_CHECK(validator.canTrust(certName2));
-
-  IntroCertificate introCert(prefix, *introducee, certName2.getPrefix(-1));
-  keychain.sign(introCert, certName2);
-  validator.addParticipant(introCert);
-  BOOST_CHECK(validator.canTrust(certName3));
-
-  IntroCertificate introCert2(prefix, *introducee2, certName4.getPrefix(-1));
-  keychain.sign(introCert2, certName4);
-  validator.addParticipant(introCert2);
-  BOOST_CHECK(validator.canTrust(certName5) == false);
-  BOOST_CHECK(validator.canTrust(certName4) == false);
-
-  validator.setAnchor(*introducer2);
-  BOOST_CHECK(validator.canTrust(certName1) == false);
-  BOOST_CHECK(validator.canTrust(certName2) == false);
-  BOOST_CHECK(validator.canTrust(certName3) == false);
-  BOOST_CHECK(validator.canTrust(certName4));
-  BOOST_CHECK(validator.canTrust(certName5));
-
-  Name dataName1 = prefix;
-  dataName1.append("data-1");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  keychain.sign(*data1, certName5);
-
-  validator.validate(*data1,
-		     bind(&onValidated, _1),
-		     bind(&onValidationFailed, _1, _2));
-
-  Name dataName2 = prefix;
-  dataName2.append("data-2");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  keychain.sign(*data2, certName1);
-
-  validator.validate(*data2,
-		     bind(&onValidated2, _1),
-		     bind(&onValidationFailed2, _1, _2));
-
-  // ioService->run();
-
-  keychain.deleteIdentity(identity1);
-  keychain.deleteIdentity(identity2);
-  keychain.deleteIdentity(identity3);
-  keychain.deleteIdentity(identity4);
-  keychain.deleteIdentity(identity5);
-}
-
-struct FacesFixture
-{
-  FacesFixture()
-    : regPrefixId(0)
-    , regPrefixId2(0)
-  {}
-
-  void
-  onInterest(ndn::shared_ptr<ndn::Face> face, ndn::shared_ptr<ndn::Data> data)
-  {
-    face->put(*data);
-    face->unsetInterestFilter(regPrefixId);
-  }
-
-  void
-  onInterest2(ndn::shared_ptr<ndn::Face> face, ndn::shared_ptr<ndn::Data> data)
-  {
-    face->put(*data);
-    face->unsetInterestFilter(regPrefixId2);
-  }
-
-  void
-  onRegFailed()
-  {}
-
-  void
-  validate(ndn::shared_ptr<Sync::SyncValidator> validator, ndn::shared_ptr<ndn::Data> data,
-           const ndn::Name& certName3, const ndn::Name& certName4)
-  {
-    validator->validate(*data,
-                        bind(&onValidated, _1),
-                        bind(&onValidationFailed, _1, _2));
-
-
-    BOOST_CHECK(validator->canTrust(certName3));
-    BOOST_CHECK(validator->canTrust(certName4));
-  }
-
-  void
-  terminate(ndn::shared_ptr<ndn::Face> face)
-  {
-    face->getIoService().stop();
-  }
-
-  const ndn::RegisteredPrefixId* regPrefixId;
-  const ndn::RegisteredPrefixId* regPrefixId2;
-};
-
-BOOST_FIXTURE_TEST_CASE(OnlineValidate, FacesFixture)
-{
-  using namespace Sync;
-  using namespace ndn;
-
-  Name prefix("/Sync/TestSyncValidator/OnlineValidate");
-  KeyChain keychain;
-
-  Name identity1("/TestSyncValidator/OnlineValidate-1/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName1 = keychain.createIdentity(identity1);
-  shared_ptr<IdentityCertificate> anchor = keychain.getCertificate(certName1);
-
-  Name identity2("/TestSyncValidator/OnlineValidate-2/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName2 = keychain.createIdentity(identity2);
-  shared_ptr<IdentityCertificate> introducer = keychain.getCertificate(certName2);
-
-  Name identity3("/TestSyncValidator/OnlineValidate-3/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName3 = keychain.createIdentity(identity3);
-  shared_ptr<IdentityCertificate> introducee = keychain.getCertificate(certName3);
-
-  Name identity4("/TestSyncValidator/OnlineValidate-4/"
-                 + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-  Name certName4 = keychain.createIdentity(identity4);
-  shared_ptr<IdentityCertificate> introducee2 = keychain.getCertificate(certName4);
-
-  shared_ptr<boost::asio::io_service> ioService = make_shared<boost::asio::io_service>();
-  shared_ptr<Face> face = make_shared<Face>(ref(*ioService));
-  shared_ptr<Face> face2 = make_shared<Face>(ref(*ioService));
-
-  shared_ptr<SecRuleRelative> rule;
-  shared_ptr<SyncValidator> validator = shared_ptr<SyncValidator>
-    (new SyncValidator(prefix, *anchor, *face2, bind(&publishData, _1, _2, _3), rule));
-
-  validator->addParticipant(*introducer);
-  BOOST_CHECK(validator->canTrust(certName2));
-
-  shared_ptr<IntroCertificate> introCert = shared_ptr<IntroCertificate>(new IntroCertificate(prefix, *introducee, certName2.getPrefix(-1)));
-  keychain.sign(*introCert, certName2);
-  BOOST_CHECK(validator->canTrust(certName3) == false);
-
-  shared_ptr<IntroCertificate> introCert2 = shared_ptr<IntroCertificate>(new IntroCertificate(prefix, *introducee2, certName3.getPrefix(-1)));
-  keychain.sign(*introCert2, certName3);
-  BOOST_CHECK(validator->canTrust(certName4) == false);
-
-  Name dataName1 = prefix;
-  dataName1.append("data-1");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  keychain.sign(*data1, certName4);
-
-  ndn::Scheduler scheduler(*ioService);
-
-  scheduler.scheduleEvent(time::seconds(1),
-                          bind(&FacesFixture::terminate, this, face));
-
-  regPrefixId = face->setInterestFilter(introCert->getName().getPrefix(-1),
-                                       bind(&FacesFixture::onInterest, this, face, introCert),
-                                       bind(&FacesFixture::onRegFailed, this));
-
-  regPrefixId2 = face->setInterestFilter(introCert2->getName().getPrefix(-1),
-					bind(&FacesFixture::onInterest2, this, face, introCert2),
-					bind(&FacesFixture::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::milliseconds(200),
-                          bind(&FacesFixture::validate, this,
-			       validator, data1, certName3, certName4));
-
-  keychain.deleteIdentity(identity1);
-  keychain.deleteIdentity(identity2);
-  keychain.deleteIdentity(identity3);
-  keychain.deleteIdentity(identity4);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
