diff --git a/src/sync-intro-certificate.h b/obsolete/sync-intro-certificate.h
similarity index 100%
rename from src/sync-intro-certificate.h
rename to obsolete/sync-intro-certificate.h
diff --git a/src/sync-validator.cc b/obsolete/sync-validator.cc
similarity index 100%
rename from src/sync-validator.cc
rename to obsolete/sync-validator.cc
diff --git a/src/sync-validator.h b/obsolete/sync-validator.h
similarity index 100%
rename from src/sync-validator.h
rename to obsolete/sync-validator.h
diff --git a/tests/unit-tests/test-sync-validator.cpp.outdated b/obsolete/tests/test-sync-validator.cpp.outdated
similarity index 100%
rename from tests/unit-tests/test-sync-validator.cpp.outdated
rename to obsolete/tests/test-sync-validator.cpp.outdated
diff --git a/src/logger.hpp b/src/logger.hpp
index 64a8563..c4eee03 100644
--- a/src/logger.hpp
+++ b/src/logger.hpp
@@ -64,7 +64,7 @@
 
 #define _LOG_DEBUG(x) \
   std::clog << boost::get_system_time() << " " << boost::this_thread::get_id() << \
-               " " << x << std::endl;
+               " " << x << std::endl
 
 #else // _DEBUG
 
