Adapt sync to use new ndn.cxx api
diff --git a/src/ccnx/sync-app-socket-c.cc b/disable/sync-app-socket-c.cc
similarity index 100%
rename from src/ccnx/sync-app-socket-c.cc
rename to disable/sync-app-socket-c.cc
diff --git a/src/ccnx/sync-app-socket-c.h b/disable/sync-app-socket-c.h
similarity index 100%
rename from src/ccnx/sync-app-socket-c.h
rename to disable/sync-app-socket-c.h
diff --git a/src/ccnx/sync-app-socket.cc b/disable/sync-app-socket.cc
similarity index 100%
rename from src/ccnx/sync-app-socket.cc
rename to disable/sync-app-socket.cc
diff --git a/src/ccnx/sync-app-socket.h b/disable/sync-app-socket.h
similarity index 100%
rename from src/ccnx/sync-app-socket.h
rename to disable/sync-app-socket.h
diff --git a/src/ccnx/sync-ccnx-wrapper.cc b/disable/sync-ccnx-wrapper.cc
similarity index 100%
rename from src/ccnx/sync-ccnx-wrapper.cc
rename to disable/sync-ccnx-wrapper.cc
diff --git a/src/ccnx/sync-ccnx-wrapper.h b/disable/sync-ccnx-wrapper.h
similarity index 100%
rename from src/ccnx/sync-ccnx-wrapper.h
rename to disable/sync-ccnx-wrapper.h
diff --git a/tests/test_app_socket.cc b/disable/test_app_socket.cc
similarity index 100%
rename from tests/test_app_socket.cc
rename to disable/test_app_socket.cc
diff --git a/tests/test_ccnx_wrapper.cc b/disable/test_ccnx_wrapper.cc
similarity index 100%
rename from tests/test_ccnx_wrapper.cc
rename to disable/test_ccnx_wrapper.cc
diff --git a/log4cxx.properties b/log4cxx.properties
index 23ff104..6252595 100644
--- a/log4cxx.properties
+++ b/log4cxx.properties
@@ -11,7 +11,8 @@
 #log4j.appender.A1.layout.ConversionPattern=%d{hh:mm:ss,SSS} %-14t %-14c  %m%n
 log4j.appender.A1.layout.ConversionPattern=%d{ss,SSS}  %-12c  %m%n
 
-log4j.logger.SyncLogic = DEBUG
+log4j.logger.SyncLogic = TRACE
+log4j.logger.SyncPolicyManager = DEBUG
 #log4j.logger.SyncInterestTable = TRACE
 #log4j.logger.AppDataFetch = TRACE
 log4j.logger.Test = TRACE
