diff --git a/src/socket.cpp b/src/socket.cpp
new file mode 100644
index 0000000..55296ab
--- /dev/null
+++ b/src/socket.cpp
@@ -0,0 +1,150 @@
+/* -*- 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 Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
+ * @author Chaoyi Bian <bcy@pku.edu.cn>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "socket.hpp"
+#include "logger.hpp"
+
+INIT_LOGGER("Socket");
+
+
+namespace chronosync {
+
+Socket::Socket(const Name& syncPrefix,
+               const Name& userPrefix,
+               ndn::Face& face,
+               const UpdateCallback& updateCallback)
+  : m_userPrefix(userPrefix)
+  , m_face(face)
+  , m_logic(face,
+            syncPrefix,
+            userPrefix,
+            updateCallback)
+{
+}
+
+
+void
+Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness)
+{
+  publishData(ndn::dataBlock(ndn::tlv::Content, buf, len), freshness);
+}
+
+void
+Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness)
+{
+  shared_ptr<Data> data = make_shared<Data>();
+  data->setContent(content);
+  data->setFreshnessPeriod(freshness);
+
+  SeqNo newSeq = m_logic.getSeqNo() + 1;
+  Name dataName;
+  dataName.append(m_logic.getSessionName()).appendNumber(newSeq);
+  data->setName(dataName);
+
+  m_keyChain.sign(*data);
+
+  m_face.put(*data);
+
+  m_logic.updateSeqNo(newSeq);
+}
+
+void
+Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
+                  const ndn::OnDataValidated& dataCallback,
+                  int nRetries)
+{
+  Name interestName;
+  interestName.append(sessionName).appendNumber(seqNo);
+
+  Interest interest(interestName);
+  interest.setMustBeFresh(true);
+
+  ndn::OnDataValidationFailed failureCallback =
+    bind(&Socket::onDataValidationFailed, this, _1, _2);
+
+  m_face.expressInterest(interest,
+                         bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
+                         bind(&Socket::onDataTimeout, this, _1, nRetries,
+                              dataCallback, failureCallback));
+}
+
+void
+Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
+                  const ndn::OnDataValidated& dataCallback,
+                  const ndn::OnDataValidationFailed& failureCallback,
+                  const ndn::OnTimeout& onTimeout,
+                  int nRetries)
+{
+  _LOG_DEBUG(">> Socket::fetchData");
+  Name interestName;
+  interestName.append(sessionName).appendNumber(seqNo);
+
+  Interest interest(interestName);
+  interest.setMustBeFresh(true);
+
+  m_face.expressInterest(interest,
+                         bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
+                         onTimeout);
+
+  _LOG_DEBUG("<< Socket::fetchData");
+}
+
+void
+Socket::onData(const Interest& interest, Data& data,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onFailed)
+{
+  _LOG_DEBUG("Socket::onData");
+  // Placeholder for validator
+  onValidated(data.shared_from_this());
+}
+
+void
+Socket::onDataTimeout(const Interest& interest, int nRetries,
+                      const ndn::OnDataValidated& onValidated,
+                      const ndn::OnDataValidationFailed& onFailed)
+{
+  _LOG_DEBUG("Socket::onDataTimeout");
+  if (nRetries <= 0)
+    return;
+
+  m_face.expressInterest(interest,
+                         bind(&Socket::onData, this, _1, _2, onValidated, onFailed),
+                         bind(&Socket::onDataTimeout, this, _1, nRetries - 1,
+                              onValidated, onFailed));
+}
+
+void
+Socket::onDataValidationFailed(const shared_ptr<const Data>& data,
+                               const std::string& failureInfo)
+{
+}
+
+ndn::ConstBufferPtr
+Socket::getRootDigest() const
+{
+  return m_logic.getRootDigest();
+}
+
+} // namespace chronosync
diff --git a/src/socket.hpp b/src/socket.hpp
new file mode 100644
index 0000000..11dc684
--- /dev/null
+++ b/src/socket.hpp
@@ -0,0 +1,158 @@
+/* -*- 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 Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
+ * @author Chaoyi Bian <bcy@pku.edu.cn>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOSYNC_SOCKET_HPP
+#define CHRONOSYNC_SOCKET_HPP
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/validation-request.hpp>
+
+#include "logic.hpp"
+
+namespace chronosync {
+
+/**
+ * @brief A simple interface to interact with client code
+ *
+ * Though it is called Socket, it is not a real socket. It just trying to provide
+ * a simplified interface for data publishing and fetching.
+ *
+ * This interface simplify data publishing.  Client can simply dump raw data
+ * into this interface without handling the ChronoSync specific details, such
+ * as sequence number and session id.
+ *
+ * This interface also simplify data fetching.  Client only needs to provide a
+ * data fetching strategy (through a updateCallback).
+ */
+class Socket : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  Socket(const Name& syncPrefix,
+         const Name& userPrefix,
+         ndn::Face& face,
+         const UpdateCallback& updateCallback);
+
+  /**
+   * @brief Publish a data packet in the session and trigger synchronization updates
+   *
+   * This method will create a data packet with the supplied content.
+   * The packet name is the local session + seqNo.
+   * The seqNo is automatically maintained by internal Logic.
+   *
+   * @param buf Pointer to the bytes in content
+   * @param len size of the bytes in content
+   * @param freshness FreshnessPeriod of the data packet.
+   */
+  void
+  publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness);
+
+  /**
+   * @brief Publish a data packet in the session and trigger synchronization updates
+   *
+   * This method will create a data packet with the supplied content.
+   * The packet name is the local session + seqNo.
+   * The seqNo is automatically maintained by internal Logic.
+   *
+   * @param content Block that will be set as the content of the data packet.
+   * @param freshness FreshnessPeriod of the data packet.
+   */
+  void
+  publishData(const Block& content, const ndn::time::milliseconds& freshness);
+
+  /**
+   * @brief Retrive a data packet with a particular seqNo from a session
+   *
+   * @param sessionName The name of the target session.
+   * @param seq The seqNo of the data packet.
+   * @param onValidated The callback when the retrieved packet has been validated.
+   * @param nRetries The number of retries.
+   */
+  void
+  fetchData(const Name& sessionName, const SeqNo& seq,
+            const ndn::OnDataValidated& onValidated,
+            int nRetries = 0);
+
+  /**
+   * @brief Retrive a data packet with a particular seqNo from a session
+   *
+   * @param sessionName The name of the target session.
+   * @param seq The seqNo of the data packet.
+   * @param onValidated The callback when the retrieved packet has been validated.
+   * @param nRetries The number of retries.
+   */
+  void
+  fetchData(const Name& sessionName, const SeqNo& seq,
+            const ndn::OnDataValidated& onValidated,
+            const ndn::OnDataValidationFailed& onValidationFailed,
+            const ndn::OnTimeout& onTimeout,
+            int nRetries = 0);
+
+  /// @brief Get the root digest of current sync tree
+  ndn::ConstBufferPtr
+  getRootDigest() const;
+
+  Logic&
+  getLogic()
+  {
+    return m_logic;
+  }
+
+private:
+  void
+  onData(const Interest& interest, Data& data,
+         const ndn::OnDataValidated& dataCallback,
+         const ndn::OnDataValidationFailed& failCallback);
+
+  void
+  onDataTimeout(const Interest& interest, int nRetries,
+                const ndn::OnDataValidated& dataCallback,
+                const ndn::OnDataValidationFailed& failCallback);
+
+  void
+  onDataValidationFailed(const shared_ptr<const Data>& data,
+                         const std::string& failureInfo);
+
+private:
+
+  Name m_userPrefix;
+  ndn::Face& m_face;
+
+  Logic m_logic;
+
+  ndn::KeyChain m_keyChain;
+};
+
+} // namespace chronosync
+
+#endif // CHRONOSYNC_SOCKET_HPP
diff --git a/src/sync-socket.cc b/src/sync-socket.cc
deleted file mode 100644
index b344a3e..0000000
--- a/src/sync-socket.cc
+++ /dev/null
@@ -1,245 +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>
- * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
- * @author Chaoyi Bian <bcy@pku.edu.cn>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "sync-socket.h"
-#include "sync-logging.h"
-
-using namespace ndn;
-
-INIT_LOGGER ("SyncSocket")
-
-namespace Sync {
-
-using ndn::shared_ptr;
-
-static const uint8_t ROUTING_PREFIX_SEPARATOR[2] = {0xF0, 0x2E};
-
-const Name SyncSocket::EMPTY_NAME = Name();
-
-SyncSocket::SyncSocket (const Name& syncPrefix,
-                        const Name& dataPrefix,
-                        uint64_t dataSession,
-                        bool withRoutingPrefix,
-                        const Name& routingPrefix,
-                        shared_ptr<Face> face,
-                        const IdentityCertificate& myCertificate,
-                        shared_ptr<SecRuleRelative> dataRule,
-                        NewDataCallback dataCallback,
-                        RemoveCallback rmCallback )
-  : m_dataPrefix(dataPrefix)
-  , m_dataSession(dataSession)
-  , m_withRoutingPrefix(false)
-  , m_newDataCallback(dataCallback)
-  , m_myCertificate(myCertificate)
-  , m_face(face)
-  , m_ioService(face->getIoService())
-{
-  if(withRoutingPrefix && !routingPrefix.isPrefixOf(m_dataPrefix))
-    {
-      m_withRoutingPrefix = true;
-      m_routableDataPrefix.append(routingPrefix).append(ROUTING_PREFIX_SEPARATOR, 2).append(m_dataPrefix);
-    }
-
-
-  if(static_cast<bool>(dataRule))
-    {
-      m_withSecurity = true;
-      m_syncValidator = shared_ptr<Validator>(new SyncValidator(syncPrefix,
-                                                                m_myCertificate,
-                                                                *m_face,
-                                                                bind(&SyncSocket::publishData, this, _1, _2, _3, true),
-                                                                dataRule));
-    }
-  else
-    {
-      m_withSecurity = false;
-      m_syncValidator = shared_ptr<Validator>(new ValidatorNull());
-    }
-
-
-  m_syncLogic = shared_ptr<SyncLogic>(new SyncLogic(syncPrefix,
-                                                    myCertificate,
-                                                    m_syncValidator,
-                                                    m_face,
-                                                    bind(&SyncSocket::passCallback, this, _1),
-                                                    rmCallback));
-}
-
-SyncSocket::~SyncSocket()
-{
-}
-
-void
-SyncSocket::publishData(const uint8_t* buf, size_t len, int freshness, bool isCert)
-{
-  shared_ptr<Data> data = make_shared<Data>();
-  data->setContent(reinterpret_cast<const uint8_t*>(buf), len);
-  data->setFreshnessPeriod(time::milliseconds(1000*freshness));
-
-  m_ioService.post(bind(&SyncSocket::publishDataInternal, this,
-                        data, isCert));
-}
-
-void
-SyncSocket::publishDataInternal(shared_ptr<Data> data, bool isCert)
-{
-  Name dataPrefix = (m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
-
-  uint64_t sequence = getNextSeq();
-
-  Name dataName;
-  dataName.append(m_dataPrefix)
-    .append(boost::lexical_cast<std::string>(m_dataSession))
-    .append(boost::lexical_cast<std::string>(sequence));
-  if(isCert)
-    dataName.append("INTRO-CERT");
-  data->setName(dataName);
-  m_keyChain.sign(*data, m_myCertificate.getName());
-
-  if(m_withRoutingPrefix)
-    {
-      Name wrappedName;
-      wrappedName.append(m_routableDataPrefix)
-        .append(boost::lexical_cast<std::string>(m_dataSession))
-        .append(boost::lexical_cast<std::string>(sequence));
-
-      Data wrappedData(wrappedName);
-      wrappedData.setContent(data->wireEncode());
-      m_keyChain.sign(wrappedData, m_myCertificate.getName());
-
-      m_face->put(wrappedData);
-    }
-  else
-    {
-      m_face->put(*data);
-    }
-
-  SeqNo s(m_dataSession, sequence + 1);
-  m_sequenceLog[dataPrefix] = s;
-  m_syncLogic->addLocalNames (dataPrefix, m_dataSession, sequence); // If DNS works, we should use pure m_dataprefix rather than the one with routing prefix.
-}
-
-void
-SyncSocket::fetchData(const Name& prefix, const SeqNo& seq, const OnDataValidated& dataCallback, int retry)
-{
-  Name interestName = prefix;
-  interestName.append(boost::lexical_cast<std::string>(seq.getSession())).append(boost::lexical_cast<std::string>(seq.getSeq()));
-
-  ndn::Interest interest(interestName);
-  interest.setMustBeFresh(true);
-
-  m_face->expressInterest(interest,
-                          bind(&SyncSocket::onData, this, _1, _2, dataCallback),
-                          bind(&SyncSocket::onDataTimeout, this, _1, retry, dataCallback));
-
-}
-
-void
-SyncSocket::onData(const ndn::Interest& interest, Data& data, const OnDataValidated& dataCallback)
-{
-  bool encaped = false;
-
-  Name interestName = interest.getName();
-  Name::const_iterator it = interestName.begin();
-  Name::const_iterator end = interestName.end();
-
-  size_t offset = interestName.size();
-  for(; it != end; it++)
-    {
-      offset--;
-      if(it->toUri() == "%F0.")
-        {
-          encaped = true;
-          break;
-        }
-    }
-
-  if(!encaped)
-    offset = interestName.size();
-
-  const OnDataValidated& onValidated = bind(&SyncSocket::onDataValidated, this, _1, offset, dataCallback);
-  const OnDataValidationFailed& onValidationFailed = bind(&SyncSocket::onDataValidationFailed, this, _1, _2);
-
-  if(encaped)
-    {
-      shared_ptr<Data> innerData = make_shared<Data>();
-      innerData->wireDecode(data.getContent().blockFromValue());
-      m_syncValidator->validate(*innerData, onValidated, onValidationFailed);
-    }
-  else
-    m_syncValidator->validate(data, onValidated, onValidationFailed);
-}
-
-void
-SyncSocket::onDataTimeout(const ndn::Interest& interest, int retry, const OnDataValidated& dataCallback)
-{
-  if(retry > 0)
-    {
-      m_face->expressInterest(interest,
-                              bind(&SyncSocket::onData,
-                                   this,
-                                   _1,
-                                   _2,
-                                   dataCallback),
-                              bind(&SyncSocket::onDataTimeout,
-                                   this,
-                                   _1,
-                                   retry - 1,
-                                   dataCallback));
-
-    }
-  else
-    _LOG_DEBUG("interest eventually time out!");
-}
-
-void
-SyncSocket::onDataValidated(const shared_ptr<const Data>& data,
-                            size_t interestNameSize,
-                            const OnDataValidated& onValidated)
-{
-  if(data->getName().size() > interestNameSize
-     && data->getName().get(interestNameSize).toUri() == "INTRO-CERT")
-    {
-      if(!m_withSecurity)
-        return;
-
-      Data rawData;
-      rawData.wireDecode(data->getContent().blockFromValue());
-      IntroCertificate introCert(rawData);
-      dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introCert);
-    }
-  else
-    {
-      onValidated(data);
-    }
-}
-
-void
-SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data,
-                                   const std::string& failureInfo)
-{
-  _LOG_DEBUG("data cannot be verified!: " << failureInfo);
-}
-
-}//Sync
diff --git a/src/sync-socket.h b/src/sync-socket.h
deleted file mode 100644
index 5e66ac6..0000000
--- a/src/sync-socket.h
+++ /dev/null
@@ -1,204 +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>
- * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
- * @author Chaoyi Bian <bcy@pku.edu.cn>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef _SYNC_SOCKET_H
-#define _SYNC_SOCKET_H
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/validator.hpp>
-#include <ndn-cxx/security/validator-null.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-
-#include "sync-logic.h"
-#include "sync-seq-no.h"
-#include "sync-validator.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:
-  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
-
-  typedef ndn::function< void (const std::vector<MissingDataInfo> &, SyncSocket * ) > NewDataCallback;
-  typedef ndn::function< void (const std::string &/*prefix*/ ) > RemoveCallback;
-
-  static const ndn::Name EMPTY_NAME;
-
-  SyncSocket(const ndn::Name& syncPrefix,
-             const ndn::Name& dataPrefix,
-             uint64_t dataSession,
-             bool withRoutingPrefix,
-             const ndn::Name& routingPrefix,
-             ndn::shared_ptr<ndn::Face> face,
-             const ndn::IdentityCertificate& myCertificate,
-             ndn::shared_ptr<ndn::SecRuleRelative> dataRule,
-             NewDataCallback dataCallback,
-             RemoveCallback rmCallback);
-
-  ~SyncSocket();
-
-  void
-  publishData(const uint8_t* buf, size_t len, int freshness, bool isCert = false);
-
-  void
-  leave()
-  {
-    m_syncLogic->remove(m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
-  }
-
-  void
-  remove(const ndn::Name& prefix)
-  {
-    m_syncLogic->remove(prefix);
-  }
-
-  void
-  fetchData(const ndn::Name &prefix, const SeqNo &seq, const ndn::OnDataValidated& onValidated, int retry = 0);
-
-  std::string
-  getRootDigest()
-  {
-    return m_syncLogic->getRootDigest();
-  }
-
-  uint64_t
-  getNextSeq()
-  {
-    // If DNS works, we should use pure m_dataprefix rather than the one with routing prefix.
-    SequenceLog::iterator i = m_sequenceLog.find (m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
-
-    if (i != m_sequenceLog.end ())
-      {
-        SeqNo s = i->second;
-        if (s.getSession() == m_dataSession)
-          return s.getSeq();
-      }
-    return 0;
-  }
-
-  SyncLogic &
-  getLogic()
-  {
-    return *m_syncLogic;
-  }
-
-  void
-  addParticipant(const ndn::IdentityCertificate& introducee)
-  {
-    if(m_withSecurity)
-      {
-        ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introducee);
-      }
-  }
-
-  void
-  addParticipant(const IntroCertificate& introCert)
-  {
-    if(m_withSecurity)
-      {
-        ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introCert);
-      }
-  }
-
-  void
-  getIntroCertNames(std::vector<ndn::Name>& list)
-  {
-    if(m_withSecurity)
-      {
-        ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->getIntroCertNames(list);
-      }
-  }
-
-  const IntroCertificate&
-  getIntroCertificate(const ndn::Name& name)
-  {
-    if(m_withSecurity)
-      {
-        return ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->getIntroCertificate(name);
-      }
-    throw Error("You are running SyncSocket without security!");
-  }
-
-  // // 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
-  publishDataInternal(ndn::shared_ptr<ndn::Data> data, bool isCert);
-
-  void
-  passCallback(const std::vector<MissingDataInfo> &v)
-  {
-    m_newDataCallback(v, this);
-  }
-
-  void
-  onData(const ndn::Interest& interest, ndn::Data& data, const ndn::OnDataValidated& dataCallback);
-
-  void
-  onDataTimeout(const ndn::Interest& interest, int retry, const ndn::OnDataValidated& dataCallback);
-
-
-  void
-  onDataValidated(const ndn::shared_ptr<const ndn::Data>& data,
-                  size_t interestNameSize,
-                  const ndn::OnDataValidated& onValidated);
-
-  void
-  onDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
-                         const std::string& failureInfo);
-
-private:
-  typedef std::map<ndn::Name, SeqNo> SequenceLog;
-
-  ndn::Name m_dataPrefix;
-  uint64_t m_dataSession;
-  ndn::Name m_routableDataPrefix;
-  bool m_withRoutingPrefix;
-  NewDataCallback m_newDataCallback;
-  SequenceLog m_sequenceLog;
-  ndn::IdentityCertificate m_myCertificate;
-  ndn::KeyChain m_keyChain;
-  ndn::shared_ptr<ndn::Face> m_face;
-  boost::asio::io_service& m_ioService;
-  bool m_withSecurity;
-  ndn::shared_ptr<ndn::Validator> m_syncValidator;
-  ndn::shared_ptr<SyncLogic>      m_syncLogic;
-};
-
-} // Sync
-
-#endif // SYNC_SOCKET_H
diff --git a/tests/integrated-tests/test-data-fetch-and-publish.cpp.outdated b/tests/integrated-tests/test-data-fetch-and-publish.cpp.outdated
deleted file mode 100644
index 583717c..0000000
--- a/tests/integrated-tests/test-data-fetch-and-publish.cpp.outdated
+++ /dev/null
@@ -1,108 +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 <boost/test/output_test_stream.hpp>
-#include <map>
-using boost::test_tools::output_test_stream;
-
-#include <boost/make_shared.hpp>
-
-#include "sync-ccnx-wrapper.h"
-#include "sync-app-data-fetch.h"
-#include "sync-app-data-publish.h"
-
-using namespace Sync;
-using namespace std;
-using namespace boost;
-
-class TestStructApp {
-public:
-  map<string, string> data;
-  void set(string str1, string str2) {
-    data.insert(make_pair(str1, str2));
-  }
-
-  void erase(string str1, string str2) {
-    data.erase(str1);
-  }
-
-  string toString(){
-    map<string, string>::iterator it = data.begin();
-    string str = "";
-    for (; it != data.end(); ++it){
-      str += "<";
-      str += it->first;
-      str += "|";
-      str += it->second;
-      str += ">";
-    }
-    return str;
-  }
-
-};
-
-BOOST_AUTO_TEST_CASE (AppDataPublishAndFetchTest)
-{
-  TestStructApp foo;
-  TestStructApp bar;
-
-  string interest = "/april/fool";
-  string seq[5] = {"0", "1", "2", "3", "4" };
-  string str[5] = {"panda", "express", "tastes", "so", "good"};
-
-  for (int i = 0; i < 5; i++) {
-    foo.set(interest + "/" + "0/" + seq[i], str[i]);
-  }
-
-  boost::function<void (string, string)> setFunc =
-    bind(&TestStructApp::set, &bar, _1, _2);
-
-  shared_ptr<CcnxWrapper> handle(new CcnxWrapper());
-
-  AppDataFetch fetcher(handle, setFunc);
-  AppDataPublish publisher(handle);
-
-  for (int i = 1; i <= 5; i++) {
-    publisher.publishData(interest, 0, str[i - 1], 5);
-  }
-
-  BOOST_CHECK_EQUAL(publisher.getNextSeq(interest, 0), 5);
-  BOOST_CHECK_EQUAL(publisher.getRecentData(interest, 0), str[4]);
-
-  fetcher.onUpdate (interest, SeqNo (0,4), SeqNo (0,-1));
-  // give time for ccnd to react
-  sleep(1);
-  BOOST_CHECK_EQUAL(foo.toString(), bar.toString());
-
-
-  boost::function<void (string, string)> eraseFunc =
-    bind(&TestStructApp::erase, &bar, _1, _2);
-  fetcher.setDataCallback(eraseFunc);
-
-  fetcher.onUpdate (interest, SeqNo (0,4), SeqNo (0,-1));
-  // give time for ccnd to react
-  sleep(1);
-  TestStructApp poo;
-
-  BOOST_CHECK_EQUAL(poo.toString(), bar.toString());
-
-}
-*/
diff --git a/tests/integrated-tests/test-socket.cpp b/tests/integrated-tests/test-socket.cpp
new file mode 100644
index 0000000..4b81554
--- /dev/null
+++ b/tests/integrated-tests/test-socket.cpp
@@ -0,0 +1,331 @@
+/* -*- 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 "socket.hpp"
+
+#include "boost-test.hpp"
+
+namespace chronosync {
+namespace test {
+
+using std::string;
+using std::vector;
+using std::map;
+
+/**
+ * @brief Emulate an app that use the Socket class
+ *
+ * The app has two types of data set: one is simply string while the other is integer array.
+ * For each type of data set, the app has a specific fetching strategy.
+ */
+class SocketTestApp : noncopyable
+{
+public:
+  SocketTestApp(const Name& syncPrefix,
+                const Name& userPrefix,
+                ndn::Face& face,
+                bool isNum)
+    : sum(0)
+    , socket(syncPrefix,
+             userPrefix,
+             face,
+             isNum ? bind(&SocketTestApp::fetchNumbers, this, _1) :
+                     bind(&SocketTestApp::fetchAll, this, _1))
+  {
+  }
+
+  void
+  set(const shared_ptr<const Data>& dataPacket)
+  {
+    // std::cerr << "set Data" << std::endl;
+    Name dataName(dataPacket->getName());
+    string str2(reinterpret_cast<const char*>(dataPacket->getContent().value()),
+                dataPacket->getContent().value_size());
+    data.insert(make_pair(dataName, str2));
+  }
+
+  void
+  set(Name name, const char* buf, int len)
+  {
+    string str2(buf, len);
+    data.insert(make_pair(name, str2));
+  }
+
+  void
+  setNum(const shared_ptr<const Data>& dataPacket)
+  {
+    // std::cerr << "setNum Data" << std::endl;
+    size_t n = dataPacket->getContent().value_size() / 4;
+    const uint32_t* numbers = reinterpret_cast<const uint32_t*>(dataPacket->getContent().value());
+    for (size_t i = 0; i < n; i++) {
+      sum += numbers[i];
+    }
+  }
+
+  void
+  setNum(Name name, const uint8_t* buf, int len)
+  {
+    BOOST_ASSERT(len >= 4);
+
+    int n = len / 4;
+    const uint32_t* numbers = reinterpret_cast<const uint32_t*>(buf);
+    for (int i = 0; i < n; i++) {
+      sum += numbers[i];
+    }
+  }
+
+  void
+  fetchAll(const vector<MissingDataInfo>& v)
+  {
+    // std::cerr << "fetchAll" << std::endl;
+    for (int i = 0; i < v.size(); i++) {
+      for(SeqNo s = v[i].low; s <= v[i].high; ++s) {
+        socket.fetchData(v[i].session, s,
+                         bind(&SocketTestApp::set, this, _1));
+      }
+    }
+  }
+
+  void
+  fetchNumbers(const vector<MissingDataInfo> &v)
+  {
+    // std::cerr << "fetchNumbers" << std::endl;
+    for (int i = 0; i < v.size(); i++) {
+      for(SeqNo s = v[i].low; s <= v[i].high; ++s) {
+        socket.fetchData(v[i].session, s,
+                         bind(&SocketTestApp::setNum, this, _1));
+      }
+    }
+  }
+
+  string
+  toString()
+  {
+    string str = "\n";
+    for (map<Name, string>::iterator it = data.begin(); it != data.end(); ++it) {
+      str += "<";
+      str += it->first.toUri();
+      str += "|";
+      str += it->second;
+      str += ">";
+      str += "\n";
+    }
+
+    return str;
+  }
+
+  map<ndn::Name, string> data;
+  uint32_t sum;
+  Socket socket;
+};
+
+class SocketFixture
+{
+public:
+  SocketFixture()
+    : syncPrefix("/ndn/broadcast/sync")
+    , scheduler(io)
+  {
+    syncPrefix.appendVersion();
+    userPrefix[0] = Name("/user0");
+    userPrefix[1] = Name("/user1");
+    userPrefix[2] = Name("/user2");
+
+    faces[0] = make_shared<ndn::Face>(ref(io));
+    faces[1] = make_shared<ndn::Face>(ref(io));
+    faces[2] = make_shared<ndn::Face>(ref(io));
+  }
+
+  void
+  createSocket(size_t idx, bool isNum)
+  {
+    app[idx] = make_shared<SocketTestApp>(syncPrefix, userPrefix[idx], ref(*faces[idx]), isNum);
+    sessionName[idx] = app[idx]->socket.getLogic().getSessionName();
+  }
+
+  void
+  publishAppData(size_t idx, const string& data)
+  {
+    app[idx]->socket.publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
+                                 ndn::time::milliseconds(1000));
+  }
+
+  void
+  setAppData(size_t idx, SeqNo seqNo, const string& data)
+  {
+    Name dataName = sessionName[idx];
+    dataName.appendNumber(seqNo);
+    app[idx]->set(dataName, data.c_str(), data.size());
+  }
+
+  void
+  publishAppNum(size_t idx, const uint8_t* buf, size_t size)
+  {
+    app[idx]->socket.publishData(buf, size, ndn::time::milliseconds(1000));
+  }
+
+  void
+  setAppNum(size_t idx, SeqNo seqNo, const uint8_t* buf, size_t size)
+  {
+    Name dataName = sessionName[idx];
+    dataName.appendNumber(seqNo);
+    app[idx]->setNum(dataName, buf, size);
+  }
+
+  void
+  check(int round)
+  {
+    BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
+    BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
+  }
+
+  void
+  check2Num(int num)
+  {
+    BOOST_CHECK_EQUAL(app[0]->sum, app[1]->sum);
+    BOOST_CHECK_EQUAL(app[1]->sum, num);
+  }
+
+  void
+  terminate()
+  {
+    io.stop();
+  }
+
+  Name syncPrefix;
+  Name userPrefix[3];
+  Name sessionName[3];
+
+  boost::asio::io_service io;
+  shared_ptr<ndn::Face> faces[3];
+  ndn::Scheduler scheduler;
+  shared_ptr<SocketTestApp> app[3];
+};
+
+
+
+BOOST_FIXTURE_TEST_SUITE(SocketTests, SocketFixture)
+
+BOOST_AUTO_TEST_CASE(BasicData)
+{
+  scheduler.scheduleEvent(ndn::time::milliseconds(0),
+                          bind(&SocketFixture::createSocket, this, 0, false));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(50),
+                          bind(&SocketFixture::createSocket, this, 1, false));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(100),
+                          bind(&SocketFixture::createSocket, this, 2, false));
+
+  string data0 = "Very funny Scotty, now beam down my clothes";
+  scheduler.scheduleEvent(ndn::time::milliseconds(150),
+                          bind(&SocketFixture::publishAppData, this, 0, data0));
+  scheduler.scheduleEvent(ndn::time::milliseconds(1150),
+                          bind(&SocketFixture::setAppData, this, 0, 1, data0));
+  scheduler.scheduleEvent(ndn::time::milliseconds(1160),
+                          bind(&SocketFixture::check, this, 1));
+
+  string data1 = "Yes, give me that ketchup";
+  string data2 = "Don't look conspicuous, it draws fire";
+  scheduler.scheduleEvent(ndn::time::milliseconds(1170),
+                          bind(&SocketFixture::publishAppData, this, 0, data1));
+  scheduler.scheduleEvent(ndn::time::milliseconds(1180),
+                          bind(&SocketFixture::publishAppData, this, 0, data2));
+  scheduler.scheduleEvent(ndn::time::milliseconds(2150),
+                          bind(&SocketFixture::setAppData, this, 0, 2, data1));
+  scheduler.scheduleEvent(ndn::time::milliseconds(2160),
+                          bind(&SocketFixture::setAppData, this, 0, 3, data2));
+  scheduler.scheduleEvent(ndn::time::milliseconds(2170),
+                          bind(&SocketFixture::check, this, 2));
+
+  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";
+  scheduler.scheduleEvent(ndn::time::milliseconds(3180),
+                          bind(&SocketFixture::publishAppData, this, 2, data3));
+  scheduler.scheduleEvent(ndn::time::milliseconds(3200),
+                          bind(&SocketFixture::publishAppData, this, 1, data4));
+  scheduler.scheduleEvent(ndn::time::milliseconds(3210),
+                          bind(&SocketFixture::publishAppData, this, 1, data5));
+  scheduler.scheduleEvent(ndn::time::milliseconds(4710),
+                          bind(&SocketFixture::setAppData, this, 2, 1, data3));
+  scheduler.scheduleEvent(ndn::time::milliseconds(4720),
+                          bind(&SocketFixture::setAppData, this, 1, 1, data4));
+  scheduler.scheduleEvent(ndn::time::milliseconds(4730),
+                          bind(&SocketFixture::setAppData, this, 1, 2, data5));
+  scheduler.scheduleEvent(ndn::time::milliseconds(4800),
+                          bind(&SocketFixture::check, this, 3));
+
+  // not sure weither this is simultanous data generation from multiple sources
+  string data6 = "Shakespeare says: 'Prose before hos.'";
+  string data7 = "Pick good people, talent never wears out";
+  scheduler.scheduleEvent(ndn::time::milliseconds(5500),
+                          bind(&SocketFixture::publishAppData, this, 0, data6));
+  scheduler.scheduleEvent(ndn::time::milliseconds(5500),
+                          bind(&SocketFixture::publishAppData, this, 1, data7));
+  scheduler.scheduleEvent(ndn::time::milliseconds(6800),
+                          bind(&SocketFixture::setAppData, this, 0, 4, data6));
+  scheduler.scheduleEvent(ndn::time::milliseconds(6800),
+                          bind(&SocketFixture::setAppData, this, 1, 3, data7));
+  scheduler.scheduleEvent(ndn::time::milliseconds(6900),
+                          bind(&SocketFixture::check, this, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(7000),
+                          bind(&SocketFixture::terminate, this));
+
+  io.run();
+}
+
+BOOST_AUTO_TEST_CASE(BasicNumber)
+{
+  scheduler.scheduleEvent(ndn::time::milliseconds(0),
+                          bind(&SocketFixture::createSocket, this, 0, true));
+  scheduler.scheduleEvent(ndn::time::milliseconds(50),
+                          bind(&SocketFixture::createSocket, this, 1, true));
+
+  uint32_t num1[5] = {0, 1, 2, 3, 4};
+  uint8_t* buf1 = reinterpret_cast<uint8_t*>(num1);
+  size_t size1 = sizeof(num1);
+  scheduler.scheduleEvent(ndn::time::milliseconds(100),
+                          bind(&SocketFixture::publishAppNum, this, 0, buf1, size1));
+  scheduler.scheduleEvent(ndn::time::milliseconds(150),
+                          bind(&SocketFixture::setAppNum, this, 0, 0, buf1, size1));
+  scheduler.scheduleEvent(ndn::time::milliseconds(1000),
+                          bind(&SocketFixture::check2Num, this, 10));
+
+  uint32_t num2[5] = {9, 7, 2, 1, 1};
+  uint8_t* buf2 = reinterpret_cast<uint8_t*>(num2);
+  size_t size2 = sizeof(num2);
+  scheduler.scheduleEvent(ndn::time::milliseconds(1100),
+                          bind(&SocketFixture::publishAppNum, this, 1, buf2, size2));
+  scheduler.scheduleEvent(ndn::time::milliseconds(1150),
+                          bind(&SocketFixture::setAppNum, this, 1, 0, buf2, size2));
+  scheduler.scheduleEvent(ndn::time::milliseconds(2000),
+                          bind(&SocketFixture::check2Num, this, 30));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(7000),
+                          bind(&SocketFixture::terminate, this));
+
+  io.run();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace chronosync
diff --git a/tests/integrated-tests/test-socket.cpp.outdated b/tests/integrated-tests/test-socket.cpp.outdated
deleted file mode 100644
index d04ded9..0000000
--- a/tests/integrated-tests/test-socket.cpp.outdated
+++ /dev/null
@@ -1,619 +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 <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 "sync-socket.h"
-#include "sync-validator.h"
-#include <ndn-cxx/security/validator-null.hpp>
-
-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:
-  TestSocketApp()
-    : sum(0)
-  {}
-
-  map<ndn::Name, string> data;
-  void set(const ndn::shared_ptr<const ndn::Data>& dataPacket) {
-    // _LOG_FUNCTION (this << ", " << str1);
-    ndn::Name dataName(dataPacket->getName());
-    string str2(reinterpret_cast<const char*>(dataPacket->getContent().value()), dataPacket->getContent().value_size());
-    data.insert(make_pair(dataName, str2));
-    // cout << str1 << ", " << str2 << endl;
-  }
-
-  void set(ndn::Name name, const char * buf, int len) {
-    string str2(buf, len);
-    data.insert(make_pair(name, str2));
-  }
-
-  void setNum(const ndn::shared_ptr<const ndn::Data>& data) {
-    int n = data->getContent().value_size() / 4;
-    uint32_t *numbers = new uint32_t [n];
-    memcpy(numbers, data->getContent().value(), data->getContent().value_size());
-    for (int i = 0; i < n; i++) {
-      sum += numbers[i];
-    }
-    delete numbers;
-
-  }
-
-  void setNum(ndn::Name name, 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;
-  }
-
-  uint32_t 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<ndn::Name, string>::iterator it = data.begin();
-    string str = "\n";
-    for (; it != data.end(); ++it){
-      str += "<";
-      str += it->first.toUri();
-      str += "|";
-      str += it->second;
-      str += ">";
-      str += "\n";
-    }
-
-    return str;
-  }
-
-};
-
-class TestSet1{
-public:
-  TestSet1(ndn::shared_ptr<boost::asio::io_service> ioService)
-    : m_face1(new ndn::Face(*ioService))
-    , m_face2(new ndn::Face(*ioService))
-    , m_face3(new ndn::Face(*ioService))
-    , m_name1("/irl.cs.ucla.edu/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-    , m_name2("/yakshi.org/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-    , m_name3("/google.com/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-  {
-    m_id1 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name1));
-    m_id2 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name2));
-    m_id3 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name3));
-
-    m_rule = ndn::make_shared<ndn::SecRuleRelative>("^(<>*)<><>$",
-                                                    "^(<>*)<><KEY><ksk-.*><ID-CERT>$",
-                                                    "==", "\\1", "\\1", true);
-  }
-
-  void
-  createSyncSocket1()
-  {
-    _LOG_DEBUG ("s1");
-
-    m_s1 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/let/us/sync",
-                      "/irl.cs.ucla.edu",
-                      0,
-                      false,
-                      "/",
-                      m_face1,
-                      *m_id1,
-                      m_rule,
-                      bind(&TestSocketApp::fetchAll, &m_a1, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a1, _1)));
-
-    m_s1->addParticipant(*m_id2);
-  }
-
-  void
-  createSyncSocket2()
-  {
-    _LOG_DEBUG ("s2");
-
-    m_s2 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/let/us/sync",
-                      "/yakshi.org",
-                      0,
-                      false,
-                      "/",
-                      m_face2,
-                      *m_id2,
-                      m_rule,
-                      bind(&TestSocketApp::fetchAll, &m_a2, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a2, _1)));
-
-    m_s2->addParticipant(*m_id1);
-    m_s2->addParticipant(*m_id3);
-  }
-
-  void
-  createSyncSocket3()
-  {
-    _LOG_DEBUG ("s3");
-
-    m_s3 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/let/us/sync",
-                      "/google.com",
-                      0,
-                      false,
-                      "/",
-                      m_face3,
-                      *m_id3,
-                      m_rule,
-                      bind(&TestSocketApp::fetchAll, &m_a3, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a3, _1)));
-
-    m_s3->addParticipant(*m_id2);
-  }
-
-  void
-  publishSocket1(string data)
-  {
-    _LOG_DEBUG ("s1 publish");
-    m_s1->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  publishSocket2(string data)
-  {
-    _LOG_DEBUG ("s2 publish");
-    m_s2->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  publishSocket3(string data)
-  {
-    _LOG_DEBUG ("s3 publish");
-    m_s3->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  setSocket1(string suffix, string data)
-  {
-    _LOG_DEBUG ("a1 set");
-    ndn::Name name("/irl.cs.ucla.edu");
-    name.append(suffix);
-    m_a1.set (name, data.c_str(), data.size());
-  }
-
-  void
-  setSocket2(string suffix, string data)
-  {
-    _LOG_DEBUG ("a2 set");
-    ndn::Name name("/yakshi.org");
-    name.append(suffix);
-    m_a2.set (name, data.c_str(), data.size());
-  }
-
-  void
-  setSocket3(string suffix, string data)
-  {
-    _LOG_DEBUG ("a3 set");
-    ndn::Name name("/google.com");
-    name.append(suffix);
-    m_a3.set (name, data.c_str(), data.size());
-  }
-
-  void
-  check(int round)
-  {
-    BOOST_CHECK_EQUAL(m_a1.toString(), m_a2.toString());
-    BOOST_CHECK_EQUAL(m_a2.toString(), m_a3.toString());
-  }
-
-  void
-  done(ndn::shared_ptr<boost::asio::io_service> ioService)
-  {
-    m_s1.reset();
-    m_s2.reset();
-    m_s3.reset();
-
-    m_keyChain.deleteIdentity(m_name1);
-    m_keyChain.deleteIdentity(m_name2);
-    m_keyChain.deleteIdentity(m_name3);
-
-    ioService->stop();
-  }
-
-  ndn::KeyChain m_keyChain;
-  ndn::shared_ptr<ndn::SecRuleRelative> m_rule;
-
-  ndn::shared_ptr<ndn::Face> m_face1, m_face2, m_face3;
-  ndn::Name m_name1, m_name2, m_name3;
-  TestSocketApp m_a1, m_a2, m_a3;
-  ndn::shared_ptr<ndn::IdentityCertificate> m_id1, m_id2, m_id3;
-  ndn::shared_ptr<SyncSocket> m_s1, m_s2, m_s3;
-};
-
-class TestSet2{
-public:
-  TestSet2(ndn::shared_ptr<boost::asio::io_service> ioService)
-    : m_face1(new ndn::Face(*ioService))
-    , m_face2(new ndn::Face(*ioService))
-    , m_name1("/xiaonei.com/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-    , m_name2("/mitbbs.com/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-  {
-    m_id1 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name1));
-    m_id2 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name2));
-
-    m_rule = ndn::make_shared<ndn::SecRuleRelative>("^(<>*)<><>$",
-                                                    "^(<>*)<><KEY><ksk-.*><ID-CERT>$",
-                                                    "==", "\\1", "\\1", true);
-  }
-
-  void
-  createSyncSocket1()
-  {
-    _LOG_DEBUG ("s1");
-
-    m_s1 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/this/is/the/prefix",
-                      "/xiaonei.com",
-                      0,
-                      false,
-                      "/",
-                      m_face1,
-                      *m_id1,
-                      m_rule,
-                      bind(&TestSocketApp::fetchNumbers, &m_a1, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a1, _1)));
-
-    m_s1->addParticipant(*m_id2);
-  }
-
-  void
-  createSyncSocket2()
-  {
-    _LOG_DEBUG ("s2");
-
-    m_s2 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/this/is/the/prefix",
-                      "/mitbbs.com",
-                      0,
-                      false,
-                      "/",
-                      m_face2,
-                      *m_id2,
-                      m_rule,
-                      bind(&TestSocketApp::fetchNumbers, &m_a2, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a2, _1)));
-
-    m_s2->addParticipant(*m_id1);
-  }
-
-  void
-  publishSocket1(string data)
-  {
-    _LOG_DEBUG ("s1 publish");
-    m_s1->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  publishSocket2(string data)
-  {
-    _LOG_DEBUG ("s2 publish");
-    m_s2->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  setSocket1(const char* ptr, size_t size)
-  {
-    _LOG_DEBUG ("a1 setNum");
-    m_a1.setNum ("/xiaonei.com", ptr, size);
-  }
-
-  void
-  setSocket2(const char* ptr, size_t size)
-  {
-    _LOG_DEBUG ("a2 setNum");
-    m_a2.setNum ("/mitbbs.com", ptr, size);
-  }
-
-  void
-  check(int num)
-  {
-    _LOG_DEBUG ("codnum " << num);
-    _LOG_DEBUG ("a1 sum " << m_a1.sum);
-    _LOG_DEBUG ("a2 sum " << m_a2.sum);
-
-    BOOST_CHECK(m_a1.sum == m_a2.sum && m_a1.sum == num);
-  }
-
-  void
-  done(ndn::shared_ptr<boost::asio::io_service> ioService)
-  {
-    m_s1.reset();
-    m_s2.reset();
-
-    m_keyChain.deleteIdentity(m_name1);
-    m_keyChain.deleteIdentity(m_name2);
-
-    ioService->stop();
-  }
-
-  ndn::KeyChain m_keyChain;
-  ndn::shared_ptr<ndn::SecRuleRelative> m_rule;
-
-  TestSocketApp m_a1, m_a2;
-  ndn::shared_ptr<ndn::IdentityCertificate> m_id1, m_id2;
-  ndn::shared_ptr<ndn::Face> m_face1, m_face2;
-  ndn::Name m_name1, m_name2;
-  ndn::shared_ptr<SyncSocket> m_s1, m_s2;
-};
-
-
-
-class TestSet3{
-public:
-  TestSet3(ndn::shared_ptr<boost::asio::io_service> ioService)
-    : m_face1(new ndn::Face(*ioService))
-    , m_face2(new ndn::Face(*ioService))
-    , m_name1("/xiaonei.com/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-    , m_name2("/mitbbs.com/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()))
-  {
-    m_id1 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name1));
-    m_id2 = m_keyChain.getCertificate(m_keyChain.createIdentity(m_name2));
-
-    m_rule = ndn::make_shared<ndn::SecRuleRelative>("^(<>*)<><>$",
-                                                    "^(<>*)<><KEY><ksk-.*><ID-CERT>$",
-                                                    "==", "\\1", "\\1", true);
-  }
-
-  void
-  createSyncSocket1()
-  {
-    _LOG_DEBUG ("s1");
-
-    m_s1 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/this/is/the/prefix",
-                      "/xiaonei.com",
-                      1,
-                      true,
-                      "/abc",
-                      m_face1,
-                      *m_id1,
-                      m_rule,
-                      bind(&TestSocketApp::fetchNumbers, &m_a1, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a1, _1)));
-
-    m_s1->addParticipant(*m_id2);
-  }
-
-  void
-  createSyncSocket2()
-  {
-    _LOG_DEBUG ("s2");
-
-    m_s2 = ndn::shared_ptr<SyncSocket>
-      (new SyncSocket("/this/is/the/prefix",
-                      "/mitbbs.com",
-                      1,
-                      false,
-                      "/",
-                      m_face2,
-                      *m_id2,
-                      m_rule,
-                      bind(&TestSocketApp::fetchNumbers, &m_a2, _1, _2),
-                      bind(&TestSocketApp::pass, &m_a2, _1)));
-
-    m_s2->addParticipant(*m_id1);
-  }
-
-  void
-  publishSocket1(string data)
-  {
-    _LOG_DEBUG ("s1 publish");
-    m_s1->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  publishSocket2(string data)
-  {
-    _LOG_DEBUG ("s2 publish");
-    m_s2->publishData (reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), 1000);
-  }
-
-  void
-  setSocket1(const char* ptr, size_t size)
-  {
-    _LOG_DEBUG ("a1 setNum");
-    m_a1.setNum ("/xiaonei.com", ptr, size);
-  }
-
-  void
-  setSocket2(const char* ptr, size_t size)
-  {
-    _LOG_DEBUG ("a2 setNum");
-    m_a2.setNum ("/mitbbs.com", ptr, size);
-  }
-
-  void
-  check(int num)
-  {
-    _LOG_DEBUG ("codnum " << num);
-    _LOG_DEBUG ("a1 sum " << m_a1.sum);
-    _LOG_DEBUG ("a2 sum " << m_a2.sum);
-
-    BOOST_CHECK(m_a1.sum == m_a2.sum && m_a1.sum == num);
-  }
-
-  void
-  done(ndn::shared_ptr<boost::asio::io_service> ioService)
-  {
-    m_s1.reset();
-    m_s2.reset();
-
-    m_keyChain.deleteIdentity(m_name1);
-    m_keyChain.deleteIdentity(m_name2);
-
-    ioService->stop();
-  }
-
-  ndn::KeyChain m_keyChain;
-  ndn::shared_ptr<ndn::SecRuleRelative> m_rule;
-
-  TestSocketApp m_a1, m_a2;
-  ndn::shared_ptr<ndn::IdentityCertificate> m_id1, m_id2;
-  ndn::shared_ptr<ndn::Face> m_face1, m_face2;
-  ndn::Name m_name1, m_name2;
-  ndn::shared_ptr<SyncSocket> m_s1, m_s2;
-};
-
-BOOST_AUTO_TEST_CASE (AppSocketTest1)
-{
-  INIT_LOGGERS ();
-
-  ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
-  ndn::Scheduler scheduler(*ioService);
-  TestSet1 testSet1(ioService);
-
-  scheduler.scheduleEvent(ndn::time::milliseconds(0), ndn::bind(&TestSet1::createSyncSocket1, &testSet1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(50), ndn::bind(&TestSet1::createSyncSocket2, &testSet1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(100), ndn::bind(&TestSet1::createSyncSocket3, &testSet1));
-  string data0 = "Very funny Scotty, now beam down my clothes";
-  scheduler.scheduleEvent(ndn::time::milliseconds(150), ndn::bind(&TestSet1::publishSocket1, &testSet1, data0));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1150), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/1", data0));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1160), ndn::bind(&TestSet1::check, &testSet1, 1));
-  string data1 = "Yes, give me that ketchup";
-  string data2 = "Don't look conspicuous, it draws fire";
-  scheduler.scheduleEvent(ndn::time::milliseconds(1170), ndn::bind(&TestSet1::publishSocket1, &testSet1, data1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1180), ndn::bind(&TestSet1::publishSocket1, &testSet1, data2));
-  scheduler.scheduleEvent(ndn::time::milliseconds(2150), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/2", data1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(2160), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/3", data2));
-  scheduler.scheduleEvent(ndn::time::milliseconds(2170), ndn::bind(&TestSet1::check, &testSet1, 2));
-  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";
-  scheduler.scheduleEvent(ndn::time::milliseconds(3180), ndn::bind(&TestSet1::publishSocket3, &testSet1, data3));
-  scheduler.scheduleEvent(ndn::time::milliseconds(3200), ndn::bind(&TestSet1::publishSocket2, &testSet1, data4));
-  scheduler.scheduleEvent(ndn::time::milliseconds(3210), ndn::bind(&TestSet1::publishSocket2, &testSet1, data5));
-  scheduler.scheduleEvent(ndn::time::milliseconds(4710), ndn::bind(&TestSet1::setSocket3, &testSet1, "/0/1", data3));
-  scheduler.scheduleEvent(ndn::time::milliseconds(4720), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/2", data4));
-  scheduler.scheduleEvent(ndn::time::milliseconds(4730), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/3", data5));
-  scheduler.scheduleEvent(ndn::time::milliseconds(4800), ndn::bind(&TestSet1::check, &testSet1, 3));
-  // 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";
-  scheduler.scheduleEvent(ndn::time::milliseconds(5500), ndn::bind(&TestSet1::publishSocket1, &testSet1, data6));
-  scheduler.scheduleEvent(ndn::time::milliseconds(5500), ndn::bind(&TestSet1::publishSocket2, &testSet1, data7));
-  scheduler.scheduleEvent(ndn::time::milliseconds(6800), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/4", data6));
-  scheduler.scheduleEvent(ndn::time::milliseconds(6800), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/4", data7));
-  scheduler.scheduleEvent(ndn::time::milliseconds(6900), ndn::bind(&TestSet1::check, &testSet1, 4));
-  scheduler.scheduleEvent(ndn::time::milliseconds(7000), ndn::bind(&TestSet1::done, &testSet1, ioService));
-
-  ioService->run();
-}
-
-BOOST_AUTO_TEST_CASE (AppSocketTest2)
-{
-  ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
-  ndn::Scheduler scheduler(*ioService);
-  TestSet2 testSet2(ioService);
-
-  scheduler.scheduleEvent(ndn::time::milliseconds(0), ndn::bind(&TestSet2::createSyncSocket1, &testSet2));
-  scheduler.scheduleEvent(ndn::time::milliseconds(50), ndn::bind(&TestSet2::createSyncSocket2, &testSet2));
-  uint32_t num[5] = {0, 1, 2, 3, 4};
-  string data0((const char *) num, sizeof(num));
-  scheduler.scheduleEvent(ndn::time::milliseconds(100), ndn::bind(&TestSet2::publishSocket1, &testSet2, data0));
-  scheduler.scheduleEvent(ndn::time::milliseconds(150), ndn::bind(&TestSet2::setSocket1, &testSet2, (const char *) num, sizeof (num)));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1000), ndn::bind(&TestSet2::check, &testSet2, 10));
-  uint32_t newNum[5] = {9, 7, 2, 1, 1};
-  string data1((const char *) newNum, sizeof(newNum));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1100), ndn::bind(&TestSet2::publishSocket2, &testSet2, data1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1150), ndn::bind(&TestSet2::setSocket2, &testSet2, (const char *) newNum, sizeof (newNum)));
-  scheduler.scheduleEvent(ndn::time::milliseconds(2000), ndn::bind(&TestSet2::check, &testSet2, 30));
-  scheduler.scheduleEvent(ndn::time::milliseconds(7000), ndn::bind(&TestSet2::done, &testSet2, ioService));
-
-  ioService->run();
-}
-
-BOOST_AUTO_TEST_CASE (AppSocketTest3)
-{
-  ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
-  ndn::Scheduler scheduler(*ioService);
-  TestSet3 testSet3(ioService);
-
-  scheduler.scheduleEvent(ndn::time::milliseconds(0), ndn::bind(&TestSet3::createSyncSocket1, &testSet3));
-  scheduler.scheduleEvent(ndn::time::milliseconds(200), ndn::bind(&TestSet3::createSyncSocket2, &testSet3));
-  uint32_t num[5] = {0, 1, 2, 3, 4};
-  string data0((const char *) num, sizeof(num));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1000), ndn::bind(&TestSet3::publishSocket1, &testSet3, data0));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1500), ndn::bind(&TestSet3::setSocket1, &testSet3, (const char *) num, sizeof (num)));
-  scheduler.scheduleEvent(ndn::time::milliseconds(2000), ndn::bind(&TestSet3::check, &testSet3, 10));
-  uint32_t newNum[5] = {9, 7, 2, 1, 1};
-  string data1((const char *) newNum, sizeof(newNum));
-  scheduler.scheduleEvent(ndn::time::milliseconds(3000), ndn::bind(&TestSet3::publishSocket2, &testSet3, data1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(3500), ndn::bind(&TestSet3::setSocket2, &testSet3, (const char *) newNum, sizeof (newNum)));
-  scheduler.scheduleEvent(ndn::time::milliseconds(5000), ndn::bind(&TestSet3::check, &testSet3, 30));
-  scheduler.scheduleEvent(ndn::time::milliseconds(7000), ndn::bind(&TestSet3::done, &testSet3, ioService));
-
-  ioService->run();
-}