diff --git a/src/logic.cpp b/src/logic.cpp
new file mode 100644
index 0000000..f584da5
--- /dev/null
+++ b/src/logic.cpp
@@ -0,0 +1,593 @@
+/* -*- 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 "logic.hpp"
+#include "logger.hpp"
+
+INIT_LOGGER("Logic");
+
+#ifdef _DEBUG
+#define _LOG_DEBUG_ID(v) _LOG_DEBUG("Instance" << m_instanceId << ": " << v)
+#else
+#define _LOG_DEBUG_ID(v) _LOG_DEBUG(v)
+#endif
+
+namespace chronosync {
+
+using ndn::ConstBufferPtr;
+using ndn::EventId;
+
+const uint8_t EMPTY_DIGEST_VALUE[] = {
+  0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+  0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+  0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+  0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
+};
+
+#ifdef _DEBUG
+int Logic::m_instanceCounter = 0;
+#endif
+
+const time::steady_clock::Duration Logic::DEFAULT_RESET_TIMER = time::seconds(0);
+const time::steady_clock::Duration Logic::DEFAULT_CANCEL_RESET_TIMER = time::milliseconds(500);
+const time::milliseconds Logic::DEFAULT_RESET_INTEREST_LIFETIME(1000);
+const time::milliseconds Logic::DEFAULT_SYNC_INTEREST_LIFETIME(1000);
+const time::milliseconds Logic::DEFAULT_SYNC_REPLY_FRESHNESS(1000);
+
+const ndn::ConstBufferPtr Logic::EMPTY_DIGEST(new ndn::Buffer(EMPTY_DIGEST_VALUE, 32));
+const ndn::name::Component Logic::RESET_COMPONENT("reset");
+
+Logic::Logic(ndn::Face& face,
+             const Name& syncPrefix,
+             const Name& userPrefix,
+             const UpdateCallback& onUpdate,
+             const time::steady_clock::Duration& resetTimer,
+             const time::steady_clock::Duration& cancelResetTimer,
+             const time::milliseconds& resetInterestLifetime,
+             const time::milliseconds& syncInterestLifetime,
+             const time::milliseconds& syncReplyFreshness)
+  : m_face(face)
+  , m_syncPrefix(syncPrefix)
+  , m_userPrefix(userPrefix)
+  , m_interestTable(m_face.getIoService())
+  , m_outstandingInterestId(0)
+  , m_isInReset(false)
+  , m_needPeriodReset(resetTimer > time::steady_clock::Duration::zero())
+  , m_onUpdate(onUpdate)
+  , m_scheduler(m_face.getIoService())
+  , m_randomGenerator(static_cast<unsigned int>(std::time(0)))
+  , m_rangeUniformRandom(m_randomGenerator, boost::uniform_int<>(100,500))
+  , m_reexpressionJitter(m_randomGenerator, boost::uniform_int<>(100,500))
+  , m_resetTimer(resetTimer)
+  , m_cancelResetTimer(cancelResetTimer)
+  , m_resetInterestLifetime(resetInterestLifetime)
+  , m_syncInterestLifetime(syncInterestLifetime)
+  , m_syncReplyFreshness(syncReplyFreshness)
+{
+#ifdef _DEBUG
+  m_instanceId = m_instanceCounter++;
+#endif
+
+  _LOG_DEBUG_ID(">> Logic::Logic");
+
+  m_syncReset = m_syncPrefix;
+  m_syncReset.append("reset");
+
+  _LOG_DEBUG_ID("Listen to: " << m_syncPrefix);
+  m_syncRegisteredPrefixId =
+    m_face.setInterestFilter(m_syncPrefix,
+                             bind(&Logic::onSyncInterest, this, _1, _2),
+                             bind(&Logic::onSyncRegisterFailed, this, _1, _2));
+
+  setUserPrefix(m_userPrefix);
+
+  _LOG_DEBUG_ID("<< Logic::Logic");
+}
+
+Logic::~Logic()
+{
+  m_face.unsetInterestFilter(m_syncRegisteredPrefixId);
+  m_scheduler.cancelAllEvents();
+}
+
+void
+Logic::reset()
+{
+  m_isInReset = true;
+
+  m_state.reset();
+  m_log.clear();
+
+  sendResetInterest();
+
+  // reset outstanding interest name, so that data for previous interest will be dropped.
+  if (m_outstandingInterestId != 0) {
+    m_face.removePendingInterest(m_outstandingInterestId);
+    m_outstandingInterestId = 0;
+  }
+
+  sendSyncInterest();
+
+  if (static_cast<bool>(m_delayedInterestProcessingId))
+    m_scheduler.cancelEvent(m_delayedInterestProcessingId);
+
+  m_delayedInterestProcessingId =
+    m_scheduler.scheduleEvent(m_cancelResetTimer,
+                              bind(&Logic::cancelReset, this));
+}
+
+void
+Logic::setUserPrefix(const Name& userPrefix)
+{
+  m_userPrefix = userPrefix;
+
+  m_sessionName = m_userPrefix;
+  m_sessionName.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
+
+  m_seqNo = 0;
+
+  reset();
+}
+
+void
+Logic::updateSeqNo(const SeqNo& seqNo)
+{
+  _LOG_DEBUG_ID(">> Logic::updateSeqNo");
+  _LOG_DEBUG_ID("seqNo: " << seqNo << " m_seqNo: " << m_seqNo);
+  if (seqNo < m_seqNo || seqNo == 0)
+    return;
+
+  m_seqNo = seqNo;
+
+  _LOG_DEBUG_ID("updateSeqNo: m_seqNo " << m_seqNo);
+
+  if (!m_isInReset) {
+    _LOG_DEBUG_ID("updateSeqNo: not in Reset ");
+    ndn::ConstBufferPtr previousRoot = m_state.getRootDigest();
+    {
+      using namespace CryptoPP;
+
+      std::string hash;
+      StringSource(previousRoot->buf(), previousRoot->size(), true,
+                   new HexEncoder(new StringSink(hash), false));
+      _LOG_DEBUG_ID("Hash: " << hash);
+    }
+
+    bool isInserted = false;
+    bool isUpdated = false;
+    SeqNo oldSeq;
+    boost::tie(isInserted, isUpdated, oldSeq) = m_state.update(m_sessionName, seqNo);
+
+    _LOG_DEBUG_ID("Insert: " << std::boolalpha << isInserted);
+    _LOG_DEBUG_ID("Updated: " << std::boolalpha << isUpdated);
+    if (isInserted || isUpdated) {
+      DiffStatePtr commit = make_shared<DiffState>();
+      commit->update(m_sessionName, seqNo);
+      commit->setRootDigest(m_state.getRootDigest());
+      insertToDiffLog(commit, previousRoot);
+
+      satisfyPendingSyncInterests(commit);
+    }
+  }
+}
+
+ConstBufferPtr
+Logic::getRootDigest() const
+{
+  return m_state.getRootDigest();
+}
+
+void
+Logic::printState(std::ostream& os) const
+{
+  BOOST_FOREACH(ConstLeafPtr leaf, m_state.getLeaves())
+    {
+      os << *leaf << "\n";
+    }
+}
+
+std::set<Name>
+Logic::getSessionNames() const
+{
+  std::set<Name> sessionNames;
+
+  BOOST_FOREACH(ConstLeafPtr leaf, m_state.getLeaves())
+    {
+      sessionNames.insert(leaf->getSessionName());
+    }
+
+  return sessionNames;
+}
+
+void
+Logic::onSyncInterest(const Name& prefix, const Interest& interest)
+{
+  _LOG_DEBUG_ID(">> Logic::onSyncInterest");
+  Name name = interest.getName();
+
+  _LOG_DEBUG_ID("InterestName: " << name);
+
+  if (RESET_COMPONENT != name.get(-1)) {
+    // normal sync interest
+    processSyncInterest(interest.shared_from_this());
+  }
+  else
+    // reset interest
+    processResetInterest(interest);
+
+  _LOG_DEBUG_ID("<< Logic::onSyncInterest");
+}
+
+void
+Logic::onSyncRegisterFailed(const Name& prefix, const std::string& msg)
+{
+  //Sync prefix registration failed
+  _LOG_DEBUG_ID(">> Logic::onSyncRegisterFailed");
+}
+
+void
+Logic::onSyncData(const Interest& interest, Data& data)
+{
+  _LOG_DEBUG_ID(">> Logic::onSyncData");
+  // Place holder for validator.
+  onSyncDataValidated(data.shared_from_this());
+  _LOG_DEBUG_ID("<< Logic::onSyncData");
+}
+
+void
+Logic::onResetData(const Interest& interest, Data& data)
+{
+  // This should not happened, drop the received data.
+}
+
+void
+Logic::onSyncTimeout(const Interest& interest)
+{
+  // It is OK. Others will handle the time out situation.
+  _LOG_DEBUG_ID(">> Logic::onSyncTimeout");
+  _LOG_DEBUG_ID("Interest: " << interest.getName());
+  _LOG_DEBUG_ID("<< Logic::onSyncTimeout");
+}
+
+void
+Logic::onSyncDataValidationFailed(const shared_ptr<const Data>& data)
+{
+  // SyncReply cannot be validated.
+}
+
+void
+Logic::onSyncDataValidated(const shared_ptr<const Data>& data)
+{
+  Name name = data->getName();
+  ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
+
+  processSyncData(name, digest, data->getContent().blockFromValue());
+}
+
+void
+Logic::processSyncInterest(const shared_ptr<const Interest>& interest,
+                           bool isTimedProcessing/*=false*/)
+{
+  _LOG_DEBUG_ID(">> Logic::processSyncInterest");
+
+  const Name& name = interest->getName();
+  ConstBufferPtr digest =
+      make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
+
+  ConstBufferPtr rootDigest = m_state.getRootDigest();
+
+  // If the digest of the incoming interest is the same as root digest
+  // Put the interest into InterestTable
+  if (*rootDigest == *digest) {
+    _LOG_DEBUG_ID("Oh, we are in the same state");
+    m_interestTable.insert(interest, digest, false);
+
+    if (!m_isInReset)
+      return;
+
+    if (!isTimedProcessing) {
+      _LOG_DEBUG_ID("Non timed processing in reset");
+      // Still in reset, our own seq has not been put into state yet
+      // Do not hurry, some others may be also resetting and may send their reply
+      if (static_cast<bool>(m_delayedInterestProcessingId))
+        m_scheduler.cancelEvent(m_delayedInterestProcessingId);
+
+      time::milliseconds after(m_rangeUniformRandom());
+      _LOG_DEBUG_ID("After: " << after);
+      m_delayedInterestProcessingId =
+        m_scheduler.scheduleEvent(after,
+                                  bind(&Logic::processSyncInterest, this, interest, true));
+    }
+    else {
+      _LOG_DEBUG_ID("Timed processing in reset");
+      // Now we can get out of reset state by putting our own stuff into m_state.
+      cancelReset();
+    }
+
+    return;
+  }
+
+  // If the digest of incoming interest is an "empty" digest
+  if (digest == EMPTY_DIGEST) {
+    _LOG_DEBUG_ID("Poor guy, he knows nothing");
+    sendSyncData(name, m_state);
+    return;
+  }
+
+  DiffStateContainer::iterator stateIter = m_log.find(digest);
+  // If the digest of incoming interest can be found from the log
+  if (stateIter != m_log.end()) {
+    _LOG_DEBUG_ID("It is ok, you are so close");
+    sendSyncData(name, *(*stateIter)->diff());
+    return;
+  }
+
+  if (!isTimedProcessing) {
+    _LOG_DEBUG_ID("Let's wait, just wait for a while");
+    // Do not hurry, some incoming SyncReplies may help us to recognize the digest
+    bool doesExist = m_interestTable.insert(interest, digest, true);
+    if (doesExist)
+      // Original comment (not sure): somebody else replied, so restart random-game timer
+      // YY: Get the same SyncInterest again, refresh the timer
+      m_scheduler.cancelEvent(m_delayedInterestProcessingId);
+
+    m_delayedInterestProcessingId =
+      m_scheduler.scheduleEvent(time::milliseconds(m_rangeUniformRandom()),
+                                bind(&Logic::processSyncInterest, this, interest, true));
+  }
+  else {
+    // OK, nobody is helping us, just tell the truth.
+    _LOG_DEBUG_ID("OK, nobody is helping us, just tell the truth");
+    m_interestTable.erase(digest);
+    sendSyncData(name, m_state);
+  }
+
+  _LOG_DEBUG_ID("<< Logic::processSyncInterest");
+}
+
+void
+Logic::processResetInterest(const Interest& interest)
+{
+  _LOG_DEBUG_ID(">> Logic::processResetInterest");
+  reset();
+}
+
+void
+Logic::processSyncData(const Name& name,
+                       ndn::ConstBufferPtr digest,
+                       const Block& syncReplyBlock)
+{
+  _LOG_DEBUG_ID(">> Logic::processSyncData");
+
+  DiffStatePtr commit = make_shared<DiffState>();
+  ndn::ConstBufferPtr previousRoot = m_state.getRootDigest();
+
+  try {
+    m_interestTable.erase(digest); // Remove satisfied interest from PIT
+
+    State reply;
+    reply.wireDecode(syncReplyBlock);
+
+    std::vector<MissingDataInfo> v;
+    BOOST_FOREACH(ConstLeafPtr leaf, reply.getLeaves().get<ordered>())
+      {
+        BOOST_ASSERT(leaf != 0);
+
+        const Name& info = leaf->getSessionName();
+        SeqNo seq = leaf->getSeq();
+
+        bool isInserted = false;
+        bool isUpdated = false;
+        SeqNo oldSeq;
+        boost::tie(isInserted, isUpdated, oldSeq) = m_state.update(info, seq);
+
+        if (isInserted || isUpdated) {
+          commit->update(info, seq);
+
+          oldSeq++;
+          MissingDataInfo mdi = {info, oldSeq, seq};
+          v.push_back(mdi);
+        }
+      }
+
+    if (!v.empty()) {
+      m_onUpdate(v);
+
+      commit->setRootDigest(m_state.getRootDigest());
+      insertToDiffLog(commit, previousRoot);
+    }
+    else {
+      _LOG_DEBUG_ID("What? nothing new");
+    }
+  }
+  catch (State::Error&) {
+    _LOG_DEBUG_ID("Something really fishy happened during state decoding");
+    // Something really fishy happened during state decoding;
+    commit.reset();
+    return;
+  }
+
+  if (static_cast<bool>(commit) && !commit->getLeaves().empty()) {
+    // state changed and it is safe to express a new interest
+    time::steady_clock::Duration after = time::milliseconds(m_reexpressionJitter());
+    _LOG_DEBUG_ID("Reschedule sync interest after: " << after);
+    EventId eventId = m_scheduler.scheduleEvent(after,
+                                                bind(&Logic::sendSyncInterest, this));
+
+    m_scheduler.cancelEvent(m_reexpressingInterestId);
+    m_reexpressingInterestId = eventId;
+  }
+}
+
+void
+Logic::satisfyPendingSyncInterests(ConstDiffStatePtr commit)
+{
+  _LOG_DEBUG_ID(">> Logic::satisfyPendingSyncInterests");
+  try {
+    _LOG_DEBUG_ID("InterestTable size: " << m_interestTable.size());
+    for (InterestTable::const_iterator it = m_interestTable.begin();
+         it != m_interestTable.end(); it++) {
+      ConstUnsatisfiedInterestPtr request = *it;
+
+      if (request->isUnknown)
+        sendSyncData(request->interest->getName(), m_state);
+      else
+        sendSyncData(request->interest->getName(), *commit);
+    }
+    m_interestTable.clear();
+  }
+  catch (InterestTable::Error&) {
+    // ok. not really an error
+  }
+  _LOG_DEBUG_ID("<< Logic::satisfyPendingSyncInterests");
+}
+
+void
+Logic::insertToDiffLog(DiffStatePtr commit, ndn::ConstBufferPtr previousRoot)
+{
+  _LOG_DEBUG_ID(">> Logic::insertToDiffLog");
+  // Connect to the history
+  if (!m_log.empty())
+    (*m_log.find(previousRoot))->setNext(commit);
+
+  // Insert the commit
+  m_log.erase(commit->getRootDigest());
+  m_log.insert(commit);
+  _LOG_DEBUG_ID("<< Logic::insertToDiffLog");
+}
+
+void
+Logic::sendResetInterest()
+{
+  _LOG_DEBUG_ID(">> Logic::sendResetInterest");
+
+  if (m_needPeriodReset) {
+    _LOG_DEBUG_ID("Need Period Reset");
+    _LOG_DEBUG_ID("ResetTimer: " << m_resetTimer);
+
+    EventId eventId =
+      m_scheduler.scheduleEvent(m_resetTimer + ndn::time::milliseconds(m_reexpressionJitter()),
+                                bind(&Logic::sendResetInterest, this));
+    m_scheduler.cancelEvent(m_resetInterestId);
+    m_resetInterestId = eventId;
+  }
+
+  Interest interest(m_syncReset);
+  interest.setMustBeFresh(true);
+  interest.setInterestLifetime(m_resetInterestLifetime);
+  m_face.expressInterest(interest,
+                         bind(&Logic::onResetData, this, _1, _2),
+                         bind(&Logic::onSyncTimeout, this, _1));
+
+  _LOG_DEBUG_ID("<< Logic::sendResetInterest");
+}
+
+void
+Logic::sendSyncInterest()
+{
+  _LOG_DEBUG_ID(">> Logic::sendSyncInterest");
+
+  Name interestName;
+  interestName.append(m_syncPrefix)
+    .append(ndn::name::Component(*m_state.getRootDigest()));
+
+  m_outstandingInterestName = interestName;
+
+#ifdef _DEBUG
+  printDigest(m_state.getRootDigest());
+#endif
+
+  EventId eventId =
+    m_scheduler.scheduleEvent(m_syncInterestLifetime +
+                              ndn::time::milliseconds(m_reexpressionJitter()),
+                              bind(&Logic::sendSyncInterest, this));
+  m_scheduler.cancelEvent(m_reexpressingInterestId);
+  m_reexpressingInterestId = eventId;
+
+  Interest interest(interestName);
+  interest.setMustBeFresh(true);
+  interest.setInterestLifetime(m_syncInterestLifetime);
+
+  m_outstandingInterestId = m_face.expressInterest(interest,
+                                                   bind(&Logic::onSyncData, this, _1, _2),
+                                                   bind(&Logic::onSyncTimeout, this, _1));
+
+  _LOG_DEBUG_ID("Send interest: " << interest.getName());
+  _LOG_DEBUG_ID("<< Logic::sendSyncInterest");
+}
+
+void
+Logic::sendSyncData(const Name& name, const State& state)
+{
+  _LOG_DEBUG_ID(">> Logic::sendSyncData");
+  shared_ptr<Data> syncReply = make_shared<Data>(name);
+  syncReply->setContent(state.wireEncode());
+  syncReply->setFreshnessPeriod(m_syncReplyFreshness);
+  m_keyChain.sign(*syncReply);
+
+  m_face.put(*syncReply);
+
+  // checking if our own interest got satisfied
+  if (m_outstandingInterestName == name) {
+    // remove outstanding interest
+    if (m_outstandingInterestId != 0) {
+      m_face.removePendingInterest(m_outstandingInterestId);
+      m_outstandingInterestId = 0;
+    }
+
+    // re-schedule sending Sync interest
+    time::milliseconds after(m_reexpressionJitter());
+    _LOG_DEBUG_ID("Satisfy our own interest");
+    _LOG_DEBUG_ID("Reschedule sync interest after " << after);
+    EventId eventId = m_scheduler.scheduleEvent(after, bind(&Logic::sendSyncInterest, this));
+    m_scheduler.cancelEvent(m_reexpressingInterestId);
+    m_reexpressingInterestId = eventId;
+  }
+  _LOG_DEBUG_ID("<< Logic::sendSyncData");
+}
+
+void
+Logic::cancelReset()
+{
+  _LOG_DEBUG_ID(">> Logic::cancelReset");
+  if (!m_isInReset)
+    return;
+
+  m_isInReset = false;
+  updateSeqNo(m_seqNo);
+  _LOG_DEBUG_ID("<< Logic::cancelReset");
+}
+
+void
+Logic::printDigest(ndn::ConstBufferPtr digest)
+{
+  using namespace CryptoPP;
+
+  std::string hash;
+  StringSource(digest->buf(), digest->size(), true,
+               new HexEncoder(new StringSink(hash), false));
+  _LOG_DEBUG_ID("Hash: " << hash);
+}
+
+} // namespace chronosync
diff --git a/src/logic.hpp b/src/logic.hpp
new file mode 100644
index 0000000..2be8636
--- /dev/null
+++ b/src/logic.hpp
@@ -0,0 +1,388 @@
+/* -*- 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_LOGIC_HPP
+#define CHRONOSYNC_LOGIC_HPP
+
+#include "boost-header.h"
+#include <memory>
+#include <map>
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+#include "interest-table.hpp"
+#include "diff-state-container.hpp"
+
+namespace chronosync {
+
+/**
+ * @brief The missing sequence numbers for a session
+ *
+ * This class is used to notify the clients of Logic
+ * the details of state changes.
+ *
+ * Instances of this class is usually used as elements of some containers
+ * such as std::vector, thus it is copyable.
+ */
+class MissingDataInfo
+{
+public:
+  /// @brief session name
+  Name session;
+  /// @brief the lowest one of missing sequence numbers
+  SeqNo low;
+  /// @brief the highest one of missing sequence numbers
+  SeqNo high;
+};
+
+/**
+ * @brief The callback function to handle state updates
+ *
+ * The parameter is a set of MissingDataInfo, of which each corresponds to
+ * a session that has changed its state.
+ */
+typedef function<void(const std::vector<MissingDataInfo>&)> UpdateCallback;
+
+/**
+ * @brief Logic of ChronoSync
+ */
+class Logic : noncopyable
+{
+public:
+  static const time::steady_clock::Duration DEFAULT_RESET_TIMER;
+  static const time::steady_clock::Duration DEFAULT_CANCEL_RESET_TIMER;
+  static const time::milliseconds DEFAULT_RESET_INTEREST_LIFETIME;
+  static const time::milliseconds DEFAULT_SYNC_INTEREST_LIFETIME;
+  static const time::milliseconds DEFAULT_SYNC_REPLY_FRESHNESS;
+
+  /**
+   * @brief Constructor
+   *
+   * @param syncPrefix The prefix of the sync group
+   * @param userPrefix The prefix of the user who owns the session
+   * @param onUpdate The callback function to handle state updates
+   * @param resetTimer The timer to periodically send Reset Interest
+   * @param syncReplyFreshness The FreshnessPeriod of sync reply
+   * @param resetInterestLifetime The lifetime of sync interest
+   * @param resetInterestLifetime The lifetime of Reset Interest
+   * @param cancelResetTimer The timer to exit from Reset state
+   */
+  Logic(ndn::Face& face,
+        const Name& syncPrefix,
+        const Name& userPrefix,
+        const UpdateCallback& onUpdate,
+        const time::steady_clock::Duration& resetTimer = DEFAULT_RESET_TIMER,
+        const time::steady_clock::Duration& cancelResetTimer = DEFAULT_CANCEL_RESET_TIMER,
+        const time::milliseconds& resetInterestLifetime = DEFAULT_RESET_INTEREST_LIFETIME,
+        const time::milliseconds& syncInterestLifetime = DEFAULT_SYNC_INTEREST_LIFETIME,
+        const time::milliseconds& syncReplyFreshness = DEFAULT_SYNC_REPLY_FRESHNESS);
+
+  ~Logic();
+
+  /// @brief Reset the sync tree (and restart synchronization again)
+  void
+  reset();
+
+  /**
+   * @brief Set user prefix
+   *
+   * This method will also change the session name and trigger reset.
+   *
+   * @param userPrefix The prefix of user.
+   */
+  void
+  setUserPrefix(const Name& userPrefix);
+
+  /// @brief Get the name of the local session.
+  const Name&
+  getSessionName() const
+  {
+    return m_sessionName;
+  }
+
+  /// @brief Get current seqNo of the local session.
+  const SeqNo&
+  getSeqNo() const
+  {
+    return m_seqNo;
+  }
+
+  /**
+   * @brief Update the seqNo of the local session
+   *
+   * The method updates the existing seqNo with the supplied seqNo.
+   *
+   * @param seq The new seqNo.
+   */
+  void
+  updateSeqNo(const SeqNo& seq);
+
+  /// @brief Get root digest of current sync tree
+  ndn::ConstBufferPtr
+  getRootDigest() const;
+
+  /// @brief Get the name of all sessions
+  std::set<Name>
+  getSessionNames() const;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  printState(std::ostream& os) const;
+
+  ndn::Scheduler&
+  getScheduler()
+  {
+    return m_scheduler;
+  }
+
+  State&
+  getState()
+  {
+    return m_state;
+  }
+
+private:
+  /**
+   * @brief Callback to handle Sync Interest
+   *
+   * This method checks whether an incoming interest is a normal one or a reset
+   * and dispatches the incoming interest to corresponding processing methods.
+   *
+   * @param prefix   The prefix of the sync group.
+   * @param interest The incoming sync interest.
+   */
+  void
+  onSyncInterest(const Name& prefix, const Interest& interest);
+
+  /**
+   * @brief Callback to handle Sync prefix registration failure
+   *
+   * This method does nothing for now.
+   *
+   * @param prefix The prefix of the sync group.
+   * @param msg    The error message.
+   */
+  void
+  onSyncRegisterFailed(const Name& prefix, const std::string& msg);
+
+  /**
+   * @brief Callback to handle Sync Reply
+   *
+   * This method calls validator to validate Sync Reply.
+   * For now, validation is disabled, Logic::onSyncDataValidated is called
+   * directly.
+   *
+   * @param interest The Sync Interest
+   * @param data     The reply to the Sync Interest
+   */
+  void
+  onSyncData(const Interest& interest, Data& data);
+
+  /**
+   * @brief Callback to handle reply to Reset Interest.
+   *
+   * This method does nothing, since reply to Reset Interest is not useful for now.
+   *
+   * @param interest The Reset Interest
+   * @param data     The reply to the Reset Interest
+   */
+  void
+  onResetData(const Interest& interest, Data& data);
+
+  /**
+   * @brief Callback to handle Sync Interest timeout.
+   *
+   * This method does nothing, since Logic per se handles timeout explicitly.
+   *
+   * @param interest The Sync Interest
+   */
+  void
+  onSyncTimeout(const Interest& interest);
+
+  /**
+   * @brief Callback to invalid Sync Reply.
+   *
+   * This method does nothing but drops the invalid reply.
+   *
+   * @param data The invalid Sync Reply
+   */
+  void
+  onSyncDataValidationFailed(const shared_ptr<const Data>& data);
+
+  /**
+   * @brief Callback to valid Sync Reply.
+   *
+   * This method simply passes the valid reply to processSyncData.
+   *
+   * @param data The valid Sync Reply.
+   */
+  void
+  onSyncDataValidated(const shared_ptr<const Data>& data);
+
+  /**
+   * @brief Process normal Sync Interest
+   *
+   * This method extracts the digest from the incoming Sync Interest,
+   * compares it against current local digest, and process the Sync
+   * Interest according to the comparison result.  See docs/design.rst
+   * for more details.
+   *
+   * @param interest          The incoming interest
+   * @param isTimedProcessing True if the interest needs an immediate reply,
+   *                          otherwise hold the interest for a while before
+   *                          making a reply (to avoid unnecessary recovery)
+   */
+  void
+  processSyncInterest(const shared_ptr<const Interest>& interest,
+                      bool isTimedProcessing = false);
+
+  /**
+   * @brief Process reset Sync Interest
+   *
+   * This method simply call Logic::reset()
+   *
+   * @param interest The incoming interest.
+   */
+  void
+  processResetInterest(const Interest& interest);
+
+  /**
+   * @brief Process Sync Reply.
+   *
+   * This method extracts state update information from Sync Reply and applies
+   * it to the Sync Tree and re-express Sync Interest.
+   *
+   * @param name           The data name of the Sync Reply.
+   * @param digest         The digest in the data name.
+   * @param syncReplyBlock The content of the Sync Reply.
+   */
+  void
+  processSyncData(const Name& name,
+                  ndn::ConstBufferPtr digest,
+                  const Block& syncReplyBlock);
+
+  /**
+   * @brief Insert state diff into log
+   *
+   * @param diff         The diff .
+   * @param previousRoot The root digest before state changes.
+   */
+  void
+  insertToDiffLog(DiffStatePtr diff,
+                  ndn::ConstBufferPtr previousRoot);
+
+  /**
+   * @brief Reply to all pending Sync Interests with a particular commit (or diff)
+   *
+   * @param commit The diff.
+   */
+  void
+  satisfyPendingSyncInterests(ConstDiffStatePtr commit);
+
+  /// @brief Helper method to send normal Sync Interest
+  void
+  sendSyncInterest();
+
+  /// @brief Helper method to send reset Sync Interest
+  void
+  sendResetInterest();
+
+  /// @brief Helper method to send Sync Reply
+  void
+  sendSyncData(const Name& name, const State& state);
+
+  /**
+   * @brief Unset reset status
+   *
+   * By invoking this method, one can add its own state into the Sync Tree, thus
+   * jumping out of the reset status
+   */
+  void
+  cancelReset();
+
+  void
+  printDigest(ndn::ConstBufferPtr digest);
+
+private:
+
+  static const ndn::ConstBufferPtr EMPTY_DIGEST;
+  static const ndn::name::Component RESET_COMPONENT;
+
+  // Communication
+  ndn::Face& m_face;
+  Name m_syncPrefix;
+  const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;
+  Name m_syncReset;
+  Name m_userPrefix;
+
+  // State
+  Name m_sessionName;
+  SeqNo m_seqNo;
+  State m_state;
+  DiffStateContainer m_log;
+  InterestTable m_interestTable;
+  Name m_outstandingInterestName;
+  const ndn::PendingInterestId* m_outstandingInterestId;
+  bool m_isInReset;
+  bool m_needPeriodReset;
+
+  // Callback
+  UpdateCallback m_onUpdate;
+
+  // Event
+  ndn::Scheduler m_scheduler;
+  ndn::EventId m_delayedInterestProcessingId;
+  ndn::EventId m_reexpressingInterestId;
+  ndn::EventId m_resetInterestId;
+
+  // Timer
+  boost::mt19937 m_randomGenerator;
+  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_rangeUniformRandom;
+  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_reexpressionJitter;
+  /// @brief Timer to send next reset 0 for no reset
+  time::steady_clock::Duration m_resetTimer;
+  /// @brief Timer to cancel reset state
+  time::steady_clock::Duration m_cancelResetTimer;
+  /// @brief Lifetime of reset interest
+  time::milliseconds m_resetInterestLifetime;
+  /// @brief Lifetime of sync interest
+  time::milliseconds m_syncInterestLifetime;
+  /// @brief FreshnessPeriod of SyncReply
+  time::milliseconds m_syncReplyFreshness;
+
+  // Others
+  ndn::KeyChain m_keyChain;
+
+#ifdef _DEBUG
+  int m_instanceId;
+  static int m_instanceCounter;
+#endif
+};
+
+
+} // namespace chronosync
+
+#endif // CHRONOSYNC_LOGIC_HPP
diff --git a/src/sync-event.h b/src/sync-event.h
deleted file mode 100644
index bbe07bc..0000000
--- a/src/sync-event.h
+++ /dev/null
@@ -1,36 +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 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_EVENT_H
-#define SYNC_EVENT_H
-
-#include <boost/function.hpp>
-
-namespace Sync
-{
-
-typedef boost::function< void ( ) > Event;
-
-} // Sync
-
-#endif // SYNC_EVENT_H
diff --git a/src/sync-logic-event-container.h b/src/sync-logic-event-container.h
deleted file mode 100644
index 015984d..0000000
--- a/src/sync-logic-event-container.h
+++ /dev/null
@@ -1,86 +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 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_LOGIC_EVENT_CONTAINER_H
-#define SYNC_LOGIC_EVENT_CONTAINER_H
-
-#include "sync-event.h"
-
-#include <boost/function.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#include <boost/multi_index_container.hpp>
-// #include <boost/multi_index/tag.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-// #include <boost/multi_index/composite_key.hpp>
-// #include <boost/multi_index/hashed_index.hpp>
-// #include <boost/multi_index/random_access_index.hpp>
-#include <boost/multi_index/member.hpp>
-// #include <boost/multi_index/mem_fun.hpp>
-
-namespace mi = boost::multi_index;
-
-namespace Sync
-{
-
-struct LogicEvent
-{
-  LogicEvent (const boost::system_time &_time, Event _event, uint32_t _label)
-    : time (_time)
-    , event (_event)
-    , lbl (_label)
-  { }
-
-  boost::system_time time;
-  Event event;
-  uint32_t lbl;
-};
-
-/// @cond include_hidden
-struct byLabel { } ;
-/// @endcond
-
-/**
- * \ingroup sync
- * @brief ???
- */
-struct EventsContainer : public mi::multi_index_container<
-  LogicEvent,
-  mi::indexed_by<
-
-    mi::ordered_non_unique<
-      mi::member<LogicEvent, boost::system_time, &LogicEvent::time>
-      >,
-
-    mi::ordered_non_unique<
-      mi::tag<byLabel>,
-      mi::member<LogicEvent, uint32_t, &LogicEvent::lbl>
-      >
-    >
-  >
-{
-};
-
-} // Sync
-
-#endif // SYNC_LOGIC_EVENT_CONTAINER_H
diff --git a/src/sync-logic.cc b/src/sync-logic.cc
deleted file mode 100644
index 0567b60..0000000
--- a/src/sync-logic.cc
+++ /dev/null
@@ -1,714 +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 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 <http://irl.cs.ucla.edu/~yingdi/web/index.html>
- */
-
-#include "sync-logic.h"
-#include "sync-diff-leaf.h"
-#include "sync-full-leaf.h"
-#include "sync-logging.h"
-#include "sync-state.h"
-
-#include <boost/foreach.hpp>
-#include <boost/lexical_cast.hpp>
-#include <vector>
-
-using namespace ndn;
-
-INIT_LOGGER ("SyncLogic")
-
-
-#ifdef _DEBUG
-#define _LOG_DEBUG_ID(v) _LOG_DEBUG(m_instanceId << " " << v)
-#else
-#define _LOG_DEBUG_ID(v) _LOG_DEBUG(v)
-#endif
-
-#define GET_RANDOM(var) var ()
-
-#define TIME_SECONDS_WITH_JITTER(sec) \
-  (time::seconds(sec) + time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
-
-#define TIME_MILLISECONDS_WITH_JITTER(ms) \
-  (time::milliseconds(ms) + time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
-
-namespace Sync {
-
-using ndn::shared_ptr;
-
-int SyncLogic::m_instanceCounter = 0;
-
-const int SyncLogic::m_syncResponseFreshness = 1000; // MUST BE dividable by 1000!!!
-const int SyncLogic::m_syncInterestReexpress = 4; // seconds
-
-SyncLogic::SyncLogic (const Name& syncPrefix,
-                      const IdentityCertificate& myCertificate,
-                      shared_ptr<Validator> validator,
-                      shared_ptr<Face> face,
-                      LogicUpdateCallback onUpdate,
-                      LogicRemoveCallback onRemove)
-  : m_state (new FullState)
-  , m_syncInterestTable (face->getIoService(), time::seconds(m_syncInterestReexpress))
-  , m_syncPrefix (syncPrefix)
-  , m_myCertificate(myCertificate)
-  , m_onUpdate (onUpdate)
-  , m_onRemove (onRemove)
-  , m_perBranch (false)
-  , m_validator(validator)
-  , m_face(face)
-  , m_scheduler(face->getIoService())
-  , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
-  , m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
-  , m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
-  , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
-{
-  m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
-                                                        bind(&SyncLogic::onSyncInterest, this, _1, _2),
-                                                        bind(&SyncLogic::onSyncRegisterFailed, this, _1, _2));
-
-
-  m_reexpressingInterestId = m_scheduler.scheduleEvent (time::seconds (0), // no need to add jitter
-                                                        bind (&SyncLogic::sendSyncInterest, this));
-
-  m_instanceId = std::string("Instance " + boost::lexical_cast<std::string>(m_instanceCounter++) + " ");
-}
-
-SyncLogic::SyncLogic (const Name& syncPrefix,
-                      const IdentityCertificate& myCertificate,
-                      shared_ptr<Validator> validator,
-                      shared_ptr<Face> face,
-                      LogicPerBranchCallback onUpdateBranch)
-  : m_state (new FullState)
-  , m_syncInterestTable (face->getIoService(), time::seconds (m_syncInterestReexpress))
-  , m_syncPrefix (syncPrefix)
-  , m_myCertificate(myCertificate)
-  , m_onUpdateBranch (onUpdateBranch)
-  , m_perBranch(true)
-  , m_validator(validator)
-  , m_face(face)
-  , m_scheduler(face->getIoService())
-  , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
-  , m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
-  , m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
-  , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
-{
-  m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
-                                                        bind(&SyncLogic::onSyncInterest, this, _1, _2),
-                                                        bind(&SyncLogic::onSyncRegisterFailed, this, _1, _2));
-
-  m_reexpressingInterestId = m_scheduler.scheduleEvent (time::seconds (0), // no need to add jitter
-                                                        bind (&SyncLogic::sendSyncInterest, this));
-}
-
-SyncLogic::~SyncLogic ()
-{
-  m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
-  m_scheduler.cancelEvent (m_reexpressingInterestId);
-  m_scheduler.cancelEvent (m_delayedInterestProcessingId);
-}
-
-/**
- * Two types of intersts
- *
- * Normal name:    .../<hash>
- * Recovery name:  .../recovery/<hash>
- */
-boost::tuple<DigestConstPtr, std::string>
-SyncLogic::convertNameToDigestAndType (const Name &name)
-{
-  BOOST_ASSERT (m_syncPrefix.isPrefixOf(name));
-
-  int nameLengthDiff = name.size() - m_syncPrefix.size();
-  BOOST_ASSERT (nameLengthDiff > 0);
-  BOOST_ASSERT (nameLengthDiff < 3);
-
-  std::string hash = name.get(-1).toUri();
-  std::string interestType;
-
-  if(nameLengthDiff == 1)
-    interestType = "normal";
-  else
-    interestType = name.get(-2).toUri();
-
-  _LOG_DEBUG_ID (hash << ", " << interestType);
-
-  DigestPtr digest = boost::make_shared<Digest> ();
-  std::istringstream is (hash);
-  is >> *digest;
-
-  return make_tuple (digest, interestType);
-}
-
-void
-SyncLogic::onSyncInterest (const Name& prefix, const ndn::Interest& interest)
-{
-  Name name = interest.getName();
-
-  _LOG_DEBUG_ID("respondSyncInterest: " << name);
-
-  try
-    {
-      _LOG_DEBUG_ID ("<< I " << name);
-
-      if(name.get(m_syncPrefix.size()).toUri() == "CHRONOS-INTRO-CERT")
-        // it is a certificate, validator will take care of it.
-        return;
-
-      DigestConstPtr digest;
-      std::string type;
-      tie (digest, type) = convertNameToDigestAndType (name);
-
-      if (type == "normal") // kind of ineffective...
-        {
-          processSyncInterest (name, digest);
-        }
-      else if (type == "recovery")
-        {
-          processSyncRecoveryInterest (name, digest);
-        }
-    }
-  catch (Error::DigestCalculationError &e)
-    {
-      _LOG_DEBUG_ID ("Something fishy happened...");
-      // log error. ignoring it for now, later we should log it
-      return ;
-    }
-}
-
-void
-SyncLogic::onSyncRegisterFailed(const Name& prefix, const std::string& msg)
-{
-  _LOG_DEBUG_ID("Sync prefix registration failed! " << msg);
-}
-
-void
-SyncLogic::onSyncData(const ndn::Interest& interest, Data& data)
-{
-  OnDataValidated onValidated = bind(&SyncLogic::onSyncDataValidated, this, _1);
-  OnDataValidationFailed onValidationFailed = bind(&SyncLogic::onSyncDataValidationFailed, this, _1);
-  m_validator->validate(data, onValidated, onValidationFailed);
-}
-
-void
-SyncLogic::onSyncTimeout(const ndn::Interest& interest)
-{
-  // It is OK. Others will handle the time out situation.
-}
-
-void
-SyncLogic::onSyncDataValidationFailed(const shared_ptr<const Data>& data)
-{
-  _LOG_DEBUG_ID("Sync data cannot be verified!");
-}
-
-void
-SyncLogic::onSyncDataValidated(const shared_ptr<const Data>& data)
-{
-  Name name = data->getName();
-  const char* wireData = (const char*)data->getContent().value();
-  size_t len = data->getContent().value_size();
-
-  try
-    {
-      _LOG_DEBUG_ID ("<< D " << name);
-
-      DigestConstPtr digest;
-      std::string type;
-      tie (digest, type) = convertNameToDigestAndType (name);
-
-      if (type == "normal")
-        {
-          processSyncData (name, digest, wireData, len);
-        }
-      else
-        {
-          // timer is always restarted when we schedule recovery
-          m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
-          processSyncData (name, digest, wireData, len);
-        }
-    }
-  catch (Error::DigestCalculationError &e)
-    {
-      _LOG_DEBUG_ID ("Something fishy happened...");
-      // log error. ignoring it for now, later we should log it
-      return;
-    }
-}
-
-void
-SyncLogic::processSyncInterest (const Name &name, DigestConstPtr digest, bool timedProcessing/*=false*/)
-{
-  _LOG_DEBUG_ID("processSyncInterest");
-  DigestConstPtr rootDigest;
-  {
-    rootDigest = m_state->getDigest();
-  }
-
-  // Special case when state is not empty and we have received request with zero-root digest
-  if (digest->isZero () && !rootDigest->isZero ())
-    {
-
-      SyncStateMsg ssm;
-      {
-        ssm << (*m_state);
-      }
-      sendSyncData (name, digest, ssm);
-      return;
-    }
-
-  if (*rootDigest == *digest)
-    {
-      _LOG_DEBUG_ID ("processSyncInterest (): Same state. Adding to PIT");
-      m_syncInterestTable.insert (digest, name.toUri(), false);
-      return;
-    }
-
-  DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
-
-  if (stateInDiffLog != m_log.end ())
-  {
-    DiffStateConstPtr stateDiff = (*stateInDiffLog)->diff ();
-
-    sendSyncData (name, digest, stateDiff);
-    return;
-  }
-
-  if (!timedProcessing)
-    {
-      bool exists = m_syncInterestTable.insert (digest, name.toUri(), true);
-      if (exists) // somebody else replied, so restart random-game timer
-        {
-          _LOG_DEBUG_ID ("Unknown digest, but somebody may have already replied, so restart our timer");
-          m_scheduler.cancelEvent (m_delayedInterestProcessingId);
-        }
-
-      uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
-      _LOG_DEBUG_ID ("Digest is not in the log. Schedule processing after small delay: " << time::milliseconds (waitDelay));
-
-      m_delayedInterestProcessingId = m_scheduler.scheduleEvent (time::milliseconds (waitDelay),
-                                                                 bind (&SyncLogic::processSyncInterest, this, name, digest, true));
-    }
-  else
-    {
-      _LOG_DEBUG_ID ("                                                      (timed processing)");
-
-      m_recoveryRetransmissionInterval = m_defaultRecoveryRetransmitInterval;
-      sendSyncRecoveryInterests (digest);
-    }
-}
-
-void
-SyncLogic::processSyncData (const Name &name, DigestConstPtr digest, const char *wireData, size_t len)
-{
-  DiffStatePtr diffLog = boost::make_shared<DiffState> ();
-  bool ownInterestSatisfied = false;
-
-  try
-    {
-
-      m_syncInterestTable.remove (name.toUri()); // Remove satisfied interest from PIT
-
-      ownInterestSatisfied = (name == m_outstandingInterestName);
-
-      DiffState diff;
-      SyncStateMsg msg;
-      if (!msg.ParseFromArray(wireData, len) || !msg.IsInitialized())
-      {
-        //Throw
-        BOOST_THROW_EXCEPTION (Error::SyncStateMsgDecodingFailure () );
-      }
-      msg >> diff;
-
-      std::vector<MissingDataInfo> v;
-      BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
-        {
-          DiffLeafConstPtr diffLeaf = boost::dynamic_pointer_cast<const DiffLeaf> (leaf);
-          BOOST_ASSERT (diffLeaf != 0);
-
-          NameInfoConstPtr info = diffLeaf->getInfo();
-          if (diffLeaf->getOperation() == UPDATE)
-            {
-              SeqNo seq = diffLeaf->getSeq();
-
-              bool inserted = false;
-              bool updated = false;
-              SeqNo oldSeq;
-              {
-                boost::tie (inserted, updated, oldSeq) = m_state->update (info, seq);
-              }
-
-              if (inserted || updated)
-                {
-                  diffLog->update (info, seq);
-                  if (!oldSeq.isValid())
-                  {
-                    oldSeq = SeqNo(seq.getSession(), 0);
-                  }
-                  else
-                  {
-                    ++oldSeq;
-                  }
-                  // there is no need for application to process update on forwarder node
-                  if (info->toString() != forwarderPrefix)
-                  {
-                    MissingDataInfo mdi = {info->toString(), oldSeq, seq};
-                    {
-                      std::ostringstream interestName;
-                      interestName << mdi.prefix << "/" << mdi.high.getSession() << "/" << mdi.high.getSeq();
-                      _LOG_DEBUG_ID("+++++++++++++++ " + interestName.str());
-                    }
-                    if (m_perBranch)
-                    {
-                      std::ostringstream interestName;
-                      interestName << mdi.prefix << "/" << mdi.high.getSession() << "/" << mdi.high.getSeq();
-                      m_onUpdateBranch(interestName.str());
-                    }
-                    else
-                    {
-                      v.push_back(mdi);
-                    }
-                  }
-                }
-            }
-          else if (diffLeaf->getOperation() == REMOVE)
-            {
-              if (m_state->remove (info))
-                {
-                  diffLog->remove (info);
-                  if (!m_perBranch)
-                  {
-                    m_onRemove (info->toString ());
-                  }
-                }
-            }
-          else
-            {
-            }
-        }
-
-      if (!v.empty())
-      {
-        if (!m_perBranch)
-        {
-           m_onUpdate(v);
-        }
-      }
-
-      insertToDiffLog (diffLog);
-    }
-  catch (Error::SyncStateMsgDecodingFailure &e)
-    {
-      _LOG_DEBUG_ID ("Something really fishy happened during state decoding " <<
-                  diagnostic_information (e));
-      diffLog.reset ();
-      // don't do anything
-    }
-
-  if ((diffLog != 0 && diffLog->getLeaves ().size () > 0) ||
-      ownInterestSatisfied)
-    {
-      _LOG_DEBUG_ID(" +++++++++++++++ state changed!!!");
-      // Do it only if everything went fine and state changed
-
-      // this is kind of wrong
-      // satisfyPendingSyncInterests (diffLog); // if there are interests in PIT, there is a point to satisfy them using new state
-
-      // if state has changed, then it is safe to express a new interest
-      time::system_clock::Duration after = time::milliseconds(GET_RANDOM (m_reexpressionJitter));
-      // cout << "------------ reexpress interest after: " << after << endl;
-      EventId eventId = m_scheduler.scheduleEvent (after,
-                                                   bind (&SyncLogic::sendSyncInterest, this));
-
-      m_scheduler.cancelEvent (m_reexpressingInterestId);
-      m_reexpressingInterestId = eventId;
-    }
-}
-
-void
-SyncLogic::processSyncRecoveryInterest (const Name &name, DigestConstPtr digest)
-{
-  _LOG_DEBUG_ID("processSyncRecoveryInterest");
-  DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
-
-  if (stateInDiffLog == m_log.end ())
-    {
-      _LOG_DEBUG_ID ("Could not find " << *digest << " in digest log");
-      return;
-    }
-
-  SyncStateMsg ssm;
-  {
-    ssm << (*m_state);
-  }
-  sendSyncData (name, digest, ssm);
-}
-
-void
-SyncLogic::satisfyPendingSyncInterests (DiffStateConstPtr diffLog)
-{
-  DiffStatePtr fullStateLog = boost::make_shared<DiffState> ();
-  {
-    BOOST_FOREACH (LeafConstPtr leaf, m_state->getLeaves ()/*.get<timed> ()*/)
-      {
-        fullStateLog->update (leaf->getInfo (), leaf->getSeq ());
-        /// @todo Impose limit on how many state info should be send out
-      }
-  }
-
-  try
-    {
-      uint32_t counter = 0;
-      while (m_syncInterestTable.size () > 0)
-        {
-          Sync::Interest interest = m_syncInterestTable.pop ();
-
-          if (!interest.m_unknown)
-            {
-              _LOG_DEBUG_ID (">> D " << interest.m_name);
-              sendSyncData (interest.m_name, interest.m_digest, diffLog);
-            }
-          else
-            {
-              _LOG_DEBUG_ID (">> D (unknown)" << interest.m_name);
-              sendSyncData (interest.m_name, interest.m_digest, fullStateLog);
-            }
-          counter ++;
-        }
-      _LOG_DEBUG_ID ("Satisfied " << counter << " pending interests");
-    }
-  catch (Error::InterestTableIsEmpty &e)
-    {
-      // ok. not really an error
-    }
-}
-
-void
-SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
-{
-  diffLog->setDigest (m_state->getDigest());
-  if (m_log.size () > 0)
-    {
-      m_log.get<sequenced> ().front ()->setNext (diffLog);
-    }
-  m_log.erase (m_state->getDigest()); // remove diff state with the same digest.  next pointers are still valid
-  /// @todo Optimization
-  m_log.get<sequenced> ().push_front (diffLog);
-}
-
-void
-SyncLogic::addLocalNames (const Name &prefix, uint64_t session, uint64_t seq)
-{
-  DiffStatePtr diff;
-  {
-    //cout << "Add local names" <<endl;
-    NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
-
-    _LOG_DEBUG_ID ("addLocalNames (): old state " << *m_state->getDigest ());
-
-    SeqNo seqN (session, seq);
-    m_state->update(info, seqN);
-
-    _LOG_DEBUG_ID ("addLocalNames (): new state " << *m_state->getDigest ());
-
-    diff = boost::make_shared<DiffState>();
-    diff->update(info, seqN);
-    insertToDiffLog (diff);
-  }
-
-  // _LOG_DEBUG_ID ("PIT size: " << m_syncInterestTable.size ());
-  satisfyPendingSyncInterests (diff);
-}
-
-void
-SyncLogic::remove(const Name &prefix)
-{
-  DiffStatePtr diff;
-  {
-    NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
-    m_state->remove(info);
-
-    // increment the sequence number for the forwarder node
-    NameInfoConstPtr forwarderInfo = StdNameInfo::FindOrCreate(forwarderPrefix);
-
-    LeafContainer::iterator item = m_state->getLeaves ().find (forwarderInfo);
-    SeqNo seqNo (0);
-    if (item != m_state->getLeaves ().end ())
-      {
-        seqNo = (*item)->getSeq ();
-        ++seqNo;
-      }
-    m_state->update (forwarderInfo, seqNo);
-
-    diff = boost::make_shared<DiffState>();
-    diff->remove(info);
-    diff->update(forwarderInfo, seqNo);
-
-    insertToDiffLog (diff);
-  }
-
-  satisfyPendingSyncInterests (diff);
-}
-
-void
-SyncLogic::sendSyncInterest ()
-{
-  _LOG_DEBUG_ID("sendSyncInterest");
-
-  {
-    m_outstandingInterestName = m_syncPrefix;
-    std::ostringstream os;
-    os << *m_state->getDigest();
-    m_outstandingInterestName.append(os.str());
-    _LOG_DEBUG_ID (">> I " << m_outstandingInterestName);
-  }
-
-  _LOG_DEBUG_ID("sendSyncInterest: " << m_outstandingInterestName);
-
-  EventId eventId = m_scheduler.scheduleEvent (time::seconds(m_syncInterestReexpress) + time::milliseconds(GET_RANDOM (m_reexpressionJitter)),
-                                               bind (&SyncLogic::sendSyncInterest, this));
-  m_scheduler.cancelEvent (m_reexpressingInterestId);
-  m_reexpressingInterestId = eventId;
-
-  ndn::Interest interest(m_outstandingInterestName);
-  interest.setMustBeFresh(true);
-
-  m_face->expressInterest(interest,
-                          bind(&SyncLogic::onSyncData, this, _1, _2),
-                          bind(&SyncLogic::onSyncTimeout, this, _1));
-}
-
-void
-SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
-{
-  std::ostringstream os;
-  os << *digest;
-
-  Name interestName = m_syncPrefix;
-  interestName.append("recovery").append(os.str());
-
-  time::system_clock::Duration nextRetransmission = time::milliseconds (m_recoveryRetransmissionInterval + GET_RANDOM (m_reexpressionJitter));
-
-  m_recoveryRetransmissionInterval <<= 1;
-
-  m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
-  if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
-    m_reexpressingRecoveryInterestId = m_scheduler.scheduleEvent (nextRetransmission,
-                                                                  bind (&SyncLogic::sendSyncRecoveryInterests, this, digest));
-
-  ndn::Interest interest(interestName);
-  interest.setMustBeFresh(true);
-
-  m_face->expressInterest(interest,
-                          bind(&SyncLogic::onSyncData, this, _1, _2),
-                          bind(&SyncLogic::onSyncTimeout, this, _1));
-}
-
-
-void
-SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, StateConstPtr state)
-{
-  SyncStateMsg msg;
-  msg << (*state);
-  sendSyncData(name, digest, msg);
-}
-
-// pass in state msg instead of state, so that there is no need to lock the state until
-// this function returns
-void
-SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &ssm)
-{
-  _LOG_DEBUG_ID (">> D " << name);
-  int size = ssm.ByteSize();
-  char *wireData = new char[size];
-  ssm.SerializeToArray(wireData, size);
-
-  Data syncData(name);
-  syncData.setContent(reinterpret_cast<const uint8_t*>(wireData), size);
-  syncData.setFreshnessPeriod(time::milliseconds(m_syncResponseFreshness));
-
-  m_keyChain.sign(syncData, m_myCertificate.getName());
-
-  m_face->put(syncData);
-
-  delete []wireData;
-
-  // checking if our own interest got satisfied
-  bool satisfiedOwnInterest = false;
-  {
-    satisfiedOwnInterest = (m_outstandingInterestName == name);
-  }
-
-  if (satisfiedOwnInterest)
-    {
-      _LOG_DEBUG_ID ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
-
-      time::system_clock::Duration after = time::milliseconds(GET_RANDOM (m_reexpressionJitter));
-      // cout << "------------ reexpress interest after: " << after << endl;
-      EventId eventId = m_scheduler.scheduleEvent (after,
-                                                   bind (&SyncLogic::sendSyncInterest, this));
-      m_scheduler.cancelEvent (m_reexpressingInterestId);
-      m_reexpressingInterestId = eventId;
-    }
-}
-
-std::string
-SyncLogic::getRootDigest()
-{
-  std::ostringstream os;
-  os << *m_state->getDigest();
-  return os.str();
-}
-
-size_t
-SyncLogic::getNumberOfBranches () const
-{
-  return m_state->getLeaves ().size ();
-}
-
-void
-SyncLogic::printState () const
-{
-  BOOST_FOREACH (const boost::shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
-    {
-      std::cout << *leaf << std::endl;
-    }
-}
-
-std::map<std::string, bool>
-SyncLogic::getBranchPrefixes() const
-{
-  std::map<std::string, bool> m;
-
-  BOOST_FOREACH (const boost::shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
-    {
-      std::string prefix = leaf->getInfo()->toString();
-      // do not return forwarder prefix
-      if (prefix != forwarderPrefix)
-      {
-        m.insert(std::pair<std::string, bool>(prefix, false));
-      }
-    }
-
-  return m;
-}
-
-}
diff --git a/src/sync-logic.h b/src/sync-logic.h
deleted file mode 100644
index 181979b..0000000
--- a/src/sync-logic.h
+++ /dev/null
@@ -1,214 +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 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 <http://irl.cs.ucla.edu/~yingdi/web/index.html>
- */
-
-#ifndef SYNC_LOGIC_H
-#define SYNC_LOGIC_H
-
-#include "boost-header.h"
-#include <memory>
-#include <map>
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/validator.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-
-#include "sync-interest-table.h"
-#include "sync-diff-state.h"
-#include "sync-full-state.h"
-#include "sync-std-name-info.h"
-
-#include "sync-diff-state-container.h"
-
-#ifdef _DEBUG
-#ifdef HAVE_LOG4CXX
-#include <log4cxx/logger.h>
-#endif
-#endif
-
-namespace Sync {
-
-struct MissingDataInfo {
-  std::string prefix;
-  SeqNo low;
-  SeqNo high;
-};
-
-/**
- * \ingroup sync
- * @brief A wrapper for SyncApp, which handles ccnx related things (process
- * interests and data)
- */
-
-class SyncLogic
-{
-public:
-  //typedef boost::function< void ( const std::string &/*prefix*/, const SeqNo &/*newSeq*/, const SeqNo &/*oldSeq*/ ) > LogicUpdateCallback;
-  typedef boost::function< void (const std::vector<MissingDataInfo> & ) > LogicUpdateCallback;
-  typedef boost::function< void (const std::string &/*prefix*/ ) > LogicRemoveCallback;
-  typedef boost::function< void (const std::string &)> LogicPerBranchCallback;
-
-  SyncLogic (const ndn::Name& syncPrefix,
-             const ndn::IdentityCertificate& myCertificate,
-             ndn::shared_ptr<ndn::Validator> validator,
-             ndn::shared_ptr<ndn::Face> face,
-             LogicUpdateCallback onUpdate,
-             LogicRemoveCallback onRemove);
-
-  SyncLogic (const ndn::Name& syncPrefix,
-             const ndn::IdentityCertificate& myCertificate,
-             ndn::shared_ptr<ndn::Validator> validator,
-             ndn::shared_ptr<ndn::Face> face,
-             LogicPerBranchCallback onUpdateBranch);
-
-  ~SyncLogic ();
-
-  /**
-   * a wrapper for the same func in SyncApp
-   */
-  void addLocalNames (const ndn::Name &prefix, uint64_t session, uint64_t seq);
-
-  /**
-   * @brief remove a participant's subtree from the sync tree
-   * @param prefix the name prefix for the participant
-   */
-  void remove (const ndn::Name &prefix);
-
-  std::string
-  getRootDigest();
-
-#ifdef _DEBUG
-  ndn::Scheduler &
-  getScheduler () { return m_scheduler; }
-#endif
-
-  void
-  printState () const;
-
-  std::map<std::string, bool>
-  getBranchPrefixes() const;
-
-private:
-  void
-  delayedChecksLoop ();
-
-  void
-  onSyncInterest (const ndn::Name& prefix, const ndn::Interest& interest);
-
-  void
-  onSyncRegisterFailed(const ndn::Name& prefix, const std::string& msg);
-
-  void
-  onSyncData(const ndn::Interest& interest, ndn::Data& data);
-
-  void
-  onSyncTimeout(const ndn::Interest& interest);
-
-  void
-  onSyncDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
-
-  void
-  onSyncDataValidated(const ndn::shared_ptr<const ndn::Data>& data);
-
-  void
-  processSyncInterest (const ndn::Name &name,
-                       DigestConstPtr digest, bool timedProcessing=false);
-
-  void
-  processSyncData (const ndn::Name &name,
-                   DigestConstPtr digest, const char *wireData, size_t len);
-
-  void
-  processSyncRecoveryInterest (const ndn::Name &name,
-                               DigestConstPtr digest);
-
-  void
-  insertToDiffLog (DiffStatePtr diff);
-
-  void
-  satisfyPendingSyncInterests (DiffStateConstPtr diff);
-
-  boost::tuple<DigestConstPtr, std::string>
-  convertNameToDigestAndType (const ndn::Name &name);
-
-  void
-  sendSyncInterest ();
-
-  void
-  sendSyncRecoveryInterests (DigestConstPtr digest);
-
-  void
-  sendSyncData (const ndn::Name &name,
-                DigestConstPtr digest, StateConstPtr state);
-
-  void
-  sendSyncData (const ndn::Name &name,
-                DigestConstPtr digest, SyncStateMsg &msg);
-
-  size_t
-  getNumberOfBranches () const;
-
-private:
-  FullStatePtr m_state;
-  DiffStateContainer m_log;
-
-  ndn::Name m_outstandingInterestName;
-  SyncInterestTable m_syncInterestTable;
-
-  ndn::Name m_syncPrefix;
-  ndn::IdentityCertificate m_myCertificate;
-  LogicUpdateCallback m_onUpdate;
-  LogicRemoveCallback m_onRemove;
-  LogicPerBranchCallback m_onUpdateBranch;
-  bool m_perBranch;
-  ndn::shared_ptr<ndn::Validator> m_validator;
-  ndn::KeyChain m_keyChain;
-  ndn::shared_ptr<ndn::Face> m_face;
-  const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;
-
-  ndn::Scheduler m_scheduler;
-
-  boost::mt19937 m_randomGenerator;
-  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_rangeUniformRandom;
-  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_reexpressionJitter;
-
-  static const int m_unknownDigestStoreTime = 10; // seconds
-  static const int m_syncResponseFreshness; // MUST BE dividable by 1000!!!
-  static const int m_syncInterestReexpress; // seconds
-
-  static const int m_defaultRecoveryRetransmitInterval = 200; // milliseconds
-  uint32_t m_recoveryRetransmissionInterval; // milliseconds
-
-  ndn::EventId m_delayedInterestProcessingId;
-  ndn::EventId m_reexpressingInterestId;
-  ndn::EventId m_reexpressingRecoveryInterestId;
-
-  std::string m_instanceId;
-  static int m_instanceCounter;
-};
-
-
-} // Sync
-
-#endif // SYNC_APP_WRAPPER_H
diff --git a/tests/unit-tests/test-data-fetch-and-publish.cpp.outdated b/tests/integrated-tests/test-data-fetch-and-publish.cpp.outdated
similarity index 100%
rename from tests/unit-tests/test-data-fetch-and-publish.cpp.outdated
rename to tests/integrated-tests/test-data-fetch-and-publish.cpp.outdated
diff --git a/tests/integrated-tests/test-logic.cpp b/tests/integrated-tests/test-logic.cpp
new file mode 100644
index 0000000..088b8fb
--- /dev/null
+++ b/tests/integrated-tests/test-logic.cpp
@@ -0,0 +1,307 @@
+/* -*- 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 "logic.hpp"
+
+#include "boost-test.hpp"
+
+namespace chronosync {
+namespace test {
+
+using std::vector;
+
+class Handler
+{
+public:
+  Handler(ndn::Face& face,
+          const Name& syncPrefix,
+          const Name& userPrefix)
+    : logic(face,
+            syncPrefix,
+            userPrefix,
+            bind(&Handler::onUpdate, this, _1))
+  {
+  }
+
+  void
+  onUpdate(const vector<MissingDataInfo>& v)
+  {
+    for (size_t i = 0; i < v.size(); i++) {
+      update(v[i].session, v[i].high, v[i].low);
+    }
+  }
+
+  void
+  update(const Name& p, const SeqNo& high, const SeqNo& low)
+  {
+    map[p] = high;
+  }
+
+  void
+  updateSeqNo(const SeqNo& seqNo)
+  {
+    logic.updateSeqNo(seqNo);
+  }
+
+  void
+  check(const Name& sessionName, const SeqNo& seqNo)
+  {
+    BOOST_CHECK_EQUAL(map[sessionName], seqNo);
+  }
+
+  Logic logic;
+  std::map<Name, SeqNo> map;
+};
+
+class LogicFixture
+{
+public:
+  LogicFixture()
+    : 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
+  createHandler(size_t idx)
+  {
+    handler[idx] = make_shared<Handler>(ref(*faces[idx]), syncPrefix, userPrefix[idx]);
+  }
+
+  void
+  updateSeqNo(size_t idx, const SeqNo& seqNo)
+  {
+    handler[idx]->updateSeqNo(seqNo);
+  }
+
+  void
+  checkSeqNo(size_t sIdx, size_t dIdx, const SeqNo& seqNo)
+  {
+    handler[sIdx]->check(handler[dIdx]->logic.getSessionName(), seqNo);
+  }
+
+  void
+  terminate()
+  {
+    io.stop();
+  }
+
+  Name syncPrefix;
+  Name userPrefix[3];
+
+  boost::asio::io_service io;
+  shared_ptr<ndn::Face> faces[3];
+  ndn::Scheduler scheduler;
+  shared_ptr<Handler> handler[3];
+};
+
+BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
+
+void
+onUpdate(const vector<MissingDataInfo>& v)
+{
+}
+
+BOOST_AUTO_TEST_CASE(Constructor)
+{
+  Name syncPrefix("/ndn/broadcast/sync");
+  Name userPrefix("/user");
+  ndn::Face face;
+  BOOST_REQUIRE_NO_THROW(Logic(face, syncPrefix, userPrefix,
+                               bind(onUpdate, _1)));
+}
+
+BOOST_AUTO_TEST_CASE(TwoBasic)
+{
+  scheduler.scheduleEvent(ndn::time::milliseconds(100),
+                          bind(&LogicFixture::createHandler, this, 0));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(200),
+                          bind(&LogicFixture::createHandler, this, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(300),
+                          bind(&LogicFixture::updateSeqNo, this, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1000),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1100),
+                          bind(&LogicFixture::updateSeqNo, this, 0, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1800),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 0, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1900),
+                          bind(&LogicFixture::updateSeqNo, this, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2600),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2800),
+                          bind(&LogicFixture::terminate, this));
+
+  io.run();
+}
+
+BOOST_AUTO_TEST_CASE(ThreeBasic)
+{
+  scheduler.scheduleEvent(ndn::time::milliseconds(100),
+                          bind(&LogicFixture::createHandler, this, 0));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(200),
+                          bind(&LogicFixture::createHandler, this, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(300),
+                          bind(&LogicFixture::createHandler, this, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(500),
+                          bind(&LogicFixture::updateSeqNo, this, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1400),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1450),
+                          bind(&LogicFixture::checkSeqNo, this, 2, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1500),
+                          bind(&LogicFixture::updateSeqNo, this, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2400),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2450),
+                          bind(&LogicFixture::checkSeqNo, this, 2, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2500),
+                          bind(&LogicFixture::updateSeqNo, this, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4400),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4450),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4500),
+                          bind(&LogicFixture::terminate, this));
+
+  io.run();
+}
+
+BOOST_AUTO_TEST_CASE(ResetRecover)
+{
+  scheduler.scheduleEvent(ndn::time::milliseconds(100),
+                          bind(&LogicFixture::createHandler, this, 0));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(200),
+                          bind(&LogicFixture::createHandler, this, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(500),
+                          bind(&LogicFixture::updateSeqNo, this, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1400),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1500),
+                          bind(&LogicFixture::updateSeqNo, this, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2400),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2500),
+                          bind(&LogicFixture::createHandler, this, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(3000),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(3050),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(3100),
+                          bind(&LogicFixture::updateSeqNo, this, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4000),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4050),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 2, 4));
+
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4500),
+                          bind(&LogicFixture::terminate, this));
+
+  io.run();
+}
+
+BOOST_AUTO_TEST_CASE(RecoverConflict)
+{
+  scheduler.scheduleEvent(ndn::time::milliseconds(0),
+                          bind(&LogicFixture::createHandler, this, 0));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(50),
+                          bind(&LogicFixture::createHandler, this, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(100),
+                          bind(&LogicFixture::createHandler, this, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(500),
+                          bind(&LogicFixture::updateSeqNo, this, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1400),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1400),
+                          bind(&LogicFixture::checkSeqNo, this, 2, 0, 1));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1500),
+                          bind(&LogicFixture::updateSeqNo, this, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(1500),
+                          bind(&LogicFixture::updateSeqNo, this, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2400),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2450),
+                          bind(&LogicFixture::checkSeqNo, this, 0, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2500),
+                          bind(&LogicFixture::checkSeqNo, this, 1, 2, 4));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(2550),
+                          bind(&LogicFixture::checkSeqNo, this, 2, 1, 2));
+
+  scheduler.scheduleEvent(ndn::time::milliseconds(4500),
+                          bind(&LogicFixture::terminate, this));
+
+  io.run();
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace chronosync
diff --git a/tests/unit-tests/test-socket.cpp.outdated b/tests/integrated-tests/test-socket.cpp.outdated
similarity index 100%
rename from tests/unit-tests/test-socket.cpp.outdated
rename to tests/integrated-tests/test-socket.cpp.outdated
diff --git a/tests/unit-tests/test-scheduler.cc.tmp b/tests/unit-tests/test-scheduler.cc.tmp
deleted file mode 100644
index 2a53a22..0000000
--- a/tests/unit-tests/test-scheduler.cc.tmp
+++ /dev/null
@@ -1,175 +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-scheduler.h"
-#include "sync-logic.h"
-
-using namespace Sync;
-using namespace std;
-using namespace boost;
-
-
-
-// void funcUpdate (const std::string &, const SeqNo &newSeq, const SeqNo &oldSeq)
-// {
-//   cout << "funcUpdate\n";
-// }
-
-// void funcRemove (const std::string &)
-// {
-//   cout << "funcRemove\n";
-// }
-
-enum SCHEDULE_LABELS
-  {
-    TEST_LABEL,
-    ANOTHER_LABEL
-  };
-
-struct SchedulerFixture
-{
-  SchedulerFixture ()
-    : counter (0)
-  {}
-
-  int counter;
-
-  Scheduler *scheduler;
-
-  void everySecond ()
-  {
-    // cout << "." << flush;
-    counter ++;
-
-    if (counter < 9)
-    scheduler->schedule (boost::posix_time::milliseconds (100),
-                         boost::bind (&SchedulerFixture::everySecond, this),
-                         TEST_LABEL);
-  }
-
-  void setCounterFive ()
-  {
-    counter = 5;
-  }
-
-  void setCounterThree ()
-  {
-    counter = 3;
-  }
-};
-
-
-#ifdef _DEBUG
-
-BOOST_FIXTURE_TEST_SUITE (SchedulerTestSuite, SchedulerFixture)
-
-BOOST_AUTO_TEST_CASE (BasicTest)
-{
-  BOOST_CHECK_NO_THROW (scheduler = new Scheduler ());
-
-  scheduler->schedule (posix_time::milliseconds (100),
-                       bind (&SchedulerFixture::everySecond, this),
-                       TEST_LABEL);
-
-  sleep (1);
-  // cout << counter << endl;
-  BOOST_CHECK_EQUAL (counter, 9); // generally, should be 9
-
-  scheduler->schedule (posix_time::seconds (2),
-		       bind (&SchedulerFixture::setCounterFive, this),
-                       TEST_LABEL);
-
-  this_thread::sleep (posix_time::milliseconds (400)); // just in case
-
-  scheduler->schedule (posix_time::milliseconds (600),
-		       bind (&SchedulerFixture::setCounterThree, this),
-                       TEST_LABEL);
-
-  this_thread::sleep (posix_time::milliseconds (500));
-  BOOST_CHECK_EQUAL (counter, 9); // still 9
-
-  this_thread::sleep (posix_time::milliseconds (200));
-  BOOST_CHECK_EQUAL (counter, 3);
-
-  this_thread::sleep (posix_time::milliseconds (1000));
-  BOOST_CHECK_EQUAL (counter, 5);
-
-  scheduler->schedule (posix_time::milliseconds (100),
-		       bind (&SchedulerFixture::setCounterThree, this),
-                       ANOTHER_LABEL);
-  this_thread::sleep (posix_time::milliseconds (50));
-  scheduler->cancel (ANOTHER_LABEL);
-  this_thread::sleep (posix_time::milliseconds (150));
-  BOOST_CHECK_EQUAL (counter, 5);
-
-  BOOST_CHECK_NO_THROW (delete scheduler);
-}
-
-BOOST_AUTO_TEST_SUITE_END ()
-
-
-void funcUpdate( const std::string &/*prefix*/, const SeqNo &/*newSeq*/, const SeqNo &/*oldSeq*/ )
-{
-}
-
-void funcPass( const std::vector<MissingDataInfo> &v)
-{
-}
-
-void funcRemove( const std::string &/*prefix*/ )
-{
-}
-
-BOOST_AUTO_TEST_CASE (SyncLogicSchedulerTest)
-{
-  SyncLogic *logic = 0;
-  BOOST_CHECK_NO_THROW (logic = new SyncLogic ("/prefix", funcPass, funcRemove));
-  this_thread::sleep (posix_time::milliseconds (100));
-
-  Scheduler &scheduler = logic->getScheduler ();
-  BOOST_CHECK_EQUAL (scheduler.getEventsSize (), 1);
-
-  BOOST_CHECK_NO_THROW (logic->respondSyncInterest ("/prefix/e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"));
-  BOOST_CHECK_EQUAL (scheduler.getEventsSize (), 2);
-
-  this_thread::sleep (posix_time::milliseconds (100)); // max waiting time
-  BOOST_CHECK_EQUAL (scheduler.getEventsSize (), 1);
-
-  BOOST_CHECK_NO_THROW (logic->respondSyncInterest ("/prefix/e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"));
-  BOOST_CHECK_NO_THROW (logic->respondSyncInterest ("/prefix/e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"));
-  BOOST_CHECK_NO_THROW (logic->respondSyncInterest ("/prefix/e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"));
-  BOOST_CHECK_NO_THROW (logic->respondSyncInterest ("/prefix/e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"));
-  BOOST_CHECK_EQUAL (scheduler.getEventsSize (), 5);
-
-  this_thread::sleep (posix_time::milliseconds (19)); // min waiting time is 20
-  BOOST_CHECK_EQUAL (scheduler.getEventsSize (), 5);
-
-  this_thread::sleep (posix_time::milliseconds (100)); // max waiting time
-  BOOST_CHECK_EQUAL (scheduler.getEventsSize (), 1);
-
-  BOOST_CHECK_NO_THROW (delete logic);
-}
-
-#endif
diff --git a/tests/unit-tests/test-sync-logic.cpp.outdated b/tests/unit-tests/test-sync-logic.cpp.outdated
deleted file mode 100644
index e916ad5..0000000
--- a/tests/unit-tests/test-sync-logic.cpp.outdated
+++ /dev/null
@@ -1,181 +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 <ndn-cxx/security/validator-null.hpp>
-#include "sync-logic.h"
-#include "sync-seq-no.h"
-
-using namespace std;
-using namespace boost;
-using namespace Sync;
-
-struct Handler
-{
-  string instance;
-
-  Handler (const string &_instance)
-  : instance (_instance)
-  {
-  }
-
-  void wrapper (const vector<MissingDataInfo> &v) {
-    int n = v.size();
-    for (int i = 0; i < n; i++) {
-      onUpdate (v[i].prefix, v[i].high, v[i].low);
-    }
-  }
-
-  void onUpdate (const string &p/*prefix*/, const SeqNo &seq/*newSeq*/, const SeqNo &oldSeq/*oldSeq*/)
-  {
-    m_map[p] = seq.getSeq ();
-
-    // cout << instance << "\t";
-    // if (!oldSeq.isValid ())
-    //   cout << "Inserted: " << p << " (" << seq << ")" << endl;
-    // else
-    //   cout << "Updated: " << p << "  ( " << oldSeq << ".." << seq << ")" << endl;
-  }
-
-  void onRemove (const string &p/*prefix*/)
-  {
-    // cout << instance << "\tRemoved: " << p << endl;
-    m_map.erase (p);
-  }
-
-  map<string, uint32_t> m_map;
-};
-
-class TestCore
-{
-public:
-  TestCore(ndn::shared_ptr<boost::asio::io_service> ioService)
-    : m_ioService(ioService)
-  {
-    m_l[0] = 0;
-    m_l[1] = 0;
-
-    m_validator = ndn::make_shared<ndn::ValidatorNull>();
-  }
-
-  ~TestCore()
-  {
-    if(m_l[0] != 0)
-      delete m_l[0];
-
-    if(m_l[1] != 0)
-      delete m_l[1];
-  }
-
-  void
-  finish(ndn::shared_ptr<boost::asio::io_service> ioService)
-  {
-    ioService->stop();
-  }
-
-  void
-  createSyncLogic(int index,
-                  ndn::shared_ptr<Handler> h)
-  {
-    ndn::Name identity("/tmp-" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
-    ndn::shared_ptr<ndn::IdentityCertificate> cert = m_keyChain.getCertificate(m_keyChain.createIdentity(identity));
-    m_faces[index] = ndn::make_shared<ndn::Face>(ndn::ref(*m_ioService));
-    m_l[index] = new SyncLogic(ndn::Name("/bcast"),
-                               *cert,
-                               m_validator, m_faces[index],
-                               bind (&Handler::wrapper, &*h, _1),
-                               bind (&Handler::onRemove, &*h, _1));
-  }
-
-  void
-  getOldDigestForOne()
-  {
-    m_oldDigest = m_l[0]->getRootDigest();
-  }
-
-  void
-  getNewDigestForOne()
-  {
-    m_newDigest = m_l[0]->getRootDigest();
-  }
-
-  void
-  addLocalNamesForOne(ndn::Name name, uint64_t session, uint64_t seq)
-  {
-    m_l[0]->addLocalNames(name, session, seq);
-  }
-
-  void
-  removeForOne(ndn::Name name)
-  {
-    m_l[0]->remove(name);
-  }
-
-  void
-  checkDigest()
-  {
-    BOOST_CHECK(m_oldDigest != m_newDigest);
-  }
-
-
-public:
-  ndn::KeyChain m_keyChain;
-  ndn::shared_ptr<boost::asio::io_service> m_ioService;
-  SyncLogic* m_l[2];
-  ndn::shared_ptr<ndn::Face> m_faces[2];
-  ndn::shared_ptr<ndn::ValidatorNull> m_validator;
-  string m_oldDigest;
-  string m_newDigest;
-};
-
-void
-checkMapSize(ndn::shared_ptr<Handler> h, int size)
-{ BOOST_CHECK_EQUAL (h->m_map.size (), size); }
-
-
-BOOST_AUTO_TEST_CASE (SyncLogicTest)
-{
-  ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
-  ndn::Scheduler scheduler(*ioService);
-  TestCore testCore(ioService);
-
-  ndn::shared_ptr<Handler> h1 = ndn::make_shared<Handler>("1");
-  ndn::shared_ptr<Handler> h2 = ndn::make_shared<Handler>("2");
-
-  scheduler.scheduleEvent(ndn::time::milliseconds(0), ndn::bind(&TestCore::createSyncLogic, &testCore, 0, h1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(100), ndn::bind(&TestCore::getOldDigestForOne, &testCore));
-  scheduler.scheduleEvent(ndn::time::milliseconds(200), ndn::bind(&TestCore::addLocalNamesForOne, &testCore, "/one", 1, 2));
-  scheduler.scheduleEvent(ndn::time::milliseconds(300), ndn::bind(&checkMapSize, h1, 0));
-  scheduler.scheduleEvent(ndn::time::milliseconds(400), ndn::bind(&TestCore::createSyncLogic, &testCore, 1, h2));
-  scheduler.scheduleEvent(ndn::time::milliseconds(500), ndn::bind(&checkMapSize, h1, 0));
-  scheduler.scheduleEvent(ndn::time::milliseconds(600), ndn::bind(&checkMapSize, h2, 1));
-  scheduler.scheduleEvent(ndn::time::milliseconds(700), ndn::bind(&TestCore::removeForOne, &testCore, "/one"));
-  scheduler.scheduleEvent(ndn::time::milliseconds(800), ndn::bind(&TestCore::getNewDigestForOne, &testCore));
-  scheduler.scheduleEvent(ndn::time::milliseconds(900), ndn::bind(&TestCore::checkDigest, &testCore));
-  scheduler.scheduleEvent(ndn::time::milliseconds(1000), ndn::bind(&TestCore::finish, &testCore, ioService));
-
-  ioService->run();
-
-}
diff --git a/tests/wscript b/tests/wscript
index d1a61ba..384dbba 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -4,9 +4,9 @@
 top = '..'
 
 def build(bld):
-    unit_test_main = bld(
-        target='unit-tests-main',
-        name='unit-tests-main',
+    test_main = bld(
+        target='tests-main',
+        name='tests-main',
         features='cxx',
         source=bld.path.ant_glob(['main.cpp']),
         use='ChronoSync',
@@ -16,7 +16,16 @@
         target="../unit-tests",
         source=bld.path.ant_glob(['unit-tests/**/*.cpp']),
         features=['cxx', 'cxxprogram'],
-        use='ChronoSync, unit-tests-main',
+        use='ChronoSync tests-main LOG4CXX',
+        includes=['.'],
+        install_path=None,
+        )
+
+    integrated_test = bld.program(
+        target="../integrated-tests",
+        source=bld.path.ant_glob(['integrated-tests/**/*.cpp']),
+        features=['cxx', 'cxxprogram'],
+        use='ChronoSync tests-main',
         includes=['.'],
         install_path=None,
         )
diff --git a/wscript b/wscript
index 0f0ea36..025e481 100644
--- a/wscript
+++ b/wscript
@@ -48,7 +48,7 @@
         # vnum = "1.0.0",
         features=['cxx', 'cxxshlib'],
         source =  bld.path.ant_glob(['src/**/*.cpp', 'src/**/*.proto']),
-        use = 'BOOST NDN_CXX',
+        use = 'BOOST NDN_CXX LOG4CXX',
         includes = ['src', '.'],
         export_includes=['src', '.'],
         )
@@ -57,23 +57,18 @@
     if bld.env["_TESTS"]:
         bld.recurse('tests')
 
-    if bld.get_define("HAVE_LOG4CXX"):
-        libsync.use += ' LOG4CXX'
-        if bld.env["_TESTS"]:
-            unittests.use += ' LOG4CXX'
-
     bld.install_files(
         dest = "%s/ChronoSync" % bld.env['INCLUDEDIR'],
-        files = bld.path.ant_glob(['src/**/*.h']),
+        files = bld.path.ant_glob(['src/**/*.hpp', 'src/**/*.h', 'common.hpp']),
         cwd = bld.path.find_dir("src"),
-        relative_trick = True,
+        relative_trick = False,
         )
 
     bld.install_files(
         dest = "%s/ChronoSync" % bld.env['INCLUDEDIR'],
-        files = bld.path.get_bld().ant_glob(['src/**/*.h']),
+        files = bld.path.get_bld().ant_glob(['src/**/*.hpp', 'src/**/*.h', 'common.hpp', 'config.hpp']),
         cwd = bld.path.get_bld().find_dir("src"),
-        relative_trick = True,
+        relative_trick = False,
         )
 
     pc = bld(
