diff --git a/src/sync-intro-certificate.h b/src/sync-intro-certificate.h
new file mode 100644
index 0000000..48dae45
--- /dev/null
+++ b/src/sync-intro-certificate.h
@@ -0,0 +1,154 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef SYNC_INTRO_CERTIFICATE_H
+#define SYNC_INTRO_CERTIFICATE_H
+
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+
+namespace Sync {
+
+class IntroCertificate : public ndn::Data
+{
+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& introducerName); //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&
+  getIntroducerName() const
+  {
+    return m_introducerName;
+  }
+
+  const ndn::Name&
+  getIntroduceeName() const
+  {
+    return m_introduceeName;
+  }
+
+private:
+  ndn::Name m_syncPrefix;
+  ndn::IdentityCertificate m_introduceeCert;
+  ndn::Name m_introducerName;
+  ndn::Name m_introduceeName;
+};
+
+inline
+IntroCertificate::IntroCertificate(const ndn::Name& syncPrefix,
+                                   const ndn::IdentityCertificate& introduceeCert,
+                                   const ndn::Name& introducerName)
+  : m_syncPrefix(syncPrefix)
+  , m_introduceeCert(introduceeCert)
+  , m_introducerName(introducerName)
+  , m_introduceeName(introduceeCert.getName().getPrefix(-1))
+{
+  // Naming convention /<sync_prefix>/intro-cert/introducee_certname/introducer_certname/version/
+  ndn::Name dataName = m_syncPrefix;
+  dataName.append("intro-cert").append(introduceeCert.getName().getPrefix(-1).wireEncode()).append(introducerName.wireEncode()).appendVersion();
+  
+  setName(dataName);
+  setContent(introduceeCert.wireEncode());
+}
+
+inline
+IntroCertificate::IntroCertificate(const ndn::Data& data)
+  : Data(data)
+{
+  ndn::Name dataName = data.getName();
+  ndn::Name introduceeCertName;
+  ndn::Name introducerName;
+
+  if(dataName.size() < 4 || dataName.get(-4).toEscapedString() != "intro-cert")
+    throw Error("Not a Sync::IntroCertificate");
+
+  m_syncPrefix = dataName.getPrefix(-4);
+
+  try
+    {
+      m_introduceeCert.wireDecode(data.getContent().blockFromValue());
+      m_introducerName.wireDecode(dataName.get(-2).blockFromValue());
+      introduceeCertName.wireDecode(dataName.get(-3).blockFromValue());
+    }
+  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(introduceeCertName != m_introduceeCert.getName().getPrefix(-1))
+    throw Error("Invalid Sync::IntroCertificate (inconsistent introducee name)");
+
+  m_introduceeName = introduceeCertName;
+
+  try
+    {
+      ndn::SignatureSha256WithRsa sig(data.getSignature());
+      introducerName = 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_introducerName != introducerName)
+    throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#3)");
+
+  if(m_introducerName != introducerName)
+    throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#3)");
+}
+
+
+} // namespace Sync
+
+#endif //SYNC_INTRO_CERTIFICATE_H
diff --git a/src/sync-logic.cc b/src/sync-logic.cc
index ec4d63e..5bbd83c 100644
--- a/src/sync-logic.cc
+++ b/src/sync-logic.cc
@@ -58,6 +58,7 @@
 int SyncLogic::m_instanceCounter = 0;
 
 SyncLogic::SyncLogic (const Name& syncPrefix,
+                      const Name& identity,
                       shared_ptr<Validator> validator, 
                       shared_ptr<Face> face,
                       LogicUpdateCallback onUpdate,
@@ -65,6 +66,7 @@
   : m_state (new FullState)
   , m_syncInterestTable (*face->ioService(), time::seconds(m_syncInterestReexpress))
   , m_syncPrefix (syncPrefix)
+  , m_identity (identity)
   , m_onUpdate (onUpdate)
   , m_onRemove (onRemove)
   , m_perBranch (false)
@@ -89,12 +91,14 @@
 }
 
 SyncLogic::SyncLogic (const Name& syncPrefix,
+                      const Name& identity,
                       shared_ptr<Validator> validator,
                       shared_ptr<Face> face,
                       LogicPerBranchCallback onUpdateBranch)
   : m_state (new FullState)
   , m_syncInterestTable (*face->ioService(), time::seconds (m_syncInterestReexpress))
   , m_syncPrefix (syncPrefix)