diff --git a/src/ccnx/sync-socket.cc b/src/ccnx/sync-socket.cc
new file mode 100644
index 0000000..48d4ad0
--- /dev/null
+++ b/src/ccnx/sync-socket.cc
@@ -0,0 +1,126 @@
+/* -*- Mode: C32++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "sync-socket.h"
+
+using namespace std;
+using namespace ndn;
+
+namespace Sync {
+
+SyncSocket::SyncSocket (const string &syncPrefix, 
+                        Ptr<SyncPolicyManager> syncPolicyManager, 
+                        NewDataCallback dataCallback, 
+                        RemoveCallback rmCallback )
+  : m_newDataCallback(dataCallback)
+  , m_syncPolicyManager(syncPolicyManager)
+  , m_syncLogic (syncPrefix,
+                 syncPolicyManager,
+                 bind(&SyncSocket::passCallback, this, _1),
+                 rmCallback)
+{
+  Ptr<security::Keychain> keychain = Ptr<security::Keychain>(new security::Keychain(Ptr<security::IdentityManager>::Create(), m_syncPolicyManager, NULL));
+  m_handler = Ptr<Wrapper>(new Wrapper(keychain));
+}
+
+SyncSocket::~SyncSocket()
+{}
+
+bool 
+SyncSocket::publishData(const std::string &prefix, uint32_t session, const char *buf, size_t len, int freshness)
+{
+  uint32_t sequence = getNextSeq(prefix, session);
+  ostringstream contentNameWithSeqno;
+  contentNameWithSeqno << prefix << "/" << session << "/" << sequence;
+  
+  Name dataName(contentNameWithSeqno.str ());
+  Blob blob(buf, len);
+  Name signingIdentity = m_syncPolicyManager->inferSigningIdentity(dataName);
+  
+  m_handler->publishDataByIdentity (dataName, 
+                                    blob, 
+                                    signingIdentity, 
+                                    freshness);
+  
+  SeqNo s(session, sequence + 1);
+  m_sequenceLog[prefix] = s;
+  m_syncLogic.addLocalNames (prefix, session, sequence);
+  return true;
+}
+
+void 
+SyncSocket::fetchData(const string &prefix, const SeqNo &seq, const DataCallback& callback, int retry)
+{
+  ostringstream interestName;
+  interestName << prefix << "/" << seq.getSession() << "/" << seq.getSeq();
+  //std::cout << "Socket " << this << " Send Interest <" << interestName.str() << "> for raw data " << endl;
+  
+  
+  Ptr<ndn::Interest> interestPtr = Ptr<ndn::Interest>(new ndn::Interest(interestName.str()));
+  Ptr<Closure> closure = Ptr<Closure> (new Closure(callback,
+						   boost::bind(&SyncSocket::onChatDataTimeout,
+                                                               this,
+                                                               _1, 
+                                                               _2,
+                                                               retry),
+						   boost::bind(&SyncSocket::onChatDataUnverified,
+                                                               this,
+                                                               _1)));
+  m_handler->sendInterest(interestPtr, closure);
+}
+
+void
+SyncSocket::onChatDataTimeout(Ptr<Closure> closure, Ptr<ndn::Interest> interest, int retry)
+{
+  if(retry > 0)
+    {
+      Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
+                                                         boost::bind(&SyncSocket::onChatDataTimeout, 
+                                                                     this, 
+                                                                     _1, 
+                                                                     _2, 
+                                                                     retry - 1),
+                                                         closure->m_unverifiedCallback,
+                                                         closure->m_stepCount)
+                                             );
+      m_handler->sendInterest(interest, newClosure);
+    }
+}
+
+void
+SyncSocket::onChatDataUnverified(Ptr<Data> data)
+{}
+
+
+uint32_t
+SyncSocket::getNextSeq (const string &prefix, uint32_t session)
+{
+  SequenceLog::iterator i = m_sequenceLog.find (prefix);
+
+  if (i != m_sequenceLog.end ())
+    {
+      SeqNo s = i->second;
+      if (s.getSession() == session)
+        return s.getSeq();
+    }
+  return 0;
+}
+
+}//Sync
diff --git a/src/ccnx/sync-socket.h b/src/ccnx/sync-socket.h
new file mode 100644
index 0000000..a4530ba
--- /dev/null
+++ b/src/ccnx/sync-socket.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef SYNC_SOCKET_H
+#define SYNC_SOCKET_H
+
+#include "sync-logic.h"
+#include <boost/function.hpp>
+#include <boost/unordered_map.hpp>
+#include "sync-seq-no.h"
+#include <ndn.cxx/wrapper/wrapper.h>
+#include <utility>
+#include <map>
+#include <vector>
+#include <sstream>
+
+namespace Sync {
+
+/**
+ * \ingroup sync
+ * @brief A simple interface to interact with client code
+ */
+class SyncSocket
+{
+public:
+  typedef boost::function< void (const std::vector<MissingDataInfo> &, SyncSocket * ) > NewDataCallback;
+  typedef boost::function< void ( const std::string &/*prefix*/ ) > RemoveCallback;
+  /**
+   * @brief the constructor for SyncAppSocket; the parameter syncPrefix
+   * should be passed to the constructor of m_syncAppWrapper; the other
+   * parameter should be passed to the constructor of m_fetcher; furthermore,
+   * the fetch function of m_fetcher should be a second paramter passed to
+   * the constructor of m_syncAppWrapper, so that m_syncAppWrapper can tell
+   * m_fetcher to fetch the actual app data after it learns the names
+   *
+   * @param syncPrefix the name prefix for Sync Interest
+   * @param dataCallback the callback to process data
+   */
+  SyncSocket (const std::string &syncPrefix, 
+              ndn::Ptr<SyncPolicyManager> syncPolicyManager,
+              NewDataCallback dataCallback, 
+              RemoveCallback rmCallback);
+
+  ~SyncSocket ();
+
+  bool 
+  publishData(const std::string &prefix, uint32_t session, const char *buf, size_t len, int freshness);
+
+  void 
+  remove (const std::string &prefix) 
+  { m_syncLogic.remove(prefix); }
+
+  void 
+  fetchData(const std::string &prefix, const SeqNo &seq, const ndn::DataCallback& callback, int retry = 0);
+
+  std::string 
+  getRootDigest() 
+  { return m_syncLogic.getRootDigest(); }
+
+  uint32_t
+  getNextSeq (const std::string &prefix, uint32_t session);
+
+  SyncLogic &
+  getLogic () 
+  { return m_syncLogic; }
+
+  // make this a static function so we don't have to create socket instance without
+  // knowing the local prefix. it's a wrong place for this function anyway
+  static std::string
+  GetLocalPrefix (); 
+  
+private:
+  void 
+  passCallback(const std::vector<MissingDataInfo> &v) 
+  { m_newDataCallback(v, this); }
+
+  void
+  onChatDataTimeout(ndn::Ptr<ndn::Closure> closure, ndn::Ptr<ndn::Interest> interest, int retry);
+
+  void
+  onChatDataUnverified(ndn::Ptr<ndn::Data> data);
+
+private:
+  typedef boost::unordered_map<std::string, SeqNo> SequenceLog;
+  NewDataCallback m_newDataCallback;
+  SequenceLog m_sequenceLog;
+  ndn::Ptr<SyncPolicyManager> m_syncPolicyManager;
+  ndn::Ptr<ndn::Wrapper> m_handler;
+  SyncLogic      m_syncLogic;
+};
+
+} // Sync
+
+#endif // SYNC_SOCKET_H
diff --git a/src/specific-policy-rule.cc b/src/specific-policy-rule.cc
new file mode 100644
index 0000000..9fbd23a
--- /dev/null
+++ b/src/specific-policy-rule.cc
@@ -0,0 +1,50 @@
+/* -*- 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 "specific-policy-rule.h"
+#include <ndn.cxx/fields/signature-sha256-with-rsa.h>
+
+using namespace ndn;
+using namespace std;
+using namespace ndn::security;
+
+
+SpecificPolicyRule::SpecificPolicyRule(Ptr<Regex> dataRegex,
+				       Ptr<Regex> signerRegex)
+  : PolicyRule(PolicyRule::IDENTITY_POLICY, true)
+  , m_dataRegex(dataRegex)
+  , m_signerRegex(signerRegex)
+{}
+
+SpecificPolicyRule::SpecificPolicyRule(const SpecificPolicyRule& rule)
+  : PolicyRule(PolicyRule::IDENTITY_POLICY, true)
+  , m_dataRegex(rule.m_dataRegex)
+  , m_signerRegex(rule.m_signerRegex)
+{}
+
+bool 
+SpecificPolicyRule::matchDataName(const Data & data)
+{ return m_dataRegex->match(data.getName()); }
+
+bool 
+SpecificPolicyRule::matchSignerName(const Data & data)
+{ 
+  Ptr<const signature::Sha256WithRsa> sigPtr = DynamicCast<const signature::Sha256WithRsa> (data.getSignature());
+  Name signerName = sigPtr->getKeyLocator ().getKeyName ();
+  return m_signerRegex->match(signerName); 
+}
+
+bool
+SpecificPolicyRule::satisfy(const Data & data)
+{ return (matchDataName(data) && matchSignerName(data)) ? true : false ; }
+
+bool
+SpecificPolicyRule::satisfy(const Name & dataName, const Name & signerName)
+{ return (m_dataRegex->match(dataName) && m_signerRegex->match(signerName)); }
diff --git a/src/specific-policy-rule.h b/src/specific-policy-rule.h
new file mode 100644
index 0000000..e2b859b
--- /dev/null
+++ b/src/specific-policy-rule.h
@@ -0,0 +1,46 @@
+/* -*- 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 SPECIFIC_POLICY_RULE_H
+#define SPECIFIC_POLICY_RULE_H
+
+#include <ndn.cxx/security/policy/policy-rule.h>
+#include <ndn.cxx/regex/regex.h>
+
+class SpecificPolicyRule : public ndn::security::PolicyRule
+{
+  
+public:
+  SpecificPolicyRule(ndn::Ptr<ndn::Regex> dataRegex,
+                     ndn::Ptr<ndn::Regex> signerRegex);
+
+  SpecificPolicyRule(const SpecificPolicyRule& rule);
+
+  virtual
+  ~SpecificPolicyRule() {};
+
+  bool 
+  matchDataName(const ndn::Data & data);
+
+  bool 
+  matchSignerName(const ndn::Data & data);
+
+  bool
+  satisfy(const ndn::Data & data);
+
+  bool
+  satisfy(const ndn::Name & dataName, const ndn::Name & signerName);
+  
+private:
+  ndn::Ptr<ndn::Regex> m_dataRegex;
+  ndn::Ptr<ndn::Regex> m_signerRegex;
+};
+
+#endif //CHAT_POLICY_RULE_H
diff --git a/src/sync-intro-certificate.cc b/src/sync-intro-certificate.cc
new file mode 100644
index 0000000..9d77cca
--- /dev/null
+++ b/src/sync-intro-certificate.cc
@@ -0,0 +1,213 @@
+/* -*- 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-intro-certificate.h"
+#include <ndn.cxx/security/exception.h>
+
+using namespace ndn;
+using namespace ndn::security;
+using namespace std;
+
+SyncIntroCertificate::SyncIntroCertificate ()
+  : Certificate()
+{}
+
+SyncIntroCertificate::SyncIntroCertificate (const Name& nameSpace,
+					    const Name& keyName,
+					    const Name& signerName,
+					    const Time& notBefore,
+					    const Time& notAfter,
+					    const Publickey& key,
+					    const IntroType& introType)
+  : m_keyName(keyName)
+  , m_introType(introType)
+{
+  Name certificateName = nameSpace;
+  certificateName.append("WOT").append(keyName).append("INTRO-CERT").append(signerName);
+  switch(introType)
+    {
+    case PRODUCER:
+      certificateName.append("PRODUCER");
+      break;
+    case INTRODUCER:
+      certificateName.append("INTRODUCER");
+      break;
+    default:
+      throw SecException("Wrong Introduction Type!");
+    }
+  certificateName.appendVersion();
+ 
+  setName(certificateName);
+  setNotBefore(notBefore);
+  setNotAfter(notAfter);
+  setPublicKeyInfo(key);
+  addSubjectDescription(CertificateSubDescrypt("2.5.4.41", keyName.toUri()));
+}
+
+SyncIntroCertificate::SyncIntroCertificate (const Name& nameSpace,
+					    const IdentityCertificate& identityCertificate,
+					    const Name& signerName,
+					    const IntroType& introType)
+  : m_introType(introType)
+{
+  m_keyName = identityCertificate.getPublicKeyName();
+
+  Name certificateName = nameSpace;
+  certificateName.append("WOT").append(m_keyName).append("INTRO-CERT").append(signerName);
+  switch(introType)
+    {
+    case PRODUCER:
+      certificateName.append("PRODUCER");
+      break;
+    case INTRODUCER:
+      certificateName.append("INTRODUCER");
+      break;
+    default:
+      throw SecException("Wrong Introduction Type!");
+    }
+  certificateName.appendVersion();
+ 
+  setName(certificateName);
+  setNotBefore(identityCertificate.getNotBefore());
+  setNotAfter(identityCertificate.getNotAfter());
+  setPublicKeyInfo(identityCertificate.getPublicKeyInfo());
+  addSubjectDescription(CertificateSubDescrypt("2.5.4.41", m_keyName.toUri()));
+}
+  
+SyncIntroCertificate::SyncIntroCertificate (const Data& data)
+  : Certificate(data)
+{
+  Name certificateName = getName();
+  int i = 0;
+  int keyNameStart = 0;
+  int keyNameEnd = 0;
+  for(; i < certificateName.size(); i++)
+    {
+      if(certificateName.get(i).toUri() == string("WOT"))
+	{
+	  keyNameStart = i + 1;
+	  break;
+	}
+    }
+  
+  if(i >= certificateName.size())
+    throw SecException("Wrong SyncIntroCertificate Name!");
+    
+  for(; i< certificateName.size(); i++)
+    {
+      if(certificateName.get(i).toUri() == string("INTRO-CERT"))
+	{
+	  keyNameEnd = i;
+	  break;
+	}
+    }
+
+  if(i >= certificateName.size())
+    throw SecException("Wrong SyncIntroCertificate Name!");
+
+  m_keyName = certificateName.getSubName(keyNameStart, keyNameEnd);
+
+  string typeComponent = certificateName.get(certificateName.size() - 2).toUri();
+  if(typeComponent == string("PRODUCER"))
+    m_introType = PRODUCER;
+  else if(typeComponent == string("INTRODUCER"))
+    m_introType = INTRODUCER;
+  else
+    throw SecException("Wrong SyncIntroCertificate Name!");
+}
+
+SyncIntroCertificate::SyncIntroCertificate (const SyncIntroCertificate& chronosIntroCertificate)
+  : Certificate(chronosIntroCertificate)
+  , m_keyName(chronosIntroCertificate.m_keyName)
+  , m_introType(chronosIntroCertificate.m_introType)
+{}
+
+Data &
+SyncIntroCertificate::setName (const Name& certificateName)
+{
+  int i = 0;
+  int keyNameStart = 0;
+  int keyNameEnd = 0;
+  for(; i < certificateName.size(); i++)
+    {
+      if(certificateName.get(i).toUri() == string("WOT"))
+	{
+	  keyNameStart = i + 1;
+	  break;
+	}
+    }
+    
+  if(i >= certificateName.size())
+    throw SecException("Wrong SyncIntroCertificate Name!");
+  
+  for(; i< certificateName.size(); i++)
+    {
+      if(certificateName.get(i).toUri() == string("INTRO-CERT"))
+	{
+	  keyNameEnd = i;
+	  break;
+	}
+    }
+
+  if(i >= certificateName.size())
+    throw SecException("Wrong SyncIntroCertificate Name!");
+
+  m_keyName = certificateName.getSubName(keyNameStart, keyNameEnd);
+
+  string typeComponent = certificateName.get(certificateName.size() - 2).toUri();
+  if(typeComponent == string("PRODUCER"))
+    m_introType = PRODUCER;
+  else if(typeComponent == string("INTRODUCER"))
+    m_introType = INTRODUCER;
+  else
+    throw SecException("Wrong SyncIntroCertificate Name!");
+    
+  return *this;
+}
+
+bool
+SyncIntroCertificate::isSyncIntroCertificate(const Certificate& certificate)
+{
+  const Name& certificateName = certificate.getName();
+  string introType = certificateName.get(certificateName.size() - 2).toUri();
+  if(introType != string("PRODUCER") && introType != string("INTRODUCER"))
+    return false;
+
+  int i = 0;
+  bool findWot = false;
+  bool findIntroCert = false;
+  for(; i < certificateName.size(); i++)
+    {
+      if(certificateName.get(i).toUri() == string("WOT"))
+	{
+	  findWot = true;
+	  break;
+	}
+    }
+    
+  if(!findWot)
+    return false;
+  
+  for(; i < certificateName.size(); i++)
+    {
+      if(certificateName.get(i).toUri() == string("INTRO-CERT"))
+	{
+	  findIntroCert = true;
+	  break;
+	}
+    }
+  if(!findIntroCert)
+    return false;
+  
+  if(i < certificateName.size() - 2)
+    return true;
+  
+  return false;    
+}
diff --git a/src/sync-intro-certificate.h b/src/sync-intro-certificate.h
new file mode 100644
index 0000000..db41627
--- /dev/null
+++ b/src/sync-intro-certificate.h
@@ -0,0 +1,69 @@
+/* -*- 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.cxx/security/certificate/certificate.h>
+#include <ndn.cxx/security/certificate/identity-certificate.h>
+
+class SyncIntroCertificate : public ndn::security::Certificate
+{
+public:
+  enum IntroType{
+    PRODUCER,
+    INTRODUCER
+  };
+  
+public:
+  SyncIntroCertificate ();
+  
+  SyncIntroCertificate (const ndn::Name& nameSpace,
+                        const ndn::Name& keyName,
+                        const ndn::Name& signerName,
+                        const ndn::Time& notBefore,
+                        const ndn::Time& notAfter,
+                        const ndn::security::Publickey& key,
+                        const IntroType& introType = PRODUCER);
+  
+  SyncIntroCertificate (const ndn::Name& nameSpace,
+                        const ndn::security::IdentityCertificate& identityCertificate,
+                        const ndn::Name& signerName,
+                        const IntroType& introType);
+  
+  SyncIntroCertificate (const ndn::Data& data);
+  
+  SyncIntroCertificate (const SyncIntroCertificate& chronosIntroCertificate);
+  
+  
+  virtual 
+  ~SyncIntroCertificate ()
+  {}
+  
+  ndn::Data &
+  setName (const ndn::Name& name);
+  
+  inline virtual ndn::Name 
+  getPublicKeyName () const
+  { return m_keyName; }
+  
+  inline IntroType
+  getIntroType()
+  { return m_introType; }
+
+  static bool
+  isSyncIntroCertificate(const ndn::security::Certificate& certificate);
+
+protected:
+  ndn::Name m_keyName;
+  IntroType m_introType;
+};
+
+#endif
diff --git a/src/sync-logic.cc b/src/sync-logic.cc
index 98160b5..ef96a86 100644
--- a/src/sync-logic.cc
+++ b/src/sync-logic.cc
@@ -38,6 +38,7 @@
 
 using namespace std;
 using namespace boost;
+using namespace ndn;
 
 INIT_LOGGER ("SyncLogic");
 
@@ -57,31 +58,36 @@
 namespace Sync
 {
 
-SyncLogic::SyncLogic (const std::string &syncPrefix,
-                      LogicUpdateCallback onUpdate,
-                      LogicRemoveCallback onRemove)
-  : m_state (new FullState)
-  , m_syncInterestTable (TIME_SECONDS (m_syncInterestReexpress))
-  , m_syncPrefix (syncPrefix)
-  , m_onUpdate (onUpdate)
-  , m_onRemove (onRemove)
-  , m_perBranch (false)
-  , m_ccnxHandle(new CcnxWrapper ())
+  SyncLogic::SyncLogic (const Name& syncPrefix,
+                        Ptr<SyncPolicyManager> syncPolicyManager, 
+                        LogicUpdateCallback onUpdate,
+                        LogicRemoveCallback onRemove)
+    : m_state (new FullState)
+    , m_syncInterestTable (TIME_SECONDS (m_syncInterestReexpress))
+    , m_syncPrefix (syncPrefix)
+    , m_onUpdate (onUpdate)
+    , m_onRemove (onRemove)
+    , m_perBranch (false)
+    , m_policyManager(syncPolicyManager)
 #ifndef NS3_MODULE
-  , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
-  , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
-  , m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
+    , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
+    , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
+    , m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
 #else
-  , m_rangeUniformRandom (200,1000)
-  , m_reexpressionJitter (10,500)
+    , m_rangeUniformRandom (200,1000)
+    , m_reexpressionJitter (10,500)
 #endif
-  , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
+    , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
 { 
 #ifndef NS3_MODULE
   // In NS3 module these functions are moved to StartApplication method
-  
-  m_ccnxHandle->setInterestFilter (m_syncPrefix,
-                                   bind (&SyncLogic::respondSyncInterest, this, _1));
+
+  Ptr<security::Keychain> keychain = Ptr<security::Keychain>(new security::Keychain(Ptr<security::IdentityManager>::Create(),
+                                                                                    m_policyManager,
+                                                                                    NULL));
+  m_handler = Ptr<Wrapper>(new Wrapper(keychain));
+  m_handler->setInterestFilter (m_syncPrefix, 
+                                bind (&SyncLogic::respondSyncInterest, this, _1));
 
   m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
                         bind (&SyncLogic::sendSyncInterest, this),
@@ -89,14 +95,15 @@
 #endif
 }
 
-SyncLogic::SyncLogic (const std::string &syncPrefix,
+SyncLogic::SyncLogic (const Name& syncPrefix,
+                      Ptr<SyncPolicyManager> syncPolicyManager,
                       LogicPerBranchCallback onUpdateBranch)
   : m_state (new FullState)
   , m_syncInterestTable (TIME_SECONDS (m_syncInterestReexpress))
   , m_syncPrefix (syncPrefix)
   , m_onUpdateBranch (onUpdateBranch)
   , m_perBranch(true)
-  , m_ccnxHandle(new CcnxWrapper())
+  , m_policyManager(syncPolicyManager)
 #ifndef NS3_MODULE
   , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
   , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
@@ -109,8 +116,13 @@
 { 
 #ifndef NS3_MODULE
   // In NS3 module these functions are moved to StartApplication method
+
+  Ptr<security::Keychain> keychain = Ptr<security::Keychain>(new security::Keychain(Ptr<security::IdentityManager>::Create(),
+                                                                                    m_policyManager,
+                                                                                    NULL));
+  m_handler = Ptr<Wrapper>(new Wrapper(keychain));
   
-  m_ccnxHandle->setInterestFilter (m_syncPrefix,
+  m_handler->setInterestFilter (m_syncPrefix,
                                    bind (&SyncLogic::respondSyncInterest, this, _1));
 
   m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
@@ -121,7 +133,7 @@
 
 SyncLogic::~SyncLogic ()
 {
-  m_ccnxHandle->clearInterestFilter (m_syncPrefix);
+  m_handler->clearInterestFilter (Name(m_syncPrefix));
 }
 
 #ifdef NS3_MODULE
@@ -152,7 +164,7 @@
 void
 SyncLogic::stop()
 {
-  m_ccnxHandle->clearInterestFilter (m_syncPrefix);
+  m_handler->clearInterestFilter (Name(m_syncPrefix));
   m_scheduler.cancel (REEXPRESSING_INTEREST);
   m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
 }
@@ -166,9 +178,9 @@
 boost::tuple<DigestConstPtr, std::string>
 SyncLogic::convertNameToDigestAndType (const std::string &name)
 {
-  BOOST_ASSERT (name.find (m_syncPrefix) == 0);
+  BOOST_ASSERT (name.find (m_syncPrefix.toUri()) == 0);
 
-  string hash = name.substr (m_syncPrefix.size (), name.size ()-m_syncPrefix.size ());
+  string hash = name.substr (m_syncPrefix.toUri().size (), name.size ()-m_syncPrefix.toUri().size ());
   if (hash[0] == '/')
     hash = hash.substr (1, hash.size ()-1);
   string interestType = "normal";
@@ -190,8 +202,10 @@
 }
 
 void
-SyncLogic::respondSyncInterest (const string &name)
+SyncLogic::respondSyncInterest (ndn::Ptr<ndn::Interest> interest)
 {
+  _LOG_DEBUG("respondSyncInterest: " << interest->getName().toUri());
+  string name = interest->getName().toUri();
   try
     {
       _LOG_TRACE ("<< I " << name);
@@ -218,8 +232,12 @@
 }
 
 void
-SyncLogic::respondSyncData (const std::string &name, const char *wireData, size_t len)
+SyncLogic::respondSyncData (Ptr<Data> data)
 {
+  string name = data->getName().toUri();
+  const char *wireData = data->content().buf();
+  size_t len = data->content().size();
+
   try
     {
       _LOG_TRACE ("<< D " << name);
@@ -247,10 +265,32 @@
     }
 }
 
+void
+SyncLogic::onSyncDataTimeout(Ptr<Closure> closure, Ptr<ndn::Interest> interest, int retry)
+{
+  if(retry > 0)
+    {
+      Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
+                                                         boost::bind(&SyncLogic::onSyncDataTimeout, 
+                                                                     this, 
+                                                                     _1, 
+                                                                     _2, 
+                                                                     retry - 1),
+                                                         closure->m_unverifiedCallback,
+                                                         closure->m_stepCount)
+                                             );
+      m_handler->sendInterest(interest, newClosure);
+    }
+}
+
+void
+SyncLogic::onSyncDataUnverified()
+{}
 
 void
 SyncLogic::processSyncInterest (const std::string &name, DigestConstPtr digest, bool timedProcessing/*=false*/)
 {
+  _LOG_DEBUG("processSyncInterest");
   DigestConstPtr rootDigest;
   {
     recursive_mutex::scoped_lock lock (m_stateMutex);
@@ -435,7 +475,7 @@
 void
 SyncLogic::processSyncRecoveryInterest (const std::string &name, DigestConstPtr digest)
 {
-  
+  _LOG_DEBUG("processSyncRecoveryInterest");
   DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
 
   if (stateInDiffLog == m_log.end ())
@@ -564,6 +604,7 @@
 void
 SyncLogic::sendSyncInterest ()
 {
+  _LOG_DEBUG("sendSyncInterest");
   ostringstream os;
 
   {
@@ -574,13 +615,25 @@
     _LOG_TRACE (">> I " << os.str ());
   }
 
+  _LOG_DEBUG("sendSyncInterest: " << os.str());
+
   m_scheduler.cancel (REEXPRESSING_INTEREST);
   m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (m_syncInterestReexpress),
                         bind (&SyncLogic::sendSyncInterest, this),
                         REEXPRESSING_INTEREST);
-  
-  m_ccnxHandle->sendInterest (os.str (),
-                              bind (&SyncLogic::respondSyncData, this, _1, _2, _3));
+
+  Ptr<ndn::Interest> interestPtr = Ptr<ndn::Interest>(new ndn::Interest(os.str()));
+  Ptr<Closure> closure = Ptr<Closure> (new Closure(boost::bind(&SyncLogic::respondSyncData, 
+                                                               this, 
+                                                               _1),
+						   boost::bind(&SyncLogic::onSyncDataTimeout,
+                                                               this,
+                                                               _1, 
+                                                               _2,
+                                                               0),
+						   boost::bind(&SyncLogic::onSyncDataUnverified,
+                                                               this)));
+  m_handler->sendInterest(interestPtr, closure);
 }
 
 void
@@ -601,8 +654,18 @@
                             REEXPRESSING_RECOVERY_INTEREST);
     }
 
