diff --git a/src/communication/data-manager.cpp b/src/communication/data-manager.cpp
deleted file mode 100644
index 3a153a3..0000000
--- a/src/communication/data-manager.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-#include <iostream>
-#include <cstdlib>
-
-#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
-#include <ndn-cxx/security/identity-certificate.hpp>
-#include <ndn-cxx/util/io.hpp>
-
-#include "nlsr.hpp"
-#include "data-manager.hpp"
-#include "utility/tokenizer.hpp"
-#include "lsdb.hpp"
-// #include "security/key-manager.hpp"
-
-namespace nlsr {
-
-using namespace std;
-using namespace ndn;
-
-void
-DataManager::processContent(const ndn::Interest& interest,
-                            const ndn::Data& data, InterestManager& im)
-{
-  std::cout << "I: " << interest.toUri() << std::endl;
-  string dataName(data.getName().toUri());
-  Tokenizer nt(dataName, "/");
-  std::string chkString("keys");
-  if (nt.doesTokenExist(chkString))
-  {
-    processContentKeys(data);
-  }
-  else
-  {
-    // if (m_nlsr.getKeyManager().verify(data))
-    {
-      std::cout << "Verified Data Content" << std::endl;
-      chkString = "info";
-      if (nt.doesTokenExist(chkString))
-      {
-        string dataContent((char*)data.getContent().value());
-        processContentInfo(dataName, dataContent);
-      }
-      chkString = "LSA";
-      if (nt.doesTokenExist(chkString))
-      {
-        string dataContent((char*)data.getContent().value());
-        processContentLsa(dataName, dataContent);
-      }
-    }
-    // else
-    // {
-    //   std::cout << "Unverified Data Content. Discarded" << std::endl;
-    // }
-  }
-}
-
-void
-DataManager::processContentInfo(const string& dataName,
-                                string& dataContent)
-{
-  Tokenizer nt(dataName, "/");
-  string chkString("info");
-  string neighbor = nt.getTokenString(0, nt.getTokenPosition(chkString) - 1);
-  int oldStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
-  int infoIntTimedOutCount = m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
-  //debugging purpose start
-  std::cout << "Before Updates: " << std::endl;
-  std::cout << "Neighbor : " << neighbor << std::endl;
-  std::cout << "Status: " << oldStatus << std::endl;
-  std::cout << "Info Interest Timed out: " << infoIntTimedOutCount << std::endl;
-  //debugging purpose end
-  m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, 1);
-  m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
-  int newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
-  infoIntTimedOutCount = m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
-  //debugging purpose
-  std::cout << "After Updates: " << std::endl;
-  std::cout << "Neighbor : " << neighbor << std::endl;
-  std::cout << "Status: " << newStatus << std::endl;
-  std::cout << "Info Interest Timed out: " << infoIntTimedOutCount << std::endl;
-  //debugging purpose end
-  if ((oldStatus - newStatus) != 0)  // change in Adjacency list
-  {
-    m_nlsr.incrementAdjBuildCount();
-    /* Need to schedule event for Adjacency LSA building */
-    if (m_nlsr.getIsBuildAdjLsaSheduled() == 0)
-    {
-      m_nlsr.setIsBuildAdjLsaSheduled(1);
-      // event here
-      m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
-                                          ndn::bind(&Lsdb::scheduledAdjLsaBuild, m_nlsr.getLsdb(),
-                                                    boost::ref(m_nlsr)));
-    }
-  }
-}
-
-void
-DataManager::processContentLsa(const string& dataName, string& dataContent)
-{
-  Tokenizer nt(dataName, "/");
-  string chkString("LSA");
-  string origRouter = nt.getTokenString(nt.getTokenPosition(chkString) + 1,
-                                        nt.getTokenNumber() - 4);
-  string lsTypeString = nt.getToken(nt.getTokenNumber() - 3);
-  string lsSeNoString = nt.getToken(nt.getTokenNumber() - 2);
-  uint32_t interestedLsSeqNo;
-  try
-  {
-    interestedLsSeqNo = boost::lexical_cast<uint32_t>(lsSeNoString);
-  }
-  catch (std::exception& e)
-  {
-    return;
-  }
-  if (lsTypeString == "1")  //Name Lsa
-  {
-    processContentNameLsa(origRouter + "/" + lsTypeString,
-                          interestedLsSeqNo, dataContent);
-  }
-  else if (lsTypeString == "2")  //Adj Lsa
-  {
-    processContentAdjLsa(origRouter + "/" + lsTypeString,
-                         interestedLsSeqNo, dataContent);
-  }
-  else if (lsTypeString == "3")  //Cor Lsa
-  {
-    processContentCorLsa(origRouter + "/" + lsTypeString,
-                         interestedLsSeqNo, dataContent);
-  }
-  else
-  {
-    cout << "Unrecognized LSA Type :(" << endl;
-  }
-}
-
-void
-DataManager::processContentNameLsa(const string& lsaKey,
-                                   uint32_t lsSeqNo, string& dataContent)
-{
-  if (m_nlsr.getLsdb().isNameLsaNew(lsaKey, lsSeqNo))
-  {
-    NameLsa nameLsa;
-    if (nameLsa.initializeFromContent(dataContent))
-    {
-      m_nlsr.getLsdb().installNameLsa(m_nlsr, nameLsa);
-    }
-    else
-    {
-      std::cout << "LSA data decoding error :(" << std::endl;
-    }
-  }
-}
-
-void
-DataManager::processContentAdjLsa(const string& lsaKey,
-                                  uint32_t lsSeqNo, string& dataContent)
-{
-  if (m_nlsr.getLsdb().isAdjLsaNew(lsaKey, lsSeqNo))
-  {
-    AdjLsa adjLsa;
-    if (adjLsa.initializeFromContent(dataContent))
-    {
-      m_nlsr.getLsdb().installAdjLsa(m_nlsr, adjLsa);
-    }
-    else
-    {
-      std::cout << "LSA data decoding error :(" << std::endl;
-    }
-  }
-}
-
-void
-DataManager::processContentCorLsa(const string& lsaKey,
-                                  uint32_t lsSeqNo, string& dataContent)
-{
-  if (m_nlsr.getLsdb().isCoordinateLsaNew(lsaKey, lsSeqNo))
-  {
-    CoordinateLsa corLsa;
-    if (corLsa.initializeFromContent(dataContent))
-    {
-      m_nlsr.getLsdb().installCoordinateLsa(m_nlsr, corLsa);
-    }
-    else
-    {
-      std::cout << "LSA data decoding error :(" << std::endl;
-    }
-  }
-}
-
-void
-DataManager::processContentKeys(const ndn::Data& data)
-{
-  std::cout << " processContentKeys called " << std::endl;
-  ndn::shared_ptr<ndn::IdentityCertificate> cert =
-    ndn::make_shared<ndn::IdentityCertificate>();
-  cert->wireDecode(data.getContent().blockFromValue());
-  std::cout << *(cert) << std::endl;
-  std::string dataName = data.getName().toUri();
-  Tokenizer nt(dataName, "/");
-  std::string certName = nt.getTokenString(0, nt.getTokenNumber() - 3);
-  uint32_t seqNum = boost::lexical_cast<uint32_t>(nt.getToken(
-                                                    nt.getTokenNumber() - 2));
-  std::cout << "Cert Name: " << certName << " Seq Num: " << seqNum << std::endl;
-  // if (m_nlsr.getKeyManager().verify(m_nlsr, *(cert)))
-  // {
-  //   m_nlsr.getKeyManager().addCertificate(cert, seqNum, true);
-  // }
-  // else
-  // {
-  //   m_nlsr.getKeyManager().addCertificate(cert, seqNum, false);
-  // }
-  // m_nlsr.getKeyManager().printCertStore();
-}
-}//namespace nlsr
diff --git a/src/communication/data-manager.hpp b/src/communication/data-manager.hpp
deleted file mode 100644
index ce10b88..0000000
--- a/src/communication/data-manager.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef NLSR_DATA_MANAGER_HPP
-#define NLSR_DATA_MANAGER_HPP
-
-#include <boost/cstdint.hpp>
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-
-#include "interest-manager.hpp"
-
-namespace nlsr {
-class Nlsr;
-
-class DataManager
-{
-public:
-  DataManager(Nlsr& nlsr)
-    : m_nlsr(nlsr)
-  {}
-  void
-  processContent(const ndn::Interest& interest,
-                 const ndn::Data& data, InterestManager& im);
-private:
-  void
-  processContentInfo(const std::string& dataName,
-                     std::string& dataContent);
-
-  void
-  processContentLsa(const std::string& dataName, std::string& dataContent);
-
-  void
-  processContentNameLsa(const std::string& lsaKey,
-                        uint32_t lsSeqNo, std::string& dataContent);
-
-  void
-  processContentAdjLsa(const std::string& lsaKey,
-                       uint32_t lsSeqNo, std::string& dataContent);
-
-  void
-  processContentCorLsa(const std::string& lsaKey,
-                       uint32_t lsSeqNo, std::string& dataContent);
-
-  void
-  processContentKeys(const ndn::Data& data);
-
-private:
-  Nlsr& m_nlsr;
-
-
-};
-
-}//namespace nlsr
-
-#endif //NLSR_DATA_MANAGER_HPP
diff --git a/src/communication/interest-manager.cpp b/src/communication/interest-manager.cpp
deleted file mode 100644
index 23ce579..0000000
--- a/src/communication/interest-manager.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-#include <iostream>
-#include <cstdlib>
-
-#include <ndn-cxx/security/identity-certificate.hpp>
-#include <ndn-cxx/util/io.hpp>
-
-#include "nlsr.hpp"
-#include "interest-manager.hpp"
-#include "data-manager.hpp"
-#include "utility/tokenizer.hpp"
-#include "lsdb.hpp"
-
-namespace nlsr {
-
-using namespace std;
-using namespace ndn;
-
-void
-InterestManager::processInterest(const ndn::Name& name,
-                                 const ndn::Interest& interest)
-{
-  cout << "<< I: " << interest << endl;
-  string intName = interest.getName().toUri();
-  cout << "Interest Received for Name: " << intName << endl;
-  Tokenizer nt(intName, "/");
-  string chkString("info");
-  if (nt.doesTokenExist(chkString))
-  {
-    string nbr = nt.getTokenString(nt.getTokenPosition(chkString) + 1);
-    cout << "Neighbor: " << nbr << endl;
-    processInterestInfo(nbr, interest);
-  }
-  chkString = "LSA";
-  if (nt.doesTokenExist(chkString))
-  {
-    processInterestLsa(interest);
-  }
-  chkString = "keys";
-  if (nt.doesTokenExist(chkString))
-  {
-    processInterestKeys(interest);
-  }
-}
-
-void
-InterestManager::processInterestInfo(const string& neighbor,
-                                     const ndn::Interest& interest)
-{
-  if (m_nlsr.getAdjacencyList().isNeighbor(neighbor))
-  {
-    Data data(ndn::Name(interest.getName()).appendVersion());
-    data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-    data.setContent((const uint8_t*)"info", sizeof("info"));
-    // m_nlsr.getKeyManager().signData(data);
-    m_keyChain.sign(data);
-    cout << ">> D: " << data << endl;
-    m_nlsr.getNlsrFace().put(data);
-    int status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
-    if (status == 0)
-    {
-      string intName = neighbor + "/" + "info" +
-                       m_nlsr.getConfParameter().getRouterPrefix();
-      expressInterest(intName, 2,
-                      m_nlsr.getConfParameter().getInterestResendTime());
-    }
-  }
-}
-
-void
-InterestManager::processInterestLsa(const ndn::Interest& interest)
-{
-  string intName = interest.getName().toUri();
-  Tokenizer nt(intName, "/");
-  string chkString("LSA");
-  string origRouter = nt.getTokenString(nt.getTokenPosition(chkString) + 1,
-                                        nt.getTokenNumber() - 3);
-  string lsTypeString = nt.getToken(nt.getTokenNumber() - 2);
-  string lsSeqString = nt.getToken(nt.getTokenNumber() - 1);
-  std::cout << "Router Name: " << origRouter << std::endl;
-  std::cout << "Ls Type    : " << lsTypeString << std::endl;
-  std::cout << "Ls Seq     : " << lsSeqString << endl;
-  uint8_t interestedLsType;
-  uint32_t interestedLsSeqNo;
-  try
-  {
-    interestedLsType = boost::lexical_cast<uint8_t>(lsTypeString);
-    interestedLsSeqNo = boost::lexical_cast<uint32_t>(lsSeqString);
-  }
-  catch (std::exception& e)
-  {
-    return;
-  }
-  std::cout << "Ls Type: " << interestedLsType << std::endl;
-  if (lsTypeString == "1") //Name Lsa
-  {
-    processInterestForNameLsa(interest,
-                              origRouter + "/" + lsTypeString, interestedLsSeqNo);
-  }
-  else if (lsTypeString == "2") //Adj Lsa
-  {
-    processInterestForAdjLsa(interest,
-                             origRouter + "/" + lsTypeString, interestedLsSeqNo);
-  }
-  else if (lsTypeString == "3") //Cor Lsa
-  {
-    processInterestForCorLsa(interest,
-                             origRouter + "/" + lsTypeString, interestedLsSeqNo);
-  }
-  else
-  {
-    cout << "Unrecognized LSA Type :(" << endl;
-  }
-}
-
-void
-InterestManager::processInterestForNameLsa(const ndn::Interest& interest,
-                                           const string& lsaKey, uint32_t interestedlsSeqNo)
-{
-  NameLsa*  nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
-  if (nameLsa != 0)
-  {
-    if (nameLsa->getLsSeqNo() >= interestedlsSeqNo)
-    {
-      Data data(ndn::Name(interest.getName()).appendVersion());
-      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-      string content = nameLsa->getData();
-      data.setContent((const uint8_t*)content.c_str(), content.size());
-      // m_nlsr.getKeyManager().signData(data);
-      m_keyChain.sign(data);
-      std::cout << ">> D: " << data << std::endl;
-      m_nlsr.getNlsrFace().put(data);
-    }
-  }
-}
-
-void
-InterestManager::processInterestForAdjLsa(const ndn::Interest& interest,
-                                          const string& lsaKey, uint32_t interestedlsSeqNo)
-{
-  AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
-  if (adjLsa != 0)
-  {
-    if (adjLsa->getLsSeqNo() >= interestedlsSeqNo)
-    {
-      Data data(ndn::Name(interest.getName()).appendVersion());
-      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-      string content = adjLsa->getData();
-      data.setContent((const uint8_t*)content.c_str(), content.size());
-      // m_nlsr.getKeyManager().signData(data);
-      m_keyChain.sign(data);
-      std::cout << ">> D: " << data << std::endl;
-      m_nlsr.getNlsrFace().put(data);
-    }
-  }
-}
-
-void
-InterestManager::processInterestForCorLsa(const ndn::Interest& interest,
-                                          const string& lsaKey, uint32_t interestedlsSeqNo)
-{
-  CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
-  if (corLsa != 0)
-  {
-    if (corLsa->getLsSeqNo() >= interestedlsSeqNo)
-    {
-      Data data(ndn::Name(interest.getName()).appendVersion());
-      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-      string content = corLsa->getData();
-      data.setContent((const uint8_t*)content.c_str(), content.size());
-      // m_nlsr.getKeyManager().signData(data);
-      m_keyChain.sign(data);
-      std::cout << ">> D: " << data << std::endl;
-      m_nlsr.getNlsrFace().put(data);
-    }
-  }
-}
-
-void
-InterestManager::processInterestKeys(const ndn::Interest& interest)
-{
-  std::cout << "processInterestKeys called " << std::endl;
-  // string intName = interest.getName().toUri();
-  // std::cout << "Interest Name for Key: " << intName << std::endl;
-  // Tokenizer nt(intName, "/");
-  // std::string chkString("ID-CERT");
-  // std::string certName;
-  // uint32_t seqNum;
-  // ndn::Name dataName;
-  // std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert;
-  // if (nt.getTokenPosition(chkString) == nt.getTokenNumber() - 1)
-  // {
-  //   certName = nt.getTokenString(0, nt.getTokenNumber() - 1);
-  //   cout << "Cert Name: " << certName << std::endl;
-  //   chkCert = m_nlsr.getKeyManager().getCertificateFromStore(certName);
-  // }
-  // else
-  // {
-  //   certName = nt.getTokenString(0, nt.getTokenNumber() - 2);
-  //   seqNum = boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber() - 1));
-  //   std::cout << "Cert Name: " << certName << " Seq Num: " << seqNum << std::endl;
-  //   chkCert = m_nlsr.getKeyManager().getCertificateFromStore(certName, seqNum);
-  // }
-  // if (chkCert.second)
-  // {
-  //   if (nt.getTokenPosition(chkString) == nt.getTokenNumber() - 1)
-  //   {
-  //     std::string dn;
-  //     dataName = ndn::Name(interest.getName()).appendVersion();
-  //     std::pair<uint32_t, bool> seqChk =
-  //       m_nlsr.getKeyManager().getCertificateSeqNum(certName);
-  //     if (seqChk.second)
-  //     {
-  //       dn = dataName.toUri() + "/" + boost::lexical_cast<std::string>(seqChk.first);
-  //       dataName = ndn::Name(dn);
-  //     }
-  //     else
-  //     {
-  //       dn = dataName.toUri() + "/" + boost::lexical_cast<std::string>(10);
-  //       dataName = ndn::Name(dn);
-  //     }
-  //   }
-  //   else
-  //   {
-  //     dataName = ndn::Name(interest.getName());
-  //   }
-  //   Data data(dataName.appendVersion());
-  //   data.setFreshnessPeriod(time::seconds(10)); //10 sec
-  //   data.setContent(chkCert.first->wireEncode());
-  //   m_nlsr.getKeyManager().signData(data);
-  //   m_nlsr.getNlsrFace()->put(data);
-  // }
-}
-
-
-void
-InterestManager::processInterestTimedOut(const ndn::Interest& interest)
-{
-  std::cout << "Timed out interest : " << interest.getName().toUri() << std::endl;
-  string intName = interest.getName().toUri();
-  Tokenizer nt(intName, "/");
-  string chkString("info");
-  if (nt.doesTokenExist(chkString))
-  {
-    string nbr = nt.getTokenString(0, nt.getTokenPosition(chkString) - 1);
-    processInterestTimedOutInfo(nbr , interest);
-  }
-  chkString = "LSA";
-  if (nt.doesTokenExist(chkString))
-  {
-    processInterestTimedOutLsa(interest);
-  }
-}
-
-void
-InterestManager::processInterestTimedOutInfo(const string& neighbor,
-                                             const ndn::Interest& interest)
-{
-  m_nlsr.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
-  int status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
-  uint32_t infoIntTimedOutCount = m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
-  std::cout << "Neighbor: " << neighbor << std::endl;
-  std::cout << "Status: " << status << std::endl;
-  std::cout << "Info Interest Timed out: " << infoIntTimedOutCount << std::endl;
-  if ((infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber()))
-  {
-    string intName = neighbor + "/" + "info" +
-                     m_nlsr.getConfParameter().getRouterPrefix();
-    expressInterest(intName, 2,
-                    m_nlsr.getConfParameter().getInterestResendTime());
-  }
-  else if ((status == 1) &&
-           (infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber()))
-  {
-    m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, 0);
-    m_nlsr.incrementAdjBuildCount();
-    if (m_nlsr.getIsBuildAdjLsaSheduled() == 0)
-    {
-      m_nlsr.setIsBuildAdjLsaSheduled(1);
-      // event here
-      m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
-                                          ndn::bind(&Lsdb::scheduledAdjLsaBuild,
-                                                    &m_nlsr.getLsdb(),
-                                                    boost::ref(m_nlsr)));
-    }
-  }
-}
-
-void
-InterestManager::processInterestTimedOutLsa(const ndn::Interest& interest)
-{
-}
-
-void
-InterestManager::expressInterest(const string& interestNamePrefix,
-                                 int32_t scope, int32_t seconds)
-{
-  std::cout << "Expressing Interest :" << interestNamePrefix << std::endl;
-  ndn::Interest i((ndn::Name(interestNamePrefix)));
-  i.setInterestLifetime(time::seconds(seconds));
-  i.setMustBeFresh(true);
-  m_nlsr.getNlsrFace().expressInterest(i,
-                                       ndn::bind(&DataManager::processContent,
-                                                 &m_nlsr.getDataManager(),
-                                                 _1, _2, boost::ref(*this)),
-                                       ndn::bind(&InterestManager::processInterestTimedOut,
-                                                 this, _1));
-}
-
-
-void
-InterestManager::sendScheduledInfoInterest(int32_t seconds)
-{
-  std::list<Adjacent> adjList = m_nlsr.getAdjacencyList().getAdjList();
-  for (std::list<Adjacent>::iterator it = adjList.begin(); it != adjList.end();
-       ++it)
-  {
-    string adjName = (*it).getName() + "/" + "info" +
-                     m_nlsr.getConfParameter().getRouterPrefix();
-    expressInterest(adjName, 2,
-                    m_nlsr.getConfParameter().getInterestResendTime());
-  }
-  scheduleInfoInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
-}
-
-void
-InterestManager::scheduleInfoInterest(int32_t seconds)
-{
-  EventId eid = m_nlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
-                                                    ndn::bind(&InterestManager::sendScheduledInfoInterest, this,
-                                                              seconds));
-}
-
-
-} //namespace nlsr
diff --git a/src/communication/interest-manager.hpp b/src/communication/interest-manager.hpp
deleted file mode 100644
index 00c798b..0000000
--- a/src/communication/interest-manager.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef NLSR_INTEREST_MANAGER_HPP
-#define NLSR_INTEREST_MANAGER_HPP
-
-#include <boost/cstdint.hpp>
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-
-namespace nlsr {
-
-class Nlsr;
-
-class InterestManager
-{
-public:
-  InterestManager(Nlsr& nlsr)
-    : m_nlsr(nlsr)
-  {
-  }
-  void
-  processInterest(const ndn::Name& name, const ndn::Interest& interest);
-
-  void
-  processInterestInfo(const std::string& neighbor, const ndn::Interest& interest);
-
-  void
-  processInterestLsa(const ndn::Interest& interest);
-
-  void
-  processInterestForNameLsa(const ndn::Interest& interest,
-                            const std::string& lsaKey, uint32_t interestedlsSeqNo);
-
-  void
-  processInterestForAdjLsa(const ndn::Interest& interest,
-                           const std::string& lsaKey, uint32_t interestedlsSeqNo);
-
-  void
-  processInterestForCorLsa(const ndn::Interest& interest,
-                           const std::string& lsaKey, uint32_t interestedlsSeqNo);
-
-  void
-  processInterestKeys(const ndn::Interest& interest);
-
-  void
-  processInterestTimedOut(const ndn::Interest& interest);
-
-  void
-  processInterestTimedOutInfo(const std::string& neighbor,
-                              const ndn::Interest& interest);
-
-  void
-  processInterestTimedOutLsa(const ndn::Interest& interest);
-
-  void
-  expressInterest(const std::string& interestNamePrefix, int32_t scope, int32_t seconds);
-
-  void
-  sendScheduledInfoInterest(int32_t seconds);
-
-  void
-  scheduleInfoInterest(int32_t seconds);
-
-private:
-  Nlsr& m_nlsr;
-
-  ndn::KeyChain m_keyChain;
-};
-
-}//namespace nlsr
-
-#endif //NLSR_INTEREST_MANAGER_HPP
diff --git a/src/communication/sync-logic-handler.cpp b/src/communication/sync-logic-handler.cpp
index c8b5ec9..10a40ec 100644
--- a/src/communication/sync-logic-handler.cpp
+++ b/src/communication/sync-logic-handler.cpp
@@ -1,7 +1,7 @@
 #include "nlsr.hpp"
 #include "sync-logic-handler.hpp"
