diff --git a/src/communication/data-manager.cpp b/src/communication/data-manager.cpp
new file mode 100644
index 0000000..e4cefe5
--- /dev/null
+++ b/src/communication/data-manager.cpp
@@ -0,0 +1,215 @@
+#include <iostream>
+#include <cstdlib>
+
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/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(Nlsr& pnlsr, 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(pnlsr, data);
+  }
+  else
+  {
+    if (pnlsr.getKeyManager().verify(data))
+    {
+      std::cout << "Verified Data Content" << std::endl;
+      chkString = "info";
+      if (nt.doesTokenExist(chkString))
+      {
+        string dataContent((char*)data.getContent().value());
+        processContentInfo(pnlsr, dataName, dataContent);
+      }
+      chkString = "LSA";
+      if (nt.doesTokenExist(chkString))
+      {
+        string dataContent((char*)data.getContent().value());
+        processContentLsa(pnlsr, dataName, dataContent);
+      }
+    }
+    else
+    {
+      std::cout << "Unverified Data Content. Discarded" << std::endl;
+    }
+  }
+}
+
+void
+DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
+                                string& dataContent)
+{
+  Tokenizer nt(dataName, "/");
+  string chkString("info");
+  string neighbor = nt.getTokenString(0, nt.getTokenPosition(chkString) - 1);
+  int oldStatus = pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+  int infoIntTimedOutCount = pnlsr.getAdl().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
+  pnlsr.getAdl().setStatusOfNeighbor(neighbor, 1);
+  pnlsr.getAdl().setTimedOutInterestCount(neighbor, 0);
+  int newStatus = pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+  infoIntTimedOutCount = pnlsr.getAdl().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
+  {
+    pnlsr.incrementAdjBuildCount();
+    /* Need to schedule event for Adjacency LSA building */
+    if (pnlsr.getIsBuildAdjLsaSheduled() == 0)
+    {
+      pnlsr.setIsBuildAdjLsaSheduled(1);
+      // event here
+      pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                         ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
+                                                   boost::ref(pnlsr)));
+    }
+  }
+}
+
+void
+DataManager::processContentLsa(Nlsr& pnlsr, 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(pnlsr, origRouter + "/" + lsTypeString,
+                          interestedLsSeqNo, dataContent);
+  }
+  else if (lsTypeString == "2")  //Adj Lsa
+  {
+    processContentAdjLsa(pnlsr, origRouter + "/" + lsTypeString,
+                         interestedLsSeqNo, dataContent);
+  }
+  else if (lsTypeString == "3")  //Cor Lsa
+  {
+    processContentCorLsa(pnlsr, origRouter + "/" + lsTypeString,
+                         interestedLsSeqNo, dataContent);
+  }
+  else
+  {
+    cout << "Unrecognized LSA Type :(" << endl;
+  }
+}
+
+void
+DataManager::processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+                                   uint32_t lsSeqNo, string& dataContent)
+{
+  if (pnlsr.getLsdb().isNameLsaNew(lsaKey, lsSeqNo))
+  {
+    NameLsa nameLsa;
+    if (nameLsa.initializeFromContent(dataContent))
+    {
+      pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
+    }
+    else
+    {
+      std::cout << "LSA data decoding error :(" << std::endl;
+    }
+  }
+}
+
+void
+DataManager::processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+                                  uint32_t lsSeqNo, string& dataContent)
+{
+  if (pnlsr.getLsdb().isAdjLsaNew(lsaKey, lsSeqNo))
+  {
+    AdjLsa adjLsa;
+    if (adjLsa.initializeFromContent(dataContent))
+    {
+      pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+    }
+    else
+    {
+      std::cout << "LSA data decoding error :(" << std::endl;
+    }
+  }
+}
+
+void
+DataManager::processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+                                  uint32_t lsSeqNo, string& dataContent)
+{
+  if (pnlsr.getLsdb().isCorLsaNew(lsaKey, lsSeqNo))
+  {
+    CorLsa corLsa;
+    if (corLsa.initializeFromContent(dataContent))
+    {
+      pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
+    }
+    else
+    {
+      std::cout << "LSA data decoding error :(" << std::endl;
+    }
+  }
+}
+
+void
+DataManager::processContentKeys(Nlsr& pnlsr, 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 (pnlsr.getKeyManager().verify(pnlsr, *(cert)))
+  {
+    pnlsr.getKeyManager().addCertificate(cert, seqNum, true);
+  }
+  else
+  {
+    pnlsr.getKeyManager().addCertificate(cert, seqNum, false);
+  }
+
+  pnlsr.getKeyManager().printCertStore();
+}
+}//namespace nlsr
diff --git a/src/communication/data-manager.hpp b/src/communication/data-manager.hpp
new file mode 100644
index 0000000..153e0a0
--- /dev/null
+++ b/src/communication/data-manager.hpp
@@ -0,0 +1,48 @@
+#ifndef NLSR_DM_HPP
+#define NLSR_DM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "interest-manager.hpp"
+
+namespace nlsr {
+class Nlsr;
+
+class DataManager
+{
+public:
+  void
+  processContent(Nlsr& pnlsr, const ndn::Interest& interest,
+                 const ndn::Data& data, InterestManager& im);
+private:
+  void
+  processContentInfo(Nlsr& pnlsr, std::string& dataName,
+                     std::string& dataContent);
+
+  void
+  processContentLsa(Nlsr& pnlsr, std::string& dataName,
+                    std::string& dataContent);
+
+  void
+  processContentNameLsa(Nlsr& pnlsr, std::string lsaKey,
+                        uint32_t lsSeqNo, std::string& dataContent);
+
+  void
+  processContentAdjLsa(Nlsr& pnlsr, std::string lsaKey,
+                       uint32_t lsSeqNo, std::string& dataContent);
+
+  void
+  processContentCorLsa(Nlsr& pnlsr, std::string lsaKey,
+                       uint32_t lsSeqNo, std::string& dataContent);
+
+  void
+  processContentKeys(Nlsr& pnlsr, const ndn::Data& data);
+
+
+};
+
+}//namespace nlsr
+
+#endif //NLSR_DM_HPP
diff --git a/src/communication/interest-manager.cpp b/src/communication/interest-manager.cpp
new file mode 100644
index 0000000..73a43e9
--- /dev/null
+++ b/src/communication/interest-manager.cpp
@@ -0,0 +1,339 @@
+#include <iostream>
+#include <cstdlib>
+
+
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/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(Nlsr& pnlsr,
+                                 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(pnlsr, nbr, interest);
+  }
+  chkString = "LSA";
+  if (nt.doesTokenExist(chkString))
+  {
+    processInterestLsa(pnlsr, interest);
+  }
+  chkString = "keys";
+  if (nt.doesTokenExist(chkString))
+  {
+    processInterestKeys(pnlsr, interest);
+  }
+}
+
+void
+InterestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                     const ndn::Interest& interest)
+{
+  if (pnlsr.getAdl().isNeighbor(neighbor))
+  {
+    Data data(ndn::Name(interest.getName()).appendVersion());
+    data.setFreshnessPeriod(time::seconds(10)); // 10 sec
+    data.setContent((const uint8_t*)"info", sizeof("info"));
+    pnlsr.getKeyManager().signData(data);
+    cout << ">> D: " << data << endl;
+    pnlsr.getNlsrFace()->put(data);
+    int status = pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+    if (status == 0)
+    {
+      string intName = neighbor + "/" + "info" +
+                       pnlsr.getConfParameter().getRouterPrefix();
+      expressInterest(pnlsr, intName, 2,
+                      pnlsr.getConfParameter().getInterestResendTime());
+    }
+  }
+}
+
+void
+InterestManager::processInterestLsa(Nlsr& pnlsr, 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(pnlsr, interest,
+                              origRouter + "/" + lsTypeString, interestedLsSeqNo);
+  }
+  else if (lsTypeString == "2") //Adj Lsa
+  {
+    processInterestForAdjLsa(pnlsr, interest,
+                             origRouter + "/" + lsTypeString, interestedLsSeqNo);
+  }
+  else if (lsTypeString == "3") //Cor Lsa
+  {
+    processInterestForCorLsa(pnlsr, interest,
+                             origRouter + "/" + lsTypeString, interestedLsSeqNo);
+  }
+  else
+  {
+    cout << "Unrecognized LSA Type :(" << endl;
+  }
+}
+
+void
+InterestManager::processInterestForNameLsa(Nlsr& pnlsr,
+                                           const ndn::Interest& interest,
+                                           string lsaKey, uint32_t interestedlsSeqNo)
+{
+  std::pair<NameLsa&, bool>  nameLsa = pnlsr.getLsdb().getNameLsa(lsaKey);
+  if (nameLsa.second)
+  {
+    if (nameLsa.first.getLsSeqNo() >= interestedlsSeqNo)
+    {
+      Data data(ndn::Name(interest.getName()).appendVersion());
+      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
+      string content = nameLsa.first.getData();
+      data.setContent((const uint8_t*)content.c_str(), content.size());
+      pnlsr.getKeyManager().signData(data);
+      std::cout << ">> D: " << data << std::endl;
+      pnlsr.getNlsrFace()->put(data);
+    }
+  }
+}
+
+void
+InterestManager::processInterestForAdjLsa(Nlsr& pnlsr,
+                                          const ndn::Interest& interest,
+                                          string lsaKey, uint32_t interestedlsSeqNo)
+{
+  std::pair<AdjLsa&, bool> adjLsa = pnlsr.getLsdb().getAdjLsa(lsaKey);
+  if (adjLsa.second)
+  {
+    if (adjLsa.first.getLsSeqNo() >= interestedlsSeqNo)
+    {
+      Data data(ndn::Name(interest.getName()).appendVersion());
+      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
+      string content = adjLsa.first.getData();
+      data.setContent((const uint8_t*)content.c_str(), content.size());
+      pnlsr.getKeyManager().signData(data);
+      std::cout << ">> D: " << data << std::endl;
+      pnlsr.getNlsrFace()->put(data);
+    }
+  }
+}
+
+void
+InterestManager::processInterestForCorLsa(Nlsr& pnlsr,
+                                          const ndn::Interest& interest,
+                                          string lsaKey, uint32_t interestedlsSeqNo)
+{
+  std::pair<CorLsa&, bool> corLsa = pnlsr.getLsdb().getCorLsa(lsaKey);
+  if (corLsa.second)
+  {
+    if (corLsa.first.getLsSeqNo() >= interestedlsSeqNo)
+    {
+      Data data(ndn::Name(interest.getName()).appendVersion());
+      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
+      string content = corLsa.first.getData();
+      data.setContent((const uint8_t*)content.c_str(), content.size());
+      pnlsr.getKeyManager().signData(data);
+      std::cout << ">> D: " << data << std::endl;
+      pnlsr.getNlsrFace()->put(data);
+    }
+  }
+}
+
+void
+InterestManager::processInterestKeys(Nlsr& pnlsr, 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 = pnlsr.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 = pnlsr.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 =
+        pnlsr.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());
+    pnlsr.getKeyManager().signData(data);
+    pnlsr.getNlsrFace()->put(data);
+  }
+}
+
+
+void
+InterestManager::processInterestTimedOut(Nlsr& pnlsr,
+                                         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(pnlsr , nbr , interest);
+  }
+  chkString = "LSA";
+  if (nt.doesTokenExist(chkString))
+  {
+    processInterestTimedOutLsa(pnlsr, interest);
+  }
+}
+
+void
+InterestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+                                             const ndn::Interest& interest)
+{
+  pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
+  int status = pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+  int infoIntTimedOutCount = pnlsr.getAdl().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 < pnlsr.getConfParameter().getInterestRetryNumber()))
+  {
+    string intName = neighbor + "/" + "info" +
+                     pnlsr.getConfParameter().getRouterPrefix();
+    expressInterest(pnlsr, intName, 2,
+                    pnlsr.getConfParameter().getInterestResendTime());
+  }
+  else if ((status == 1) &&
+           (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
+  {
+    pnlsr.getAdl().setStatusOfNeighbor(neighbor, 0);
+    pnlsr.incrementAdjBuildCount();
+    if (pnlsr.getIsBuildAdjLsaSheduled() == 0)
+    {
+      pnlsr.setIsBuildAdjLsaSheduled(1);
+      // event here
+      pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                         ndn::bind(&Lsdb::scheduledAdjLsaBuild,
+                                                   &pnlsr.getLsdb(),
+                                                   boost::ref(pnlsr)));
+    }
+  }
+}
+
+void
+InterestManager::processInterestTimedOutLsa(Nlsr& pnlsr,
+                                            const ndn::Interest& interest)
+{
+}
+
+void
+InterestManager::expressInterest(Nlsr& pnlsr, const string& interestNamePrefix,
+                                 int scope, int seconds)
+{
+  std::cout << "Expressing Interest :" << interestNamePrefix << std::endl;
+  ndn::Interest i((ndn::Name(interestNamePrefix)));
+  i.setInterestLifetime(time::seconds(seconds));
+  i.setMustBeFresh(true);
+  pnlsr.getNlsrFace()->expressInterest(i,
+                                       ndn::func_lib::bind(&DataManager::processContent,
+                                                           &pnlsr.getDm(),
+                                                           boost::ref(pnlsr), _1,
+                                                           _2, boost::ref(*this)),
+                                       ndn::func_lib::bind(&InterestManager::processInterestTimedOut,
+                                                           this, boost::ref(pnlsr), _1));
+}
+
+
+void
+InterestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
+{
+  std::list<Adjacent> adjList = pnlsr.getAdl().getAdjList();
+  for (std::list<Adjacent>::iterator it = adjList.begin(); it != adjList.end();
+       ++it)
+  {
+    string adjName = (*it).getName() + "/" + "info" +
+                     pnlsr.getConfParameter().getRouterPrefix();
+    expressInterest(pnlsr, adjName, 2,
+                    pnlsr.getConfParameter().getInterestResendTime());
+  }
+  scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
+}
+
+void
+InterestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
+{
+  EventId eid = pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
+                                                   ndn::bind(&InterestManager::sendScheduledInfoInterest, this,
+                                                             boost::ref(pnlsr), seconds));
+}
+
+
+} //namespace nlsr
diff --git a/src/communication/interest-manager.hpp b/src/communication/interest-manager.hpp
new file mode 100644
index 0000000..5975e7f
--- /dev/null
+++ b/src/communication/interest-manager.hpp
@@ -0,0 +1,71 @@
+#ifndef NLSR_IM_HPP
+#define NLSR_IM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+namespace nlsr {
+
+class Nlsr;
+
+class InterestManager
+{
+public:
+  InterestManager()
+  {
+  }
+  void
+  processInterest(Nlsr& pnlsr, const ndn::Name& name,
+                  const ndn::Interest& interest);
+
+  void
+  processInterestInfo(Nlsr& pnlsr, std::string& neighbor,
+                      const ndn::Interest& interest);
+
+  void
+  processInterestLsa(Nlsr& pnlsr, const ndn::Interest& interest);
+
+  void
+  processInterestForNameLsa(Nlsr& pnlsr, const ndn::Interest& interest,
+                            std::string lsaKey, uint32_t interestedlsSeqNo);
+
+  void
+  processInterestForAdjLsa(Nlsr& pnlsr, const ndn::Interest& interest,
+                           std::string lsaKey, uint32_t interestedlsSeqNo);
+
+  void
+  processInterestForCorLsa(Nlsr& pnlsr, const ndn::Interest& interest,
+                           std::string lsaKey, uint32_t interestedlsSeqNo);
+
+  void
+  processInterestKeys(Nlsr& pnlsr, const ndn::Interest& interest);
+
+  void
+  processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest& interest);
+
+  void
+  processInterestTimedOutInfo(Nlsr& pnlsr, std::string& neighbor,
+                              const ndn::Interest& interest);
+
+  void
+  processInterestTimedOutLsa(Nlsr& pnlsr, const ndn::Interest& interest);
+
+  void
+  expressInterest(Nlsr& pnlsr,
+                  const std::string& interestNamePrefix, int scope, int seconds);
+
+  void
+  sendScheduledInfoInterest(Nlsr& pnlsr, int seconds);
+
+  void
+  scheduleInfoInterest(Nlsr& pnlsr, int seconds);
+
+private:
+
+
+};
+
+}//namespace nlsr
+
+#endif //NLSR_IM_HPP
diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
deleted file mode 100644
index 249b5e7..0000000
--- a/src/communication/nlsr_dm.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-#include<iostream>
-#include<cstdlib>
-
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <ndn-cpp-dev/util/io.hpp>
-
-#include "nlsr.hpp"
-#include "nlsr_dm.hpp"
-#include "utility/nlsr_tokenizer.hpp"
-#include "nlsr_lsdb.hpp"
-#include "security/nlsr_km.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_dm.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-  using namespace ndn;
-
-  void
-  DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
-                              const ndn::Data & data, InterestManager& im)
-  {
-    cout << "I: " << interest.toUri() << endl;
-    string dataName(data.getName().toUri());
-    nlsrTokenizer nt(dataName,"/");
-    std::string chkString("keys");
-    if( nt.doesTokenExist(chkString) )
-    {
-      processContentKeys(pnlsr, data);
-    }
-    else
-    {
-      if ( pnlsr.getKeyManager().verify(data))
-      {
-        std::cout<<"Verified Data Content"<<std::endl;
-        chkString="info";
-        if( nt.doesTokenExist(chkString) )
-        {
-          string dataContent((char *)data.getContent().value());
-          processContentInfo(pnlsr,dataName,dataContent);
-        }
-        chkString="LSA";
-        if( nt.doesTokenExist(chkString) )
-        {
-          string dataContent((char *)data.getContent().value());
-          processContentLsa(pnlsr, dataName, dataContent);
-        }
-      }
-      else
-      {
-        std::cout<<"Unverified Data Content. Discarded"<<std::endl;
-      }
-    }
-  }
-
-  void
-  DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
-                                  string& dataContent)
-  {
-    nlsrTokenizer nt(dataName,"/");
-    string chkString("info");
-    string neighbor=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
-    int oldStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
-    int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
-    //debugging purpose start
-    cout <<"Before Updates: " <<endl;
-    cout <<"Neighbor : "<<neighbor<<endl;
-    cout<<"Status: "<< oldStatus << endl;
-    cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
-    //debugging purpose end
-    pnlsr.getAdl().setStatusOfNeighbor(neighbor,1);
-    pnlsr.getAdl().setTimedOutInterestCount(neighbor,0);
-    int newStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
-    infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
-    //debugging purpose
-    cout <<"After Updates: " <<endl;
-    cout <<"Neighbor : "<<neighbor<<endl;
-    cout<<"Status: "<< newStatus << endl;
-    cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
-    //debugging purpose end
-    if ( ( oldStatus-newStatus)!= 0 ) // change in Adjacency list
-    {
-      pnlsr.incrementAdjBuildCount();
-      /* Need to schedule event for Adjacency LSA building */
-      if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
-      {
-        pnlsr.setIsBuildAdjLsaSheduled(1);
-        // event here
-        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
-                                           ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
-                                               boost::ref(pnlsr)));
-      }
-    }
-  }
-
-  void
-  DataManager::processContentLsa(Nlsr& pnlsr, string& dataName,
-                                 string& dataContent)
-  {
-    nlsrTokenizer 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(pnlsr, origRouter+"/"+lsTypeString,
-                            interestedLsSeqNo, dataContent);
-    }
-    else if( lsTypeString == "2" ) //Adj Lsa
-    {
-      processContentAdjLsa(pnlsr, origRouter+"/"+lsTypeString,
-                           interestedLsSeqNo, dataContent);
-    }
-    else if( lsTypeString == "3" ) //Cor Lsa
-    {
-      processContentCorLsa(pnlsr, origRouter+"/"+lsTypeString,
-                           interestedLsSeqNo, dataContent);
-    }
-    else
-    {
-      cout<<"Unrecognized LSA Type :("<<endl;
-    }
-  }
-
-  void
-  DataManager::processContentNameLsa(Nlsr& pnlsr, string lsaKey,
-                                     uint32_t lsSeqNo, string& dataContent)
-  {
-    if ( pnlsr.getLsdb().isNameLsaNew(lsaKey,lsSeqNo))
-    {
-      NameLsa nameLsa;
-      if( nameLsa.initializeFromContent(dataContent) )
-      {
-        pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
-      }
-      else
-      {
-        cout<<"LSA data decoding error :("<<endl;
-      }
-    }
-  }
-
-  void
-  DataManager::processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
-                                    uint32_t lsSeqNo, string& dataContent)
-  {
-    if ( pnlsr.getLsdb().isAdjLsaNew(lsaKey,lsSeqNo))
-    {
-      AdjLsa adjLsa;
-      if( adjLsa.initializeFromContent(dataContent) )
-      {
-        pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
-      }
-      else
-      {
-        cout<<"LSA data decoding error :("<<endl;
-      }
-    }
-  }
-
-  void
-  DataManager::processContentCorLsa(Nlsr& pnlsr, string lsaKey,
-                                    uint32_t lsSeqNo, string& dataContent)
-  {
-    if ( pnlsr.getLsdb().isCorLsaNew(lsaKey,lsSeqNo))
-    {
-      CorLsa corLsa;
-      if( corLsa.initializeFromContent(dataContent) )
-      {
-        pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
-      }
-      else
-      {
-        cout<<"LSA data decoding error :("<<endl;
-      }
-    }
-  }
-
-  void
-  DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
-  {
-    std::cout<<" processContentKeys called "<<endl;
-    ndn::shared_ptr<ndn::IdentityCertificate> cert=
-      ndn::make_shared<ndn::IdentityCertificate>();
-    cert->wireDecode(data.getContent().blockFromValue());
-    std::cout<<*(cert)<<endl;
-    std::string dataName=data.getName().toUri();
-    nlsrTokenizer nt(dataName,"/");
-    std::string certName=nt.getTokenString(0,nt.getTokenNumber()-3);
-    uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(
-                      nt.getTokenNumber()-2));
-    cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
-    if ( pnlsr.getKeyManager().verify(pnlsr, *(cert)))
-    {
-      pnlsr.getKeyManager().addCertificate(cert, seqNum, true);
-    }
-    else
-    {
-      pnlsr.getKeyManager().addCertificate(cert, seqNum, false);
-    }
-    
-    pnlsr.getKeyManager().printCertStore();
-  }
-}//namespace nlsr
diff --git a/src/communication/nlsr_dm.hpp b/src/communication/nlsr_dm.hpp
deleted file mode 100644
index fc231d3..0000000
--- a/src/communication/nlsr_dm.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef NLSR_DM_HPP
-#define NLSR_DM_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include "nlsr_im.hpp"
-
-namespace nlsr
-{
-
-  using namespace ndn;
-  using namespace std;
-
-  class Nlsr;
-
-  class DataManager
-  {
-  public:
-    void processContent(Nlsr& pnlsr, const ndn::Interest& interest,
-                        const ndn::Data& data, InterestManager& im);
-  private:
-    void processContentInfo(Nlsr& pnlsr, string& dataName,
-                            string& dataContent);
-    void processContentLsa(Nlsr& pnlsr, string& dataName,
-                           string& dataContent);
-    void processContentNameLsa(Nlsr& pnlsr, string lsaKey,
-                               uint32_t lsSeqNo, string& dataContent);
-    void processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
-                              uint32_t lsSeqNo, string& dataContent);
-    void processContentCorLsa(Nlsr& pnlsr, string lsaKey,
-                              uint32_t lsSeqNo, string& dataContent);
-    void processContentKeys(Nlsr& pnlsr, const ndn::Data& data);
-
-
-  };
-
-}//namespace nlsr
-#endif
diff --git a/src/communication/nlsr_im.cpp b/src/communication/nlsr_im.cpp
deleted file mode 100644
index d708812..0000000
--- a/src/communication/nlsr_im.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-#include<iostream>
-#include<cstdlib>
-
-
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <ndn-cpp-dev/util/io.hpp>
-
-#include "nlsr.hpp"
-#include "nlsr_im.hpp"
-#include "nlsr_dm.hpp"
-#include "utility/nlsr_tokenizer.hpp"
-#include "nlsr_lsdb.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_im.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-  using namespace ndn;
-
-  void
-  InterestManager::processInterest( Nlsr& pnlsr,
-                                    const ndn::Name& name,
-                                    const ndn::Interest& interest)
-  {
-    cout << "<< I: " << interest << endl;
-    string intName=interest.getName().toUri();
-    cout << "Interest Received for Name: "<< intName <<endl;
-    nlsrTokenizer nt(intName,"/");
-    string chkString("info");
-    if( nt.doesTokenExist(chkString) )
-    {
-      string nbr=nt.getTokenString(nt.getTokenPosition(chkString)+1);
-      cout <<"Neighbor: " << nbr <<endl;
-      processInterestInfo(pnlsr,nbr,interest);
-    }
-    chkString="LSA";
-    if( nt.doesTokenExist(chkString) )
-    {
-      processInterestLsa(pnlsr,interest);
-    }
-    chkString="keys";
-    if( nt.doesTokenExist(chkString) )
-    {
-      processInterestKeys(pnlsr,interest);
-    }
-  }
-
-  void
-  InterestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
-                                       const ndn::Interest& interest)
-  {
-    if ( pnlsr.getAdl().isNeighbor(neighbor) )
-    {
-      Data data(ndn::Name(interest.getName()).appendVersion());
-      data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-      data.setContent((const uint8_t*)"info", sizeof("info"));
-      pnlsr.getKeyManager().signData(data);
-      cout << ">> D: " << data << endl;
-      pnlsr.getNlsrFace()->put(data);
-      int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
-      if ( status == 0 )
-      {
-        string intName=neighbor +"/"+"info"+
-                       pnlsr.getConfParameter().getRouterPrefix();
-        expressInterest(	pnlsr,intName,2,
-                          pnlsr.getConfParameter().getInterestResendTime());
-      }
-    }
-  }
-
-  void
-  InterestManager::processInterestLsa(Nlsr& pnlsr,const ndn::Interest& interest)
-  {
-    string intName=interest.getName().toUri();
-    nlsrTokenizer 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);
-    cout<<"Router Name: "<<origRouter<<endl;
-    cout<<"Ls Type    : "<<lsTypeString<<endl;
-    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;
-    }
-    cout <<"Ls Type: "<<interestedLsType<<endl;
-    if( lsTypeString == "1" ) //Name Lsa
-    {
-      processInterestForNameLsa(pnlsr, interest,
-                                origRouter+"/"+lsTypeString, interestedLsSeqNo);
-    }
-    else if( lsTypeString == "2" ) //Adj Lsa
-    {
-      processInterestForAdjLsa(pnlsr, interest,
-                               origRouter+"/"+lsTypeString, interestedLsSeqNo);
-    }
-    else if( lsTypeString == "3" ) //Cor Lsa
-    {
-      processInterestForCorLsa(pnlsr, interest,
-                               origRouter+"/"+lsTypeString, interestedLsSeqNo);
-    }
-    else
-    {
-      cout<<"Unrecognized LSA Type :("<<endl;
-    }
-  }
-
-  void
-  InterestManager::processInterestForNameLsa(Nlsr& pnlsr,
-      const ndn::Interest& interest,
-      string lsaKey, uint32_t interestedlsSeqNo)
-  {
-    std::pair<NameLsa&, bool>  nameLsa=pnlsr.getLsdb().getNameLsa(lsaKey);
-    if( nameLsa.second )
-    {
-      if ( nameLsa.first.getLsSeqNo() >= interestedlsSeqNo )
-      {
-        Data data(ndn::Name(interest.getName()).appendVersion());
-        data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-        string content=nameLsa.first.getData();
-        data.setContent((const uint8_t*)content.c_str(),content.size());
-        pnlsr.getKeyManager().signData(data);
-        cout << ">> D: " << data << endl;
-        pnlsr.getNlsrFace()->put(data);
-      }
-    }
-  }
-
-  void
-  InterestManager::processInterestForAdjLsa(Nlsr& pnlsr,
-      const ndn::Interest& interest,
-      string lsaKey, uint32_t interestedlsSeqNo)
-  {
-    std::pair<AdjLsa&, bool>  adjLsa=pnlsr.getLsdb().getAdjLsa(lsaKey);
-    if( adjLsa.second )
-    {
-      if ( adjLsa.first.getLsSeqNo() >= interestedlsSeqNo )
-      {
-        Data data(ndn::Name(interest.getName()).appendVersion());
-        data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-        string content=adjLsa.first.getData();
-        data.setContent((const uint8_t*)content.c_str(),content.size());
-        pnlsr.getKeyManager().signData(data);
-        cout << ">> D: " << data << endl;
-        pnlsr.getNlsrFace()->put(data);
-      }
-    }
-  }
-
-  void
-  InterestManager::processInterestForCorLsa(Nlsr& pnlsr,
-      const ndn::Interest& interest,
-      string lsaKey, uint32_t interestedlsSeqNo)
-  {
-    std::pair<CorLsa&, bool>  corLsa=pnlsr.getLsdb().getCorLsa(lsaKey);
-    if( corLsa.second )
-    {
-      if ( corLsa.first.getLsSeqNo() >= interestedlsSeqNo )
-      {
-        Data data(ndn::Name(interest.getName()).appendVersion());
-        data.setFreshnessPeriod(time::seconds(10)); // 10 sec
-        string content=corLsa.first.getData();
-        data.setContent((const uint8_t*)content.c_str(),content.size());
-        pnlsr.getKeyManager().signData(data);
-        cout << ">> D: " << data << endl;
-        pnlsr.getNlsrFace()->put(data);
-      }
-    }
-  }
-
-  void
-  InterestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest& interest)
-  {
-    cout<<"processInterestKeys called "<<endl;
-    string intName=interest.getName().toUri();
-    cout<<"Interest Name for Key: "<<intName<<std::endl;
-    nlsrTokenizer 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=pnlsr.getKeyManager().getCertificateFromStore(certName);
-    }
-    else
-    {
-      certName=nt.getTokenString(0,nt.getTokenNumber()-2);
-      seqNum=boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber()-1));
-      cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
-      chkCert=pnlsr.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 = 
-                           pnlsr.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());
-      pnlsr.getKeyManager().signData(data);
-      pnlsr.getNlsrFace()->put(data);
-    }
-  }
-
-
-  void
-  InterestManager::processInterestTimedOut(Nlsr& pnlsr,
-      const ndn::Interest& interest)
-  {
-    cout << "Timed out interest : " << interest.getName().toUri() << endl;
-    string intName=	interest.getName().toUri();
-    nlsrTokenizer nt(intName,"/");
-    string chkString("info");
-    if( nt.doesTokenExist(chkString) )
-    {
-      string nbr=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
-      processInterestTimedOutInfo( pnlsr , nbr , interest);
-    }
-    chkString="LSA";
-    if( nt.doesTokenExist(chkString) )
-    {
-      processInterestTimedOutLsa(pnlsr, interest);
-    }
-  }
-
-  void
-  InterestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
-      const ndn::Interest& interest)
-  {
-    pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
-    int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
-    int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
-    cout<<"Neighbor: "<< neighbor << endl;
-    cout<<"Status: "<< status << endl;
-    cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
-    if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
-    {
-      string intName=neighbor +"/"+"info"+
-                     pnlsr.getConfParameter().getRouterPrefix();
-      expressInterest(	pnlsr,intName,2,
-                        pnlsr.getConfParameter().getInterestResendTime());
-    }
-    else if ( (status == 1) &&
-              (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
-    {
-      pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
-      pnlsr.incrementAdjBuildCount();
-      if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
-      {
-        pnlsr.setIsBuildAdjLsaSheduled(1);
-        // event here
-        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
-                                           ndn::bind(&Lsdb::scheduledAdjLsaBuild,&pnlsr.getLsdb(),
-                                               boost::ref(pnlsr)));
-      }
-    }
-  }
-
-  void
-  InterestManager::processInterestTimedOutLsa(Nlsr& pnlsr,
-      const ndn::Interest& interest)
-  {
-  }
-
-  void
-  InterestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
-                                   int scope, int seconds)
-  {
-    cout<<"Expressing Interest :"<<interestNamePrefix<<endl;
-    ndn::Interest i((ndn::Name(interestNamePrefix)));
-    //i.setScope(scope);
-    i.setInterestLifetime(time::seconds(seconds));
-    i.setMustBeFresh(true);
-    pnlsr.getNlsrFace()->expressInterest(i,
-                                         ndn::func_lib::bind(&DataManager::processContent,
-                                             &pnlsr.getDm(), boost::ref(pnlsr),_1, _2,boost::ref(*this)),
-                                         ndn::func_lib::bind(&InterestManager::processInterestTimedOut,
-                                             this,boost::ref(pnlsr),_1));
-  }
-
-
-  void
-  InterestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
-  {
-    std::list<Adjacent> adjList=pnlsr.getAdl().getAdjList();
-    for(std::list<Adjacent>::iterator it=adjList.begin(); it!=adjList.end(); ++it)
-    {
-      string adjName=(*it).getName()+"/"+"info"+
-                     pnlsr.getConfParameter().getRouterPrefix();
-      expressInterest(	pnlsr,adjName,2,
-                        pnlsr.getConfParameter().getInterestResendTime());
-    }
-    scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
-  }
-
-  void
-  InterestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
-  {
-    EventId eid=pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
-                ndn::bind(&InterestManager::sendScheduledInfoInterest, this,
-                          boost::ref(pnlsr),seconds));
-  }
-
-
-} //namespace nlsr
diff --git a/src/communication/nlsr_im.hpp b/src/communication/nlsr_im.hpp
deleted file mode 100644
index 5b74174..0000000
--- a/src/communication/nlsr_im.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef NLSR_IM_HPP
-#define NLSR_IM_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-namespace nlsr
-{
-
-  using namespace ndn;
-  using namespace std;
-
-  class Nlsr;
-
-  class InterestManager
-  {
-  public:
-    InterestManager()
-    {
-    }
-    void processInterest(Nlsr& pnlsr, const ndn::Name& name,
-                         const ndn::Interest& interest);
-    void processInterestInfo(Nlsr& pnlsr, string& neighbor,
-                             const ndn::Interest& interest);
-    void processInterestLsa(Nlsr& pnlsr,const ndn::Interest& interest);
-    void processInterestForNameLsa(Nlsr& pnlsr, const ndn::Interest& interest,
-                                   string lsaKey, uint32_t interestedlsSeqNo);
-    void processInterestForAdjLsa(Nlsr& pnlsr, const ndn::Interest& interest,
-                                  string lsaKey, uint32_t interestedlsSeqNo);
-    void processInterestForCorLsa(Nlsr& pnlsr, const ndn::Interest& interest,
-                                  string lsaKey, uint32_t interestedlsSeqNo);
-
-    void processInterestKeys(Nlsr& pnlsr,const ndn::Interest& interest);
-
-    void processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest& interest);
-    void processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
-                                     const ndn::Interest& interest);
-    void processInterestTimedOutLsa(Nlsr& pnlsr,const ndn::Interest& interest);
-    void expressInterest(Nlsr& pnlsr,const string& interestNamePrefix, int scope,
-                         int seconds);
-    void sendScheduledInfoInterest(Nlsr& pnlsr, int seconds);
-    void scheduleInfoInterest(Nlsr& pnlsr, int seconds);
-
-  private:
-
-
-  };
-
-}//namespace nlsr
-
-#endif
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
deleted file mode 100644
index 70295aa..0000000
--- a/src/communication/nlsr_slh.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "nlsr.hpp"
-#include "nlsr_slh.hpp"
-#include "security/nlsr_km.hpp"
-#include "utility/nlsr_tokenizer.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_slh.cpp"
-
-
-namespace nlsr
-{
-  void
-  SyncLogicHandler::createSyncSocket(Nlsr& pnlsr )
-  {
-    cout<<"Creating Sync socket ......"<<endl;
-    cout<<"Sync prefix: "<<m_syncPrefix.toUri()<<endl;
-    m_syncSocket=make_shared<SyncSocket>(m_syncPrefix, m_validator, m_syncFace,
-                                       bind(&SyncLogicHandler::nsyncUpdateCallBack,this,
-                                            _1, _2,boost::ref(pnlsr)),
-                                       bind(&SyncLogicHandler::nsyncRemoveCallBack, this,
-                                            _1,boost::ref(pnlsr)));
-  }
-
-  void
-  SyncLogicHandler::nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
-                                        SyncSocket *socket, Nlsr& pnlsr)
-  {
-    cout<<"nsyncUpdateCallBack called ...."<<endl;
-    int n = v.size();
-    for(int i=0; i < n; i++)
-    {
-      std::cout<<"Data Name: "<<v[i].prefix<<" Seq: "<<v[i].high.getSeq()<<endl;
-      processUpdateFromSync(v[i].prefix,v[i].high.getSeq(),pnlsr);
-    }
-  }
-
-  void
-  SyncLogicHandler::nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr)
-  {
-    cout<<"nsyncRemoveCallBack called ...."<<endl;
-  }
-
-  void
-  SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
-  {
-  }
-
-  void
-  SyncLogicHandler::processUpdateFromSync(std::string updateName,
-                                          uint64_t seqNo,  Nlsr& pnlsr)
-  {
-    nlsrTokenizer nt(updateName,"/");
-    string chkString("LSA");
-    if( nt.doesTokenExist(chkString) )
-    {
-      //process LSA Update here
-      string routerName=nt.getTokenString(nt.getTokenPosition(chkString)+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);
-    }
-  }
-
-  void
-  SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
-      uint64_t seqNo,  Nlsr& pnlsr)
-  {
-    if( routerName != pnlsr.getConfParameter().getRouterPrefix() )
-    {
-      SequencingManager sm(seqNo);
-      cout<<sm;
-      cout<<"Router Name: "<<routerName<<endl;
-      if ( pnlsr.getLsdb().isNameLsaNew(routerName+"/1",sm.getNameLsaSeq()))
-      {
-        cout<<"Updated Name LSA. Need to fetch it"<<endl;
-        string lsaPrefix=
-          pnlsr.getConfParameter().getChronosyncLsaPrefix() +
-          routerName + "/1/" +
-          boost::lexical_cast<std::string>(sm.getNameLsaSeq());
-        pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
-                                      pnlsr.getConfParameter().getInterestResendTime());
-      }
-      if ( pnlsr.getLsdb().isAdjLsaNew(routerName+"/2",sm.getAdjLsaSeq()))
-      {
-        cout<<"Updated Adj LSA. Need to fetch it"<<endl;
-        string lsaPrefix=
-          pnlsr.getConfParameter().getChronosyncLsaPrefix() +
-          routerName + "/2/" +
-          boost::lexical_cast<std::string>(sm.getAdjLsaSeq());
-        pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
-                                      pnlsr.getConfParameter().getInterestResendTime());
-      }
-      if ( pnlsr.getLsdb().isCorLsaNew(routerName+"/3",sm.getCorLsaSeq()))
-      {
-        cout<<"Updated Cor LSA. Need to fetch it"<<endl;
-        string lsaPrefix=
-          pnlsr.getConfParameter().getChronosyncLsaPrefix() +
-          routerName + "/3/" +
-          boost::lexical_cast<std::string>(sm.getCorLsaSeq());
-        pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
-                                      pnlsr.getConfParameter().getInterestResendTime());
-      }
-    }
-  }
-
-  void
-  SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
-      uint64_t seqNo, Nlsr& pnlsr)
-  {
-    cout<<"Cert Name: "<<certName<<std::endl;
-    if ( pnlsr.getKeyManager().isNewCertificate(certName,seqNo) )
-    {
-      string certNamePrefix=certName + "/" +
-                            boost::lexical_cast<string>(seqNo);
-      pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
-                                    pnlsr.getConfParameter().getInterestResendTime());
-    }
-  }
-
-  void
-  SyncLogicHandler::publishRoutingUpdate(SequencingManager& sm,
-                                         string updatePrefix)
-  {
-    sm.writeSeqNoToFile();
-    publishSyncUpdate(updatePrefix,sm.getCombinedSeqNo());
-  }
-
-  void
-  SyncLogicHandler::publishKeyUpdate(KeyManager& km)
-  {
-    publishSyncUpdate(km.getProcessCertName().toUri(),km.getCertSeqNo());
-  }
-
-  void
-  SyncLogicHandler::publishIdentityUpdate(string identityName)
-  {
-    publishSyncUpdate(identityName,0);
-  }
-
-  void
-  SyncLogicHandler::publishSyncUpdate(string updatePrefix, uint64_t seqNo)
-  {
-    cout<<"Publishing Sync Update ......"<<endl;
-    cout<<"Update in prefix: "<<updatePrefix<<endl;
-    cout<<"Seq No: "<<seqNo<<endl;
-    ndn::Name updateName(updatePrefix);
-    string data("NoData");
-    m_syncSocket->publishData(updateName,0,data.c_str(),data.size(),1000,seqNo);
-  }
-
-}
diff --git a/src/communication/nlsr_slh.hpp b/src/communication/nlsr_slh.hpp
deleted file mode 100644
index 4f90fd6..0000000
--- a/src/communication/nlsr_slh.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef NLSR_SLH_HPP
-#define NLSR_SLH_HPP
-
-#include <iostream>
-
-#include <ndn-cpp-dev/face.hpp>
-#include <nsync/sync-socket.h>
-#include <ndn-cpp-dev/security/validator-null.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include "nlsr_sm.hpp"
-
-class KeyManager;
-
-extern "C" {
-#include <unistd.h>
-}
-
-using namespace ndn;
-using namespace Sync;
-using namespace std;
-
-class InterestManager;
-class ConfParameter;
-
-namespace nlsr
-{
-  class SyncLogicHandler
-  {
-  public:
-    SyncLogicHandler(ndn::shared_ptr<boost::asio::io_service> ioService)
-      : m_validator(new ndn::ValidatorNull())
-      , m_syncFace(new ndn::Face(ioService))
-    {}
-
-
-    void createSyncSocket(Nlsr& pnlsr);
-    void nsyncUpdateCallBack(const vector<MissingDataInfo>& v,
-                             SyncSocket *socket, Nlsr& pnlsr );
-    void nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr);
-    void removeRouterFromSyncing(string& routerPrefix);
-    void publishRoutingUpdate(SequencingManager& sm, string updatePrefix);
-    void publishKeyUpdate(KeyManager& km);
-    void publishIdentityUpdate(string identityName);
-    void setSyncPrefix(string sp)
-    {
-      m_syncPrefix.clear();
-      m_syncPrefix.set(sp);
-    }
-  private:
-    void processUpdateFromSync(std::string updateName, uint64_t seqNo,
-                               Nlsr& pnlsr);
-    void processRoutingUpdateFromSync(std::string routerName, uint64_t seqNo,
-                                      Nlsr& pnlsr);
-    void processKeysUpdateFromSync(std::string certName, uint64_t seqNo,
-                                   Nlsr& pnlsr);
-    void publishSyncUpdate(string updatePrefix, uint64_t seqNo);
-  private:
-    ndn::shared_ptr<ndn::ValidatorNull> m_validator;
-    ndn::shared_ptr<ndn::Face> m_syncFace;
-    ndn::shared_ptr<SyncSocket> m_syncSocket;
-    ndn::Name m_syncPrefix;
-  };
-}
-#endif
diff --git a/src/communication/sync-logic-handler.cpp b/src/communication/sync-logic-handler.cpp
new file mode 100644
index 0000000..a38fe98
--- /dev/null
+++ b/src/communication/sync-logic-handler.cpp
@@ -0,0 +1,156 @@
+#include "nlsr.hpp"
+#include "sync-logic-handler.hpp"
+#include "security/key-manager.hpp"
+#include "utility/tokenizer.hpp"
+
+
+namespace nlsr {
+
+void
+SyncLogicHandler::createSyncSocket(Nlsr& pnlsr)
+{
+  std::cout << "Creating Sync socket ......" << std::endl;
+  std::cout << "Sync prefix: " << m_syncPrefix.toUri() << std::endl;
+  m_syncSocket = make_shared<Sync::SyncSocket>(m_syncPrefix, m_validator,
+                                               m_syncFace,
+                                               bind(&SyncLogicHandler::nsyncUpdateCallBack, this,
+                                                    _1, _2, boost::ref(pnlsr)),
+                                               bind(&SyncLogicHandler::nsyncRemoveCallBack, this,
+                                                    _1, boost::ref(pnlsr)));
+}
+
+void
+SyncLogicHandler::nsyncUpdateCallBack(const vector<Sync::MissingDataInfo>& v,
+                                      Sync::SyncSocket* socket, Nlsr& pnlsr)
+{
+  std::cout << "nsyncUpdateCallBack called ...." << std::endl;
+  int n = v.size();
+  for (int i = 0; i < n; i++)
+  {
+    std::cout << "Data Name: " << v[i].prefix << " Seq: " << v[i].high.getSeq() <<
+              endl;
+    processUpdateFromSync(v[i].prefix, v[i].high.getSeq(), pnlsr);
+  }
+}
+
+void
+SyncLogicHandler::nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr)
+{
+  std::cout << "nsyncRemoveCallBack called ...." << std::endl;
+}
+
+void
+SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
+{
+}
+
+void
+SyncLogicHandler::processUpdateFromSync(std::string updateName,
+                                        uint64_t seqNo,  Nlsr& pnlsr)
+{
+  Tokenizer nt(updateName, "/");
+  string chkString("LSA");
+  if (nt.doesTokenExist(chkString))
+  {
+    //process LSA Update here
+    string routerName = nt.getTokenString(nt.getTokenPosition(chkString) + 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);
+  }
+}
+
+void
+SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
+                                               uint64_t seqNo,  Nlsr& pnlsr)
+{
+  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()))
+    {
+      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.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                    pnlsr.getConfParameter().getInterestResendTime());
+    }
+    if (pnlsr.getLsdb().isAdjLsaNew(routerName + "/2", sm.getAdjLsaSeq()))
+    {
+      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.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                    pnlsr.getConfParameter().getInterestResendTime());
+    }
+    if (pnlsr.getLsdb().isCorLsaNew(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.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                    pnlsr.getConfParameter().getInterestResendTime());
+    }
+  }
+}
+
+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(pnlsr, certNamePrefix, 3,
+                                  pnlsr.getConfParameter().getInterestResendTime());
+  }
+}
+
+void
+SyncLogicHandler::publishRoutingUpdate(SequencingManager& sm,
+                                       string updatePrefix)
+{
+  sm.writeSeqNoToFile();
+  publishSyncUpdate(updatePrefix, sm.getCombinedSeqNo());
+}
+
+void
+SyncLogicHandler::publishKeyUpdate(KeyManager& km)
+{
+  publishSyncUpdate(km.getProcessCertName().toUri(), km.getCertSeqNo());
+}
+
+void
+SyncLogicHandler::publishIdentityUpdate(string identityName)
+{
+  publishSyncUpdate(identityName, 0);
+}
+
+void
+SyncLogicHandler::publishSyncUpdate(string 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,
+                            seqNo);
+}
+
+}//namespace nlsr
diff --git a/src/communication/sync-logic-handler.hpp b/src/communication/sync-logic-handler.hpp
new file mode 100644
index 0000000..8fd29fe
--- /dev/null
+++ b/src/communication/sync-logic-handler.hpp
@@ -0,0 +1,85 @@
+#ifndef NLSR_SLH_HPP
+#define NLSR_SLH_HPP
+
+#include <iostream>
+
+#include <ndn-cpp-dev/face.hpp>
+#include <nsync/sync-socket.h>
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "sequencing-manager.hpp"
+
+class KeyManager;
+
+extern "C" {
+#include <unistd.h>
+}
+
+class InterestManager;
+class ConfParameter;
+
+namespace nlsr {
+
+class SyncLogicHandler
+{
+public:
+  SyncLogicHandler(ndn::shared_ptr<boost::asio::io_service> ioService)
+    : m_validator(new ndn::ValidatorNull())
+    , m_syncFace(new ndn::Face(ioService))
+  {}
+
+
+  void
+  createSyncSocket(Nlsr& pnlsr);
+
+  void
+  nsyncUpdateCallBack(const vector<Sync::MissingDataInfo>& v,
+                      Sync::SyncSocket* socket, Nlsr& pnlsr);
+
+  void
+  nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr);
+
+  void
+  removeRouterFromSyncing(string& routerPrefix);
+
+  void
+  publishRoutingUpdate(SequencingManager& sm, string updatePrefix);
+
+  void
+  publishKeyUpdate(KeyManager& km);
+
+  void
+  publishIdentityUpdate(string identityName);
+
+  void
+  setSyncPrefix(string sp)
+  {
+    m_syncPrefix.clear();
+    m_syncPrefix.set(sp);
+  }
+
+private:
+  void
+  processUpdateFromSync(std::string updateName, uint64_t seqNo, Nlsr& pnlsr);
+
+  void
+  processRoutingUpdateFromSync(std::string routerName, uint64_t seqNo,
+                               Nlsr& pnlsr);
+
+  void
+  processKeysUpdateFromSync(std::string certName, uint64_t seqNo, Nlsr& pnlsr);
+
+  void
+  publishSyncUpdate(string updatePrefix, uint64_t seqNo);
+
+private:
+  ndn::shared_ptr<ndn::ValidatorNull> m_validator;
+  ndn::shared_ptr<ndn::Face> m_syncFace;
+  ndn::shared_ptr<Sync::SyncSocket> m_syncSocket;
+  ndn::Name m_syncPrefix;
+};
+
+} //namespace nlsr
+
+#endif //NLSR_SLH_HPP