-  m_ccnxHandle->sendInterest (os.str (),
-                              bind (&SyncLogic::respondSyncData, this, _1, _2, _3));
+  Ptr<ndn::Interest> interestPtr = Ptr<ndn::Interest>(new ndn::Interest(os.str()));
+  Ptr<Closure> closure = Ptr<Closure> (new Closure(boost::bind(&SyncLogic::respondSyncData, 
+                                                               this, 
+                                                               _1),
+						   boost::bind(&SyncLogic::onSyncDataTimeout,
+                                                               this,
+                                                               _1, 
+                                                               _2,
+                                                               0),
+						   boost::bind(&SyncLogic::onSyncDataUnverified,
+                                                               this)));
+  m_handler->sendInterest (interestPtr, closure);
 }
 
 
@@ -623,10 +686,13 @@
   int size = ssm.ByteSize();
   char *wireData = new char[size];
   ssm.SerializeToArray(wireData, size);
-  m_ccnxHandle->publishRawData (name,
-                             wireData,
-                             size,
-                             m_syncResponseFreshness); // in NS-3 it doesn't have any effect... yet
+  Blob blob(wireData, size);
+  Name dataName(name);
+  Name signingIdentity = m_policyManager->inferSigningIdentity(dataName);
+  m_handler->publishDataByIdentity (dataName,
+                                    blob,
+                                    signingIdentity,
+                                    m_syncResponseFreshness); // in NS-3 it doesn't have any effect... yet
   delete []wireData;
 
   // checking if our own interest got satisfied