-// #include "security/key-manager.hpp"
-#include "utility/tokenizer.hpp"
+#include "utility/name-helper.hpp"
+#include "lsa.hpp"
 
 
 namespace nlsr {
@@ -13,7 +13,7 @@
 SyncLogicHandler::createSyncSocket(Nlsr& pnlsr)
 {
   std::cout << "Creating Sync socket ......" << std::endl;
-  std::cout << "Sync prefix: " << m_syncPrefix.toUri() << std::endl;
+  std::cout << "Sync prefix: " << m_syncPrefix << std::endl;
   m_syncSocket = make_shared<Sync::SyncSocket>(m_syncPrefix, m_validator,
                                                m_syncFace,
                                                bind(&SyncLogicHandler::nsyncUpdateCallBack, this,
@@ -43,116 +43,97 @@
 }
 
 void
-SyncLogicHandler::removeRouterFromSyncing(const string& routerPrefix)
+SyncLogicHandler::removeRouterFromSyncing(const ndn::Name& routerPrefix)
 {
 }
 
 void
-SyncLogicHandler::processUpdateFromSync(const std::string& updateName,
+SyncLogicHandler::processUpdateFromSync(const ndn::Name& updateName,
                                         uint64_t seqNo,  Nlsr& pnlsr)
 {
-  Tokenizer nt(updateName, "/");
+  //const ndn::Name name(updateName);
   string chkString("LSA");
-  if (nt.doesTokenExist(chkString))
+  int32_t lasPosition = util::getNameComponentPosition(updateName, chkString);
+  if (lasPosition >= 0)
   {
-    //process LSA Update here
-    string routerName = nt.getTokenString(nt.getTokenPosition(chkString) + 1);
+    ndn::Name routerName = updateName.getSubName(lasPosition + 1);
     processRoutingUpdateFromSync(routerName, seqNo, pnlsr);
-  }
-  chkString = "keys";
-  if (nt.doesTokenExist(chkString))
-  {
-    //process keys update here
-    std::string certName = nt.getTokenString(0);
-    // processKeysUpdateFromSync(certName, seqNo, pnlsr);
+    return;
   }
 }
 
 void
-SyncLogicHandler::processRoutingUpdateFromSync(const std::string& routerName,
+SyncLogicHandler::processRoutingUpdateFromSync(const ndn::Name& routerName,
                                                uint64_t seqNo,  Nlsr& pnlsr)
 {
+  ndn::Name rName = routerName;
   if (routerName != pnlsr.getConfParameter().getRouterPrefix())
   {
     SequencingManager sm(seqNo);
     std::cout << sm;
     std::cout << "Router Name: " << routerName << endl;
-    if (pnlsr.getLsdb().isNameLsaNew(routerName + "/1", sm.getNameLsaSeq()))
+    try
     {
-      std::cout << "Updated Name LSA. Need to fetch it" << std::endl;
-      string lsaPrefix =
-        pnlsr.getConfParameter().getChronosyncLsaPrefix() +
-        routerName + "/1/" +
-        boost::lexical_cast<std::string>(sm.getNameLsaSeq());
-      pnlsr.getInterestManager().expressInterest(lsaPrefix, 3,
-                                                 pnlsr.getConfParameter().getInterestResendTime());
+      if (pnlsr.getLsdb().isNameLsaNew(rName.append("name"), sm.getNameLsaSeq()))
+      {
+        std::cout << "Updated Name LSA. Need to fetch it" << std::endl;
+        ndn::Name interestName(pnlsr.getConfParameter().getChronosyncLsaPrefix());
+        interestName.append(routerName);
+        interestName.append("name");
+        interestName.appendNumber(sm.getNameLsaSeq());
+        pnlsr.getLsdb().expressInterest(interestName,
+                                        pnlsr.getConfParameter().getInterestResendTime());
+      }
+      if (pnlsr.getLsdb().isAdjLsaNew(rName.append("adjacency"),
+                                      sm.getAdjLsaSeq()))
+      {
+        std::cout << "Updated Adj LSA. Need to fetch it" << std::endl;
+        ndn::Name interestName(pnlsr.getConfParameter().getChronosyncLsaPrefix());
+        interestName.append(routerName);
+        interestName.append("adjacency");
+        interestName.appendNumber(sm.getAdjLsaSeq());
+        pnlsr.getLsdb().expressInterest(interestName,
+                                        pnlsr.getConfParameter().getInterestResendTime());
+      }
+      if (pnlsr.getLsdb().isCoordinateLsaNew(rName.append("coordinate"),
+                                             sm.getCorLsaSeq()))
+      {
+        std::cout << "Updated Cor LSA. Need to fetch it" << std::endl;
+        ndn::Name interestName(pnlsr.getConfParameter().getChronosyncLsaPrefix());
+        interestName.append(routerName);
+        interestName.append("coordinate");
+        interestName.appendNumber(sm.getCorLsaSeq());
+        pnlsr.getLsdb().expressInterest(interestName,
+                                        pnlsr.getConfParameter().getInterestResendTime());
+      }
     }
-    if (pnlsr.getLsdb().isAdjLsaNew(routerName + "/2", sm.getAdjLsaSeq()))
+    catch (std::exception& e)
     {
-      std::cout << "Updated Adj LSA. Need to fetch it" << std::endl;
-      string lsaPrefix =
-        pnlsr.getConfParameter().getChronosyncLsaPrefix() +
-        routerName + "/2/" +
-        boost::lexical_cast<std::string>(sm.getAdjLsaSeq());
-      pnlsr.getInterestManager().expressInterest(lsaPrefix, 3,
-                                                 pnlsr.getConfParameter().getInterestResendTime());
-    }
-    if (pnlsr.getLsdb().isCoordinateLsaNew(routerName + "/3", sm.getCorLsaSeq()))
-    {
-      std::cout << "Updated Cor LSA. Need to fetch it" << std::endl;
-      string lsaPrefix =
-        pnlsr.getConfParameter().getChronosyncLsaPrefix() +
-        routerName + "/3/" +
-        boost::lexical_cast<std::string>(sm.getCorLsaSeq());
-      pnlsr.getInterestManager().expressInterest(lsaPrefix, 3,
-                                                 pnlsr.getConfParameter().getInterestResendTime());
+      std::cerr << e.what() << std::endl;
+      return;
     }
   }
 }
 
-// void
-// SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
-//                                             uint64_t seqNo, Nlsr& pnlsr)
-// {
-//   std::cout << "Cert Name: " << certName << std::endl;
-//   // if (pnlsr.getKeyManager().isNewCertificate(certName, seqNo))
-//   {
-//     string certNamePrefix = certName + "/" +
-//                             boost::lexical_cast<string>(seqNo);
-//     pnlsr.getIm().expressInterest(certNamePrefix, 3,
-//                                   pnlsr.getConfParameter().getInterestResendTime());
-//   }
-// }
-
 void
 SyncLogicHandler::publishRoutingUpdate(SequencingManager& sm,
-                                       const string& updatePrefix)
+                                       const ndn::Name& updatePrefix)
 {
   sm.writeSeqNoToFile();
   publishSyncUpdate(updatePrefix, sm.getCombinedSeqNo());
 }
 
-// void
-// SyncLogicHandler::publishKeyUpdate(KeyManager& km)
-// {
-//   publishSyncUpdate(km.getProcessCertName().toUri(), km.getCertSeqNo());
-// }
-
 void
-SyncLogicHandler::publishIdentityUpdate(const string& identityName)
-{
-  publishSyncUpdate(identityName, 0);
-}
-
-void
-SyncLogicHandler::publishSyncUpdate(const string& updatePrefix, uint64_t seqNo)
+SyncLogicHandler::publishSyncUpdate(const ndn::Name& updatePrefix,
+                                    uint64_t seqNo)
 {
   std::cout << "Publishing Sync Update ......" << std::endl;
   std::cout << "Update in prefix: " << updatePrefix << std::endl;
   std::cout << "Seq No: " << seqNo << std::endl;
   ndn::Name updateName(updatePrefix);
   string data("NoData");
-  m_syncSocket->publishData(updateName, 0, data.c_str(), data.size(), 1000,
+  m_syncSocket->publishData(updateName.toUri(), 0, data.c_str(), data.size(),
+                            1000,
                             seqNo);
 }
 
diff --git a/src/communication/sync-logic-handler.hpp b/src/communication/sync-logic-handler.hpp
index 9f6badd..1f62554 100644
--- a/src/communication/sync-logic-handler.hpp
+++ b/src/communication/sync-logic-handler.hpp
@@ -11,8 +11,6 @@
 
 #include "sequencing-manager.hpp"
 
-// class KeyManager;
-
 extern "C" {
 #include <unistd.h>
 }
@@ -42,16 +40,10 @@
   nsyncRemoveCallBack(const std::string& prefix, Nlsr& pnlsr);
 
   void
-  removeRouterFromSyncing(const std::string& routerPrefix);
+  removeRouterFromSyncing(const ndn::Name& routerPrefix);
 
   void
-  publishRoutingUpdate(SequencingManager& sm, const std::string& updatePrefix);
-
-  // void
-  // publishKeyUpdate(KeyManager& km);
-
-  void
-  publishIdentityUpdate(const std::string& identityName);
+  publishRoutingUpdate(SequencingManager& sm, const ndn::Name& updatePrefix);
 
   void
   setSyncPrefix(const std::string& sp)
@@ -62,17 +54,15 @@
 
 private:
   void
-  processUpdateFromSync(const std::string& updateName, uint64_t seqNo, Nlsr& pnlsr);
+  processUpdateFromSync(const ndn::Name& updateName, uint64_t seqNo,
+                        Nlsr& pnlsr);
 
   void
-  processRoutingUpdateFromSync(const std::string& routerName, uint64_t seqNo,
+  processRoutingUpdateFromSync(const ndn::Name& routerName, uint64_t seqNo,
                                Nlsr& pnlsr);
 
-  // void
-  // processKeysUpdateFromSync(std::string certName, uint64_t seqNo, Nlsr& pnlsr);
-
   void
-  publishSyncUpdate(const std::string& updatePrefix, uint64_t seqNo);
+  publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo);
 
 private:
   ndn::shared_ptr<ndn::ValidatorNull> m_validator;