+  , m_identity (identity)
   , m_onUpdateBranch (onUpdateBranch)
   , m_perBranch(true)
   , m_validator(validator)
@@ -164,6 +168,10 @@
     {
       _LOG_DEBUG_ID ("<< I " << name);
 
+      if(name.get(m_syncPrefix.size()).toEscapedString() == "intro-cert")
+        // it is a certificate, validator will take care of it.
+        return;
+
       DigestConstPtr digest;
       string type;
       tie (digest, type) = convertNameToDigestAndType (name);
@@ -636,7 +644,7 @@
   syncData.setContent(reinterpret_cast<const uint8_t*>(wireData), size);
   syncData.setFreshnessPeriod(m_syncResponseFreshness);
   
-  m_keyChain->sign(syncData);
+  m_keyChain->signByIdentity(syncData, m_identity);
   
   m_face->put(syncData);
   
diff --git a/src/sync-logic.h b/src/sync-logic.h
index fc63fca..423c8d7 100644
--- a/src/sync-logic.h
+++ b/src/sync-logic.h
@@ -77,12 +77,14 @@
    * the app data when new remote names are learned
    */
   SyncLogic (const ndn::Name& syncPrefix,
+             const ndn::Name& identity,
              ndn::shared_ptr<ndn::Validator> validator,
              ndn::shared_ptr<ndn::Face> face,
              LogicUpdateCallback onUpdate,
              LogicRemoveCallback onRemove);
 
   SyncLogic (const ndn::Name& syncPrefix,
+             const ndn::Name& identity,
              ndn::shared_ptr<ndn::Validator> validator,
              ndn::shared_ptr<ndn::Face> face,
              LogicPerBranchCallback onUpdateBranch);
@@ -182,6 +184,7 @@
   SyncInterestTable m_syncInterestTable;
 
   ndn::Name m_syncPrefix;
+  ndn::Name m_identity;
   LogicUpdateCallback m_onUpdate;
   LogicRemoveCallback m_onRemove;
   LogicPerBranchCallback m_onUpdateBranch;
diff --git a/src/sync-socket.cc b/src/sync-socket.cc
index f590338..b37d657 100644
--- a/src/sync-socket.cc
+++ b/src/sync-socket.cc
@@ -30,17 +30,20 @@
 
 using ndn::shared_ptr;
 
-SyncSocket::SyncSocket (const Name &syncPrefix, 
+SyncSocket::SyncSocket (const Name& syncPrefix,
+                        const Name& identity,
                         shared_ptr<Validator> validator,
                         shared_ptr<Face> face,
                         NewDataCallback dataCallback, 
                         RemoveCallback rmCallback )
   : m_newDataCallback(dataCallback)
+  , m_identity(identity)
   , m_validator(validator)
   , m_keyChain(new KeyChain())
   , m_face(face)
   , m_ioService(face->ioService())
   , m_syncLogic (syncPrefix,
+                 identity,
                  validator,
                  face,
                  bind(&SyncSocket::passCallback, this, _1),
@@ -71,7 +74,7 @@
   dataName.append(boost::lexical_cast<string>(session)).append(boost::lexical_cast<string>(sequence));
   data->setName(dataName);
 
-  m_keyChain->sign(*data);  
+  m_keyChain->signByIdentity(*data, m_identity);
   m_face->put(*data);
 
   SeqNo s(session, sequence + 1);
diff --git a/src/sync-socket.h b/src/sync-socket.h
index ee02ae8..f796fed 100644
--- a/src/sync-socket.h
+++ b/src/sync-socket.h
@@ -56,7 +56,8 @@
    * @param syncPrefix the name prefix for Sync Interest
    * @param dataCallback the callback to process data
    */
-  SyncSocket (const ndn::Name &syncPrefix, 
+  SyncSocket (const ndn::Name& syncPrefix, 
+              const ndn::Name& identity,
               ndn::shared_ptr<ndn::Validator> validator,
               ndn::shared_ptr<ndn::Face> face,
               NewDataCallback dataCallback, 
@@ -116,6 +117,7 @@
   typedef std::map<ndn::Name, SeqNo> SequenceLog;
   NewDataCallback m_newDataCallback;
   SequenceLog m_sequenceLog;
+  ndn::Name m_identity;
   ndn::shared_ptr<ndn::Validator> m_validator;
   ndn::shared_ptr<ndn::KeyChain> m_keyChain;
   ndn::shared_ptr<ndn::Face> m_face;
diff --git a/src/sync-validator.cc b/src/sync-validator.cc
new file mode 100644
index 0000000..03c292b
--- /dev/null
+++ b/src/sync-validator.cc
@@ -0,0 +1,259 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "sync-validator.h"
+#include "sync-logging.h"
+#include <ndn-cpp-dev/security/certificate-cache-ttl.hpp>
+#include <queue>
+
+using namespace ndn;
+using namespace std;
+
+INIT_LOGGER ("SyncValidator");
+
+namespace Sync {
+
+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,
+                             shared_ptr<Face> face,
+                             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_dataRule(rule)
+{
+  if(!static_cast<bool>(face))
+    throw Error("Face is not set!");
+
+  if(!static_cast<bool>(m_certificateCache))
+    m_certificateCache = make_shared<CertificateCacheTtl>(m_face->ioService());
+
+  Name certPrefix = prefix;
+  certPrefix.append("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()
+{
+  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.getIntroduceeName()) == 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.getIntroduceeName()] = edgeIt->second.getIntroduceeCert().getPublicKeyInfo();
+                  nodeQueue.push(edgeIt->second.getIntroduceeName());
+                }
+            }
+        }
+      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()))
+    {
+      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
+            {
+              Name interestName = m_prefix;
+              interestName.append("intro-cert").append(keyLocatorName.wireEncode());
+              Interest interest(interestName);
+              interest.setInterestLifetime(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: " + string(e.what()));
+        }
+      catch(KeyLocator::Error& e)
+        {
+          return onValidationFailed(data.shared_from_this(),
+                                    "Key Locator is not a name: " + data.getName().toUri());
+        }
+    }
+
+  if(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
+            return onValidationFailed(data.shared_from_this(), 
+                                      "Signer cannot be trusted: " + keyLocatorName.toUri());
+        }
+      catch(SignatureSha256WithRsa::Error& e)
+        {
+          return onValidationFailed(data.shared_from_this(), 
+                                    "Not SignatureSha256WithRsa signature: " + 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 data 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: " + string(e.what()));
+    }
+}
+
+void
+SyncValidator::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate, 
+                                             const 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 string& msg)
+{
+  _LOG_DEBUG("SyncValidator::onCertRegisterFailed: " << msg);
+}
+
+} // namespace Sync
diff --git a/src/sync-validator.h b/src/sync-validator.h
new file mode 100644
index 0000000..b3cff00
--- /dev/null
+++ b/src/sync-validator.h
@@ -0,0 +1,296 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef SYNC_VALIDATOR_H
+#define SYNC_VALIDATOR_H
+
+#include "sync-intro-certificate.h"
+#include <ndn-cpp-dev/security/validator.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/security/sec-rule-relative.hpp>
+#include <ndn-cpp-dev/security/certificate-cache.hpp>
+#include <map>
+
+namespace Sync {
+
+class SyncValidator : public ndn::Validator
+{
+public:
+  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::shared_ptr<ndn::Face> face,
+                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);
+
+#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;
+  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.getIntroducerName();
+          m_introduceeCerts.push_back(introCert.getName());
+        }
+      else
+        {
+          m_nodeName = introCert.getIntroduceeName();
+          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.getIntroducerName());
+  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.getIntroduceeName());
+  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.getIntroducerName());
+  if(trustNodeIt != m_trustedNodes.end() && verifySignature(introCert, trustNodeIt->second))
+    // If the introducee, add it into trusted node set.
+    m_trustedNodes[introCert.getIntroduceeName()] = introCert.getIntroduceeCert().getPublicKeyInfo();
+}
+
+inline ndn::shared_ptr<const IntroCertificate>
+SyncValidator::addParticipant(const ndn::IdentityCertificate& introducee)
+{
+  ndn::shared_ptr<IntroCertificate> introCert = ndn::make_shared<IntroCertificate>(m_prefix, introducee, m_anchor.getName().getPrefix(-1));
+
+  m_keychain.sign(*introCert, m_anchor.getName());
+  
+  addParticipant(*introCert);
+
+  return introCert;
+}
+
+} // namespace Sync
+
+#endif //SYNC_VALIDATOR_H