diff --git a/src/sync-logic.h b/src/sync-logic.h
index 1bc5984..b7152cc 100644
--- a/src/sync-logic.h
+++ b/src/sync-logic.h
@@ -29,12 +29,13 @@
 #include <memory>
 #include <map>
 
-#include "ccnx/sync-ccnx-wrapper.h"
+#include <ndn.cxx/wrapper/wrapper.h>
 #include "sync-interest-table.h"
 #include "sync-diff-state.h"
 #include "sync-full-state.h"
 #include "sync-std-name-info.h"
 #include "sync-scheduler.h"
+#include "sync-policy-manager.h"
 
 #include "sync-diff-state-container.h"
 
@@ -82,11 +83,13 @@
    * @param ccnxHandle ccnx handle
    * the app data when new remote names are learned
    */
-  SyncLogic (const std::string &syncPrefix,
+  SyncLogic (const ndn::Name& syncPrefix,
+             ndn::Ptr<SyncPolicyManager> syncPolicyManager,
              LogicUpdateCallback onUpdate,
              LogicRemoveCallback onRemove);
 
-  SyncLogic (const std::string &syncPrefix,
+  SyncLogic (const ndn::Name& syncPrefix,
+             ndn::Ptr<SyncPolicyManager> syncPolicyManager,
              LogicPerBranchCallback onUpdateBranch);
 
   ~SyncLogic ();
@@ -100,14 +103,14 @@
    * @brief respond to the Sync Interest; a lot of logic needs to go in here
    * @param interest the Sync Interest in string format
    */
-  void respondSyncInterest (const std::string &interest);
+  void respondSyncInterest (ndn::Ptr<ndn::Interest>);
 
   /**
    * @brief process the fetched sync data
    * @param name the data name
    * @param dataBuffer the sync data
    */
-  void respondSyncData (const std::string &name, const char *wireData, size_t len);
+  void respondSyncData (ndn::Ptr<ndn::Data> data);
 
   /**
    * @brief remove a participant's subtree from the sync tree
@@ -142,6 +145,12 @@
   delayedChecksLoop ();
 
   void
+  onSyncDataTimeout(ndn::Ptr<ndn::Closure> closure, ndn::Ptr<ndn::Interest> interest, int retry);
+
+  void
+  onSyncDataUnverified();
+
+  void
   processSyncInterest (const std::string &name,
                        DigestConstPtr digest, bool timedProcessing=false);
 
@@ -187,12 +196,13 @@
   std::string m_outstandingInterestName;
   SyncInterestTable m_syncInterestTable;
 
-  std::string m_syncPrefix;
+  ndn::Name m_syncPrefix;
   LogicUpdateCallback m_onUpdate;
   LogicRemoveCallback m_onRemove;
   LogicPerBranchCallback m_onUpdateBranch;
   bool m_perBranch;
-  CcnxWrapperPtr m_ccnxHandle;
+  ndn::Ptr<SyncPolicyManager> m_policyManager;
+  ndn::Ptr<ndn::Wrapper> m_handler;
 
   Scheduler m_scheduler;
 
diff --git a/src/sync-policy-manager.cc b/src/sync-policy-manager.cc
new file mode 100644
index 0000000..86726d3
--- /dev/null
+++ b/src/sync-policy-manager.cc
@@ -0,0 +1,341 @@
+/* -*- 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-policy-manager.h"
+
+#include "sync-intro-certificate.h"
+#include "sync-logging.h"
+
+using namespace ndn;
+using namespace ndn::security;
+using namespace std;
+
+INIT_LOGGER("SyncPolicyManager");
+
+SyncPolicyManager::SyncPolicyManager(const Name& signingIdentity,
+				     const Name& signingCertificateName,
+				     const Name& syncPrefix,
+                                     int stepLimit)
+  : m_signingIdentity(signingIdentity)
+  , m_signingCertificateName(signingCertificateName.getPrefix(signingCertificateName.size()-1))
+  , m_syncPrefix(syncPrefix)
+  , m_stepLimit(stepLimit)
+{
+  Name wotPrefix = syncPrefix;
+  wotPrefix.append("WOT");
+  m_syncPrefixRegex = Regex::fromName(syncPrefix);
+  m_wotPrefixRegex = Regex::fromName(wotPrefix);
+  m_chatDataPolicy = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^[^<FH>]*<FH>([^<chronos>]*)<chronos><>",
+                                                                    "^(<>*)<KEY><DSK-.*><ID-CERT><>$",
+                                                                    "==", "\\1", "\\1", true));  
+}
+  
+SyncPolicyManager::~SyncPolicyManager()
+{}
+
+bool 
+SyncPolicyManager::skipVerifyAndTrust (const Data& data)
+{ return false; }
+
+bool
+SyncPolicyManager::requireVerify (const Data& data)
+{ return true; }
+
+Ptr<ValidationRequest>
+SyncPolicyManager::checkVerificationPolicy(Ptr<Data> data, 
+					   const int& stepCount, 
+					   const DataCallback& verifiedCallback,
+					   const UnverifiedCallback& unverifiedCallback)
+{
+#ifdef _DEBUG
+  _LOG_DEBUG("checkVerificationPolicy");
+  verifiedCallback(data);
+  return NULL;
+#else
+  //TODO:
+  if(stepCount > m_stepLimit)
+    {
+      unverifiedCallback(data);
+      return NULL;
+    }
+
+  Ptr<const signature::Sha256WithRsa> sha256sig = DynamicCast<const signature::Sha256WithRsa> (data->getSignature());
+  if(KeyLocator::KEYNAME != sha256sig->getKeyLocator().getType())
+    {
+      unverifiedCallback(data);
+      return NULL;
+    }
+
+  const Name& keyLocatorName = sha256sig->getKeyLocator().getKeyName();
+  
+  // if data is intro cert
+  if(m_wotPrefixRegex->match(data->getName()))
+    {
+      Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+      map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
+      if(m_trustedIntroducers.end() != it)
+	{
+	  if(verifySignature(*data, it->second))
+	    verifiedCallback(data);
+	  else
+	    unverifiedCallback(data);
+	  return NULL;
+	}
+      else
+	return prepareRequest(keyName, true, data, stepCount, verifiedCallback, unverifiedCallback);
+    }
+
+  // if data is sync data or chat data
+  if(m_syncPrefixRegex->match(data->getName()) || m_chatDataPolicy->satisfy(*data))
+    {
+      Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+
+      map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
+      if(m_trustedIntroducers.end() != it)
+	{
+	  if(verifySignature(*data, it->second))
+	    verifiedCallback(data);
+	  else
+	    unverifiedCallback(data);
+	  return NULL;
+	}
+
+      it = m_trustedProducers.find(keyName);
+      if(m_trustedProducers.end() != it)
+	{
+	  if(verifySignature(*data, it->second))
+	    verifiedCallback(data);
+	  else
+	    unverifiedCallback(data);
+	  return NULL;
+	}
+      
+      return prepareRequest(keyName, false, data, stepCount, verifiedCallback, unverifiedCallback);
+    }
+  
+  unverifiedCallback(data);
+  return NULL;
+#endif
+}
+
+bool 
+SyncPolicyManager::checkSigningPolicy(const Name& dataName, 
+				      const Name& certificateName)
+{ 
+
+#ifdef _DEBUG
+  _LOG_DEBUG("checkSigningPolicy");
+  return true;
+#else
+  return (m_syncPrefixRegex->match(dataName) && certificateName == m_signingCertificateName) ? true : false; 
+#endif
+}
+    
+Name 
+SyncPolicyManager::inferSigningIdentity(const ndn::Name& dataName)
+{ return m_signingIdentity; }
+
+void
+SyncPolicyManager::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
+{
+  if(isIntroducer)
+    m_trustedIntroducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
+  else
+    m_trustedProducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
+}
+
+void
+SyncPolicyManager::addChatDataRule(const Name& prefix, 
+                                   const IdentityCertificate& identityCertificate,
+                                   bool isIntroducer)
+{
+  // Name dataPrefix = prefix;
+  // dataPrefix.append("chronos").append(m_syncPrefix.get(-1));
+  // Ptr<Regex> dataRegex = Regex::fromName(prefix);
+  // Name certName = identityCertificate.getName();
+  // Name signerName = certName.getPrefix(certName.size()-1);
+  // Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
+  
+  // SpecificPolicyRule rule(dataRegex, signerRegex);
+  // map<Name, SpecificPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
+  // if(it != m_chatDataRules.end())
+  //   it->second = rule;
+  // else
+  //   m_chatDataRules.insert(pair <Name, SpecificPolicyRule > (dataPrefix, rule));
+
+  addTrustAnchor(identityCertificate, isIntroducer);
+}
+
+
+Ptr<const vector<Name> >
+SyncPolicyManager::getAllIntroducerName()
+{
+  Ptr<vector<Name> > nameList = Ptr<vector<Name> >(new vector<Name>);
+  
+  map<Name, Publickey>::iterator it =  m_trustedIntroducers.begin();
+  for(; it != m_trustedIntroducers.end(); it++)
+    nameList->push_back(it->first);
+  
+  return nameList;
+}
+
+Ptr<ValidationRequest>
+SyncPolicyManager::prepareRequest(const Name& keyName, 
+				  bool forIntroducer,
+				  Ptr<Data> data,
+				  const int & stepCount, 
+				  const DataCallback& verifiedCallback,
+				  const UnverifiedCallback& unverifiedCallback)
+{
+  Ptr<Name> interestPrefixName = Ptr<Name>(new Name(m_syncPrefix));
+  interestPrefixName->append("WOT").append(keyName).append("INTRO-CERT");
+
+  Ptr<const std::vector<ndn::Name> > nameList = getAllIntroducerName();
+
+  Name interestName = *interestPrefixName;
+  interestName.append(nameList->at(0));
+
+  if(forIntroducer)
+    interestName.append("INTRODUCER");
+
+  Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
+  interest->setChildSelector(Interest::CHILD_RIGHT);
+
+  DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified, 
+							   this, 
+							   _1,
+							   forIntroducer, 
+							   data,
+							   verifiedCallback,
+							   unverifiedCallback);
+                                                             
+  UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified, 
+								   this, 
+								   _1, 
+								   interestPrefixName,
+								   forIntroducer,
+								   nameList,
+								   1,
+								   data,
+								   verifiedCallback,
+								   unverifiedCallback);
+
+    
+  Ptr<ValidationRequest> nextStep = Ptr<ValidationRequest>(new ValidationRequest(interest, 
+										 requestedCertVerifiedCallback,
+										 requestedCertUnverifiedCallback,
+										 1,
+										 m_stepLimit-1)
+							   );
+  return nextStep;
+}
+
+void
+SyncPolicyManager::onIntroCertVerified(Ptr<Data> introCertificateData,
+				       bool forIntroducer,
+				       Ptr<Data> originalData,
+				       const DataCallback& verifiedCallback,
+				       const UnverifiedCallback& unverifiedCallback)
+{
+  Ptr<SyncIntroCertificate> introCertificate = Ptr<SyncIntroCertificate>(new SyncIntroCertificate(*introCertificateData));
+  if(forIntroducer)
+    m_trustedIntroducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
+  else
+    m_trustedProducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
+
+  if(verifySignature(*originalData, introCertificate->getPublicKeyInfo()))      
+    verifiedCallback(originalData);    
+  else
+    unverifiedCallback(originalData);
+}
+
+void 
+SyncPolicyManager::onIntroCertUnverified(Ptr<Data> introCertificateData,
+					 Ptr<Name> interestPrefixName,
+					 bool forIntroducer,
+					 Ptr<const std::vector<ndn::Name> > introNameList,
+					 const int& nextIntroducerIndex,
+					 Ptr<Data> originalData,
+					 const DataCallback& verifiedCallback,
+					 const UnverifiedCallback& unverifiedCallback)
+{
+  Name interestName = *interestPrefixName;
+  if(nextIntroducerIndex < introNameList->size())
+    interestName.append(introNameList->at(nextIntroducerIndex));
+  else
+    unverifiedCallback(originalData);
+
+  if(forIntroducer)
+    interestName.append("INTRODUCER");
+  
+  Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
+  interest->setChildSelector(Interest::CHILD_RIGHT);
+
+  DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified, 
+							   this, 
+							   _1,
+							   forIntroducer, 
+							   originalData,
+							   verifiedCallback,
+							   unverifiedCallback);
+    
+  UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified, 
+								   this, 
+								   _1,
+								   interestPrefixName,
+								   forIntroducer,
+								   introNameList,
+								   nextIntroducerIndex + 1,
+								   originalData, 
+								   verifiedCallback,
+								   unverifiedCallback);
+  
+  TimeoutCallback requestedCertTimeoutCallback = boost::bind(&SyncPolicyManager::onIntroCertTimeOut, 
+							     this, 
+							     _1, 
+							     _2, 
+							     1,
+							     requestedCertUnverifiedCallback,
+							     originalData);
+      
+  Ptr<Closure> closure = Ptr<Closure> (new Closure(requestedCertVerifiedCallback,
+						   requestedCertTimeoutCallback,
+						   requestedCertUnverifiedCallback,
+						   m_stepLimit-1)
+				       );
+    
+  m_handler->sendInterest(interest, closure);
+}
+
+void
+SyncPolicyManager::onIntroCertTimeOut(Ptr<Closure> closure, 
+				      Ptr<Interest> interest, 
+				      int retry, 
+				      const UnverifiedCallback& unverifiedCallback,
+				      Ptr<Data> data)
+{
+  if(retry > 0)
+    {
+      Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
+							 boost::bind(&SyncPolicyManager::onIntroCertTimeOut, 
+								     this, 
+								     _1, 
+								     _2, 
+								     retry - 1, 
+								     unverifiedCallback,
+								     data),
+							 closure->m_unverifiedCallback,
+							 closure->m_stepCount)
+					     );
+      m_handler->sendInterest(interest, newClosure);
+    }
+  else
+    unverifiedCallback(data);
+}
diff --git a/src/sync-policy-manager.h b/src/sync-policy-manager.h
new file mode 100644
index 0000000..418abc7
--- /dev/null
+++ b/src/sync-policy-manager.h
@@ -0,0 +1,124 @@
+/* -*- 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_POLICY_MANAGER_H
+#define SYNC_POLICY_MANAGER_H
+
+#include <ndn.cxx/security/policy/policy-manager.h>
+#include <ndn.cxx/security/policy/identity-policy-rule.h>
+#include <ndn.cxx/security/certificate/identity-certificate.h>
+#include <ndn.cxx/regex/regex.h>
+#include <ndn.cxx/wrapper/wrapper.h>
+#include "specific-policy-rule.h"
+
+
+class SyncPolicyManager : public ndn::security::PolicyManager
+{
+public:
+  SyncPolicyManager(const ndn::Name& signingIdentity,
+                    const ndn::Name& signingCertificateName,
+                    const ndn::Name& syncPrefix,
+                    int m_stepLimit = 3);
+  
+  virtual
+  ~SyncPolicyManager();
+
+  bool 
+  skipVerifyAndTrust (const ndn::Data& data);
+
+  bool
+  requireVerify (const ndn::Data& data);
+
+  ndn::Ptr<ndn::security::ValidationRequest>
+  checkVerificationPolicy(ndn::Ptr<ndn::Data> data, 
+                          const int& stepCount, 
+                          const ndn::DataCallback& verifiedCallback,
+                          const ndn::UnverifiedCallback& unverifiedCallback);
+
+  bool 
+  checkSigningPolicy(const ndn::Name& dataName, 
+                     const ndn::Name& certificateName);
+    
+  ndn::Name 
+  inferSigningIdentity(const ndn::Name& dataName);
+
+  void
+  addTrustAnchor(const ndn::security::IdentityCertificate& identityCertificate, bool isIntroducer);
+
+  void
+  addChatDataRule(const ndn::Name& prefix, 
+                  const ndn::security::IdentityCertificate& identityCertificate,
+                  bool isIntroducer);
+
+  inline void 
+  setWrapper(ndn::Wrapper* handler)
+  { m_handler = handler; }
+
+private:
+  ndn::Ptr<ndn::security::ValidationRequest>
+  prepareIntroducerRequest(const ndn::Name& keyName,
+                           ndn::Ptr<ndn::Data> data, 
+                           const int & stepCount, 
+                           const ndn::DataCallback& verifiedCallback,
+                           const ndn::UnverifiedCallback& unverifiedCallback);
+  
+  ndn::Ptr<const std::vector<ndn::Name> >
+  getAllIntroducerName();
+
+  ndn::Ptr<ndn::security::ValidationRequest>
+  prepareRequest(const ndn::Name& keyName, 
+                 bool forIntroducer,
+                 ndn::Ptr<ndn::Data> data,
+                 const int & stepCount, 
+                 const ndn::DataCallback& verifiedCallback,
+                 const ndn::UnverifiedCallback& unverifiedCallback);
+
+  void
+  onIntroCertVerified(ndn::Ptr<ndn::Data> introCertificateData,
+                      bool forIntroducer,
+                      ndn::Ptr<ndn::Data> originalData,
+                      const ndn::DataCallback& verifiedCallback,
+                      const ndn::UnverifiedCallback& unverifiedCallback);
+
+  void 
+  onIntroCertUnverified(ndn::Ptr<ndn::Data> introCertificateData,
+                        ndn::Ptr<ndn::Name> interestPrefixName,
+                        bool forIntroducer,
+                        ndn::Ptr<const std::vector<ndn::Name> > introNameList,
+                        const int& nextIntroducerIndex,
+                        ndn::Ptr<ndn::Data> originalData,
+                        const ndn::DataCallback& verifiedCallback,
+                        const ndn::UnverifiedCallback& unverifiedCallback);
+
+  void
+  onIntroCertTimeOut(ndn::Ptr<ndn::Closure> closure, 
+                     ndn::Ptr<ndn::Interest> interest, 
+                     int retry, 
+                     const ndn::UnverifiedCallback& unverifiedCallback,
+                     ndn::Ptr<ndn::Data> data);
+
+
+
+private:
+  ndn::Name m_signingIdentity;
+  ndn::Name m_signingCertificateName;
+  ndn::Name m_syncPrefix;
+  int m_stepLimit;
+  ndn::Ptr<ndn::Regex> m_syncPrefixRegex;
+  ndn::Ptr<ndn::Regex> m_wotPrefixRegex;
+  ndn::Ptr<ndn::security::IdentityPolicyRule> m_chatDataPolicy; 
+  std::map<ndn::Name, ndn::security::Publickey> m_trustedIntroducers;
+  std::map<ndn::Name, ndn::security::Publickey> m_trustedProducers;
+  std::map<ndn::Name, SpecificPolicyRule> m_chatDataRules;
+
+  ndn::Wrapper* m_handler;
+};
+
+#endif
diff --git a/tests/test_scheduler.cc b/tests/test_scheduler.cc.tmp
similarity index 100%
rename from tests/test_scheduler.cc
rename to tests/test_scheduler.cc.tmp
diff --git a/tests/test_socket.cc b/tests/test_socket.cc
new file mode 100644
index 0000000..2305230
--- /dev/null
+++ b/tests/test_socket.cc
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Chaoyi Bian <bcy@pku.edu.cn>
+ *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/output_test_stream.hpp> 
+using boost::test_tools::output_test_stream;
+
+#include <boost/make_shared.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+#include "sync-logging.h"
+
+#include "ccnx/sync-socket.h"
+
+extern "C" {
+#include <unistd.h>
+}
+
+using namespace Sync;
+using namespace std;
+using namespace boost;
+
+INIT_LOGGER ("Test.AppSocket");
+
+#define PRINT 
+//std::cout << "Line: " << __LINE__ << std::endl;
+
+class TestSocketApp {
+public:
+  map<string, string> data;
+  void set(ndn::Ptr<ndn::Data> dataPacket) {
+    // _LOG_FUNCTION (this << ", " << str1);
+    string str1(dataPacket->getName().toUri());
+    string str2(dataPacket->content().buf(), dataPacket->content().size());
+    data.insert(make_pair(str1, str2));
+    // cout << str1 << ", " << str2 << endl;
+  }
+
+  void set(string str1, const char * buf, int len) {
+    string str2(buf, len);
+    data.insert(make_pair(str1, str2));
+  }
+  
+  void setNum(ndn::Ptr<ndn::Data> dataPacket) {
+    int n = dataPacket->content().size() / 4;
+    int *numbers = new int [n];
+    memcpy(numbers, dataPacket->content().buf(), dataPacket->content().size());
+    for (int i = 0; i < n; i++) {
+      sum += numbers[i];
+    }
+    delete numbers;
+
+  }
+
+  void setNum(string str1, const char * buf, int len) {
+    int n = len / 4;
+    int *numbers = new int [n];
+    memcpy(numbers, buf, len);
+    for (int i = 0; i < n; i++) {
+      sum += numbers[i];
+    }
+    delete numbers;
+  }
+
+  int sum;
+
+  void fetchAll(const vector<MissingDataInfo> &v, SyncSocket *socket) {
+    int n = v.size();
+
+    PRINT
+
+    for (int i = 0; i < n; i++) {
+      for(SeqNo s = v[i].low; s <= v[i].high; ++s) {
+        //PRINT
+        socket->fetchData(v[i].prefix, s, bind(&TestSocketApp::set, this, _1));
+      }
+    }
+  }
+
+  void fetchNumbers(const vector<MissingDataInfo> &v, SyncSocket *socket) {
+    int n = v.size();
+
+    PRINT
+
+    std::cout << "In fetchNumbers. size of v is:  " << n << std::endl;
+    for (int i = 0; i < n; i++) {
+      std::cout << "In fetchNumbers. v[i].low is (" <<v[i].low.getSession() <<", " << v[i].low.getSeq() << ") v[i].high is ("<<v[i].high.getSession() <<", " <<v[i].high.getSeq()<<")" << std::endl;
+      for(SeqNo s = v[i].low; s <= v[i].high; ++s) {
+        PRINT
+        socket->fetchData(v[i].prefix, s, bind(&TestSocketApp::setNum, this, _1));
+      }
+    }
+  }
+
+  void pass(const string &prefix) {
+  }
+
+  string toString(){
+    map<string, string>::iterator it = data.begin(); 
+    string str = "\n";
+    for (; it != data.end(); ++it){
+      str += "<";
+      str += it->first;
+      str += "|";
+      str += it->second;
+      str += ">";
+      str += "\n";
+    }
+
+    return str;
+  }
+
+};
+
+BOOST_AUTO_TEST_CASE (AppSocketTest)
+{
+  INIT_LOGGERS ();
+  
+  TestSocketApp a1, a2, a3;
+	
+  string syncPrefix("/let/us/sync");
+  string p1("/irl.cs.ucla.edu"), p2("/yakshi.org"), p3("/google.com");
+
+  ndn::Ptr<SyncPolicyManager> policyManager1 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/alice"), ndn::Name("/ndn/ucla.edu/alice/KEY/dsk-1382934202/ID-CERT/%FD%FF%FF%FF%FF%DEk%C0%0B"), ndn::Name(syncPrefix)));
+
+  _LOG_DEBUG ("s1");
+  SyncSocket s1 (syncPrefix, policyManager1, bind(&TestSocketApp::fetchAll, &a1, _1, _2), bind(&TestSocketApp::pass, &a1, _1));
+  this_thread::sleep (posix_time::milliseconds (50));
+  _LOG_DEBUG ("s2");
+  SyncSocket s2 (syncPrefix, policyManager1, bind(&TestSocketApp::fetchAll, &a2, _1, _2), bind(&TestSocketApp::pass, &a2, _1));
+  this_thread::sleep (posix_time::milliseconds (50));
+  SyncSocket s3 (syncPrefix, policyManager1, bind(&TestSocketApp::fetchAll, &a3, _1, _2), bind(&TestSocketApp::pass, &a3, _1));
+  this_thread::sleep (posix_time::milliseconds (50));
+
+  // single source
+  string data0 = "Very funny Scotty, now beam down my clothes";
+  _LOG_DEBUG ("s1 publish");
+  s1.publishData (p1, 0, data0.c_str(), data0.size(), 10); 
+  this_thread::sleep (posix_time::milliseconds (1000));
+
+  // from code logic, we won't be fetching our own data
+  a1.set(p1 + "/0/0", data0.c_str(), data0.size());
+  BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
+  BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
+
+  // single source, multiple data at once
+  string data1 = "Yes, give me that ketchup";
+  string data2 = "Don't look conspicuous, it draws fire";
+
+  _LOG_DEBUG ("s1 publish");
+  s1.publishData (p1, 0, data1.c_str(), data1.size(), 10);
+  _LOG_DEBUG ("s1 publish");
+  s1.publishData (p1, 0, data2.c_str(), data2.size(), 10);
+  this_thread::sleep (posix_time::milliseconds (1000));
+  
+  // from code logic, we won't be fetching our own data
+  a1.set(p1 + "/0/1", data1.c_str(), data1.size());
+  a1.set(p1 + "/0/2", data2.c_str(), data2.size());
+  BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
+  BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
+
+  // another single source
+  string data3 = "You surf the Internet, I surf the real world";
+  string data4 = "I got a fortune cookie once that said 'You like Chinese food'";
+  string data5 = "Real men wear pink. Why? Because their wives make them";
+  _LOG_DEBUG ("s3 publish");
+  s3.publishData(p3, 0, data3.c_str(), data3.size(), 10); 
+  this_thread::sleep (posix_time::milliseconds (200));
+  
+  // another single source, multiple data at once
+  s2.publishData(p2, 0, data4.c_str(), data4.size(), 10); 
+  s2.publishData(p2, 0, data5.c_str(), data5.size(), 10);
+  this_thread::sleep (posix_time::milliseconds (1000));
+
+  // from code logic, we won't be fetching our own data
+  a3.set(p3 + "/0/0", data3.c_str(), data3.size());
+  a2.set(p2 + "/0/0", data4.c_str(), data4.size());
+  a2.set(p2 + "/0/1", data5.c_str(), data5.size());
+  BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
+  BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
+
+  // not sure weither this is simultanous data generation from multiple sources
+  _LOG_DEBUG ("Simultaneous publishing");
+  string data6 = "Shakespeare says: 'Prose before hos.'";
+  string data7 = "Pick good people, talent never wears out";
+  s1.publishData(p1, 0, data6.c_str(), data6.size(), 10); 
+  // this_thread::sleep (posix_time::milliseconds (1000));
+  s2.publishData(p2, 0, data7.c_str(), data7.size(), 10); 
+  this_thread::sleep (posix_time::milliseconds (1500));
+
+  // from code logic, we won't be fetching our own data
+  a1.set(p1 + "/0/3", data6.c_str(), data6.size());
+  a2.set(p2 + "/0/2", data7.c_str(), data7.size());
+  // a1.set(p1 + "/0/1", data6);
+  // a2.set(p2 + "/0/0", data7);
+  BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
+  BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
+
+  _LOG_DEBUG("Begin new test");
+  std::cout << "Begin new Test " << std::endl;
+  string syncRawPrefix = "/this/is/the/prefix";
+  ndn::Ptr<SyncPolicyManager> policyManager2 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/alice"), ndn::Name("/ndn/ucla.edu/alice/KEY/dsk-1382934202/ID-CERT/%FD%FF%FF%FF%FF%DEk%C0%0B"), ndn::Name(syncRawPrefix)));
+
+  a1.sum = 0;
+  a2.sum = 0;
+  SyncSocket s4 (syncRawPrefix, policyManager2, bind(&TestSocketApp::fetchNumbers, &a1, _1, _2), bind(&TestSocketApp::pass, &a1, _1));
+  SyncSocket s5 (syncRawPrefix, policyManager2, bind(&TestSocketApp::fetchNumbers, &a2, _1, _2), bind(&TestSocketApp::pass, &a2, _1));
+
+  int num[5] = {0, 1, 2, 3, 4};
+
+  string p4 = "/xiaonei.com";
+  string p5 = "/mitbbs.com";
+
+  s4.publishData(p4, 0,(const char *) num, sizeof(num), 10);
+  a1.setNum(p4, (const char *) num, sizeof (num));
+
+  this_thread::sleep (posix_time::milliseconds (1000));
+  BOOST_CHECK(a1.sum == a2.sum && a1.sum == 10);
+
+  int newNum[5] = {9, 7, 2, 1, 1};
+
+  s5.publishData(p5, 0,(const char *) newNum, sizeof(newNum), 10);
+  a2.setNum(p5, (const char *)newNum, sizeof (newNum));
+  this_thread::sleep (posix_time::milliseconds (1000));
+  BOOST_CHECK_EQUAL(a1.sum, a2.sum);
+  BOOST_CHECK_EQUAL(a1.sum, 30);
+
+  _LOG_DEBUG ("Finish");
+}
diff --git a/tests/test_sync_logic.cc b/tests/test_sync_logic.cc
index e6b7d04..651545b 100644
--- a/tests/test_sync_logic.cc
+++ b/tests/test_sync_logic.cc
@@ -27,7 +27,8 @@
 
 #include <boost/make_shared.hpp>
 
-#include "ccnx/sync-ccnx-wrapper.h"
+// #include <ndn.cxx/wrapper/wrapper.h>
+#include "sync-policy-manager.h"
 #include "sync-logic.h"
 #include "sync-seq-no.h"
 
@@ -75,7 +76,9 @@
 {
   Handler h1 ("1");
 
-  SyncLogic l1 ("/bcast", bind (&Handler::wrapper, &h1, _1), bind (&Handler::onRemove, &h1, _1));
+  ndn::Ptr<SyncPolicyManager> policyManager1 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/alice"), ndn::Name("/ndn/ucla.edu/alice/KEY/dsk-1382934202/ID-CERT/%FD%FF%FF%FF%FF%DEk%C0%0B"), ndn::Name("/bcast")));
+
+  SyncLogic l1 (ndn::Name("/bcast"), policyManager1, bind (&Handler::wrapper, &h1, _1), bind (&Handler::onRemove, &h1, _1));
 
   std::string oldDigest  = l1.getRootDigest();
   
@@ -86,7 +89,10 @@
   BOOST_CHECK_EQUAL (h1.m_map.size (), 0);
 
   Handler h2 ("2");
-  SyncLogic l2 ("/bcast", bind (&Handler::wrapper, &h2, _1), bind (&Handler::onRemove, &h2, _1));
+
+ ndn::Ptr<SyncPolicyManager> policyManager2 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/bob"), ndn::Name("/ndn/ucla.edu/bob/KEY/dsk-1382934206/ID-CERT/%FD%FF%FF%FF%FF%DEl%0BC"), ndn::Name("/bcast")));
+
+  SyncLogic l2 (ndn::Name("/bcast"), policyManager2, bind (&Handler::wrapper, &h2, _1), bind (&Handler::onRemove, &h2, _1));
   
   sleep (1);
   BOOST_CHECK_EQUAL (h1.m_map.size (), 0);
diff --git a/wscript b/wscript
index 7ec9fdf..560f1fe 100644
--- a/wscript
+++ b/wscript
@@ -7,7 +7,7 @@
 
 def options(opt):
     opt.load('compiler_c compiler_cxx boost doxygen gnu_dirs protoc')
-    opt.load('ndnx', tooldir=["waf-tools"])
+    # opt.load('ndnx', tooldir=["waf-tools"])
 
     syncopt = opt.add_option_group ("ChronoSync Options")
 
@@ -17,7 +17,7 @@
 
 def configure(conf):
     conf.load('compiler_c compiler_cxx gnu_dirs boost')
-    conf.load('ndnx')
+    # conf.load('ndnx')
 
     if conf.options.debug:
         conf.define ('_DEBUG', 1)
@@ -32,8 +32,11 @@
     else:
         conf.add_supported_cxxflags (cxxflags = ['-O3', '-g'])
 
-    conf.check_ndnx ()
-    conf.check_openssl ()
+    # conf.check_ndnx ()
+
+    conf.check_cfg(package='libndn.cxx', args=['--cflags', '--libs'], uselib_store='NDNCXX', mandatory=True)
+    conf.check_cfg(package='openssl', args=['--cflags', '--libs'], uselib_store='OPENSSL', mandatory=True)
+    # conf.check_openssl ()
 
     conf.check_boost(lib='system iostreams test thread')
 
@@ -55,7 +58,7 @@
         target="ChronoSync",
         features=['cxx', 'cxxshlib'],
         source =  bld.path.ant_glob (['src/**/*.cc', 'src/**/*.proto']),
-        use = 'BOOST BOOST_IOSTREAMS BOOST_THREAD SSL NDNX',
+        use = 'BOOST BOOST_IOSTREAMS BOOST_THREAD SSL NDNCXX OPENSSL',
         includes = ['src'],
         )