diff --git a/src/adjacent.cpp b/src/adjacent.cpp
new file mode 100644
index 0000000..807eb0b
--- /dev/null
+++ b/src/adjacent.cpp
@@ -0,0 +1,40 @@
+#include <iostream>
+#include <string>
+#include <cmath>
+#include <limits>
+#include "adjacent.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+Adjacent::Adjacent(const string& an, int cf, double lc, int s, int iton)
+{
+  m_name = an;
+  m_connectingFace = cf;
+  m_linkCost = lc;
+  m_status = s;
+  m_interestTimedOutNo = iton;
+}
+
+bool
+Adjacent::isEqual(Adjacent& adj)
+{
+  return (m_name == adj.getName()) &&
+         (m_connectingFace == adj.getConnectingFace()) &&
+         (std::abs(m_linkCost - adj.getLinkCost()) <
+          std::numeric_limits<double>::epsilon()) ;
+}
+
+std::ostream&
+operator<<(std::ostream& os, Adjacent& adj)
+{
+  os << "Adjacent : " << adj.getName()	<< endl;
+  os << "Connecting Face: " << adj.getConnectingFace() << endl;
+  os << "Link Cost: " << adj.getLinkCost() << endl;
+  os << "Status: " << adj.getStatus() << endl;
+  os << "Interest Timed out: " << adj.getInterestTimedOutNo() << endl;
+  return os;
+}
+
+} //namespace nlsr
diff --git a/src/adjacent.hpp b/src/adjacent.hpp
new file mode 100644
index 0000000..22066d1
--- /dev/null
+++ b/src/adjacent.hpp
@@ -0,0 +1,107 @@
+#include <string>
+
+#ifndef ADJACENT_HPP
+#define ADJACENT_HPP
+
+namespace nlsr {
+class Adjacent
+{
+
+public:
+  Adjacent()
+    : m_name("")
+    , m_connectingFace(0)
+    , m_linkCost(10.0)
+    , m_status(0)
+    , m_interestTimedOutNo(0)
+  {
+  }
+
+  Adjacent(const std::string& an)
+    : m_connectingFace(0)
+    , m_linkCost(0.0)
+    , m_status(0)
+    , m_interestTimedOutNo(0)
+  {
+    m_name = an;
+  }
+
+  Adjacent(const std::string& an, int cf, double lc, int s, int iton);
+
+  std::string
+  getName()
+  {
+    return m_name;
+  }
+
+  void
+  setName(const std::string& an)
+  {
+    m_name = an;
+  }
+
+  int
+  getConnectingFace()
+  {
+    return m_connectingFace;
+  }
+
+  void
+  setConnectingFace(int cf)
+  {
+    m_connectingFace = cf;
+  }
+
+  double
+  getLinkCost()
+  {
+    return m_linkCost;
+  }
+
+  void
+  setLinkCost(double lc)
+  {
+    m_linkCost = lc;
+  }
+
+  int
+  getStatus()
+  {
+    return m_status;
+  }
+
+  void
+  setStatus(int s)
+  {
+    m_status = s;
+  }
+
+  int
+  getInterestTimedOutNo()
+  {
+    return m_interestTimedOutNo;
+  }
+
+  void
+  setInterestTimedOutNo(int iton)
+  {
+    m_interestTimedOutNo = iton;
+  }
+
+  bool
+  isEqual(Adjacent& adj);
+
+private:
+  std::string m_name;
+  int m_connectingFace;
+  double m_linkCost;
+  int m_status;
+  int m_interestTimedOutNo;
+};
+
+std::ostream&
+operator<<(std::ostream& os, Adjacent& adj);
+
+} // namespace nlsr
+
+#endif //ADJACENT_HPP
diff --git a/src/adl.cpp b/src/adl.cpp
new file mode 100644
index 0000000..57b3307
--- /dev/null
+++ b/src/adl.cpp
@@ -0,0 +1,243 @@
+#include <iostream>
+#include <algorithm>
+
+#include "adl.hpp"
+#include "adjacent.hpp"
+#include "nlsr.hpp"
+
+
+namespace nlsr {
+
+Adl::Adl()
+{
+}
+
+Adl::~Adl()
+{
+}
+
+static bool
+adjacent_compare(Adjacent& adj1, Adjacent& adj2)
+{
+  return adj1.getName() == adj2.getName();
+}
+
+int
+Adl::insert(Adjacent& adj)
+{
+  std::list<Adjacent>::iterator it = find(adj.getName());
+  if (it != m_adjList.end())
+  {
+    return -1;
+  }
+  m_adjList.push_back(adj);
+  return 0;
+}
+
+void
+Adl::addAdjacentsFromAdl(Adl& adl)
+{
+  for (std::list<Adjacent>::iterator it = adl.getAdjList().begin();
+       it != adl.getAdjList().end(); ++it)
+  {
+    insert((*it));
+  }
+}
+
+int
+Adl::updateAdjacentStatus(string adjName, int s)
+{
+  std::list<Adjacent>::iterator it = find(adjName);
+  if (it == m_adjList.end())
+  {
+    return -1;
+  }
+  (*it).setStatus(s);
+  return 0;
+}
+
+Adjacent
+Adl::getAdjacent(string adjName)
+{
+  Adjacent adj(adjName);
+  std::list<Adjacent>::iterator it = find(adjName);
+  if (it != m_adjList.end())
+  {
+    return (*it);
+  }
+  return adj;
+}
+
+
+bool
+Adl::isEqual(Adl& adl)
+{
+  if (getSize() != adl.getSize())
+  {
+    return false;
+  }
+  m_adjList.sort(adjacent_compare);
+  adl.getAdjList().sort(adjacent_compare);
+  int equalAdjCount = 0;
+  std::list<Adjacent> adjList2 = adl.getAdjList();
+  std::list<Adjacent>::iterator it1;
+  std::list<Adjacent>::iterator it2;
+  for (it1 = m_adjList.begin(), it2 = adjList2.begin();
+       it1 != m_adjList.end(); it1++, it2++)
+  {
+    if (!(*it1).isEqual((*it2)))
+    {
+      break;
+    }
+    equalAdjCount++;
+  }
+  return equalAdjCount == getSize();
+}
+
+
+int
+Adl::updateAdjacentLinkCost(string adjName, double lc)
+{
+  std::list<Adjacent>::iterator it = find(adjName);
+  if (it == m_adjList.end())
+  {
+    return -1;
+  }
+  (*it).setLinkCost(lc);
+  return 0;
+}
+
+bool
+Adl::isNeighbor(string adjName)
+{
+  std::list<Adjacent>::iterator it = find(adjName);
+  if (it == m_adjList.end())
+  {
+    return false;
+  }
+  return true;
+}
+
+void
+Adl::incrementTimedOutInterestCount(string& neighbor)
+{
+  std::list<Adjacent>::iterator it = find(neighbor);
+  if (it == m_adjList.end())
+  {
+    return ;
+  }
+  (*it).setInterestTimedOutNo((*it).getInterestTimedOutNo() + 1);
+}
+
+void
+Adl::setTimedOutInterestCount(string& neighbor, int count)
+{
+  std::list<Adjacent>::iterator it = find(neighbor);
+  if (it != m_adjList.end())
+  {
+    (*it).setInterestTimedOutNo(count);
+  }
+}
+
+int
+Adl::getTimedOutInterestCount(string& neighbor)
+{
+  std::list<Adjacent>::iterator it = find(neighbor);
+  if (it == m_adjList.end())
+  {
+    return -1;
+  }
+  return (*it).getInterestTimedOutNo();
+}
+
+int
+Adl::getStatusOfNeighbor(string& neighbor)
+{
+  std::list<Adjacent>::iterator it = find(neighbor);
+  if (it == m_adjList.end())
+  {
+    return -1;
+  }
+  return (*it).getStatus();
+}
+
+void
+Adl::setStatusOfNeighbor(string& neighbor, int status)
+{
+  std::list<Adjacent>::iterator it = find(neighbor);
+  if (it != m_adjList.end())
+  {
+    (*it).setStatus(status);
+  }
+}
+
+std::list<Adjacent>&
+Adl::getAdjList()
+{
+  return m_adjList;
+}
+
+bool
+Adl::isAdjLsaBuildable(Nlsr& pnlsr)
+{
+  uint32_t nbrCount = 0;
+  for (std::list<Adjacent>::iterator it = m_adjList.begin();
+       it != m_adjList.end() ; it++)
+  {
+    if (((*it).getStatus() == 1))
+    {
+      nbrCount++;
+    }
+    else
+    {
+      if ((*it).getInterestTimedOutNo() >=
+          pnlsr.getConfParameter().getInterestRetryNumber())
+      {
+        nbrCount++;
+      }
+    }
+  }
+  if (nbrCount == m_adjList.size())
+  {
+    return true;
+  }
+  return false;
+}
+
+int
+Adl::getNumOfActiveNeighbor()
+{
+  int actNbrCount = 0;
+  for (std::list<Adjacent>::iterator it = m_adjList.begin();
+       it != m_adjList.end(); it++)
+  {
+    if (((*it).getStatus() == 1))
+    {
+      actNbrCount++;
+    }
+  }
+  return actNbrCount;
+}
+
+std::list<Adjacent>::iterator
+Adl::find(std::string adjName)
+{
+  Adjacent adj(adjName);
+  std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
+                                                  m_adjList.end(),
+                                                  bind(&adjacent_compare, _1, adj));
+  return it;
+}
+
+// used for debugging purpose
+void
+Adl::printAdl()
+{
+  for (std::list<Adjacent>::iterator it = m_adjList.begin();
+       it != m_adjList.end(); it++)
+  {
+    cout << (*it) << endl;
+  }
+}
+
+} //namespace nlsr
diff --git a/src/adl.hpp b/src/adl.hpp
new file mode 100644
index 0000000..8a7da9f
--- /dev/null
+++ b/src/adl.hpp
@@ -0,0 +1,90 @@
+#ifndef NLSR_ADL_HPP
+#define NLSR_ADL_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include "adjacent.hpp"
+#include <list>
+
+namespace nlsr {
+class Nlsr;
+
+class Adl
+{
+
+public:
+  Adl();
+  ~Adl();
+
+  int
+  insert(Adjacent& adj);
+
+  int
+  updateAdjacentStatus(std::string adjName, int s);
+
+  int
+  updateAdjacentLinkCost(std::string adjName, double lc);
+
+  std::list<Adjacent>&
+  getAdjList();
+
+  bool
+  isNeighbor(std::string adjName);
+
+  void
+  incrementTimedOutInterestCount(std::string& neighbor);
+
+  int
+  getTimedOutInterestCount(std::string& neighbor);
+
+  int
+  getStatusOfNeighbor(std::string& neighbor);
+
+  void
+  setStatusOfNeighbor(std::string& neighbor, int status);
+
+  void
+  setTimedOutInterestCount(std::string& neighbor, int count);
+
+  void
+  addAdjacentsFromAdl(Adl& adl);
+
+  bool
+  isAdjLsaBuildable(Nlsr& pnlsr);
+
+  int
+  getNumOfActiveNeighbor();
+
+  Adjacent
+  getAdjacent(std::string adjName);
+
+  bool
+  isEqual(Adl& adl);
+
+  int
+  getSize()
+  {
+    return m_adjList.size();
+  }
+
+  void
+  reset()
+  {
+    if (m_adjList.size() > 0)
+    {
+      m_adjList.clear();
+    }
+  }
+
+  void
+  printAdl();
+
+private:
+  std::list<Adjacent>::iterator
+  find(std::string adjName);
+
+private:
+  std::list<Adjacent> m_adjList;
+};
+
+} //namespace nlsr
+#endif //NLSR_ADL_HPP
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
diff --git a/src/conf-file-processor.cpp b/src/conf-file-processor.cpp
new file mode 100644
index 0000000..a19fa09
--- /dev/null
+++ b/src/conf-file-processor.cpp
@@ -0,0 +1,558 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cstdlib>
+#include <sstream>
+
+#include "conf-file-processor.hpp"
+#include "conf-parameter.hpp"
+#include "utility/tokenizer.hpp"
+#include "adjacent.hpp"
+
+
+namespace nlsr {
+
+using namespace std;
+
+int
+ConfFileProcessor::processConfFile(Nlsr& pnlsr)
+{
+  int ret = 0;
+  if (!m_confFileName.empty())
+  {
+    std::ifstream inputFile(m_confFileName.c_str());
+    if (inputFile.is_open())
+    {
+      for (string line; getline(inputFile, line);)
+      {
+        if (!line.empty())
+        {
+          if (line[0] != '#' && line[0] != '!')
+          {
+            ret = processConfCommand(pnlsr, line);
+            if (ret == -1)
+            {
+              break;
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      std::cerr << "Configuration file: (" << m_confFileName << ") does not exist :(";
+      std::cerr << endl;
+      ret = -1;
+    }
+  }
+  return ret;
+}
+
+
+int
+ConfFileProcessor::processConfCommand(Nlsr& pnlsr, string command)
+{
+  int ret = 0;
+  Tokenizer nt(command, " ");
+  if ((nt.getFirstToken() == "network"))
+  {
+    ret = processConfCommandNetwork(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "site-name"))
+  {
+    ret = processConfCommandSiteName(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "root-key-prefix"))
+  {
+    ret = processConfCommandRootKeyPrefix(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "router-name"))
+  {
+    ret = processConfCommandRouterName(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "ndnneighbor"))
+  {
+    ret = processConfCommandNdnNeighbor(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "link-cost"))
+  {
+    ret = processConfCommandLinkCost(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "ndnname"))
+  {
+    ret = processConfCommandNdnName(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "interest-retry-num"))
+  {
+    processConfCommandInterestRetryNumber(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "interest-resend-time"))
+  {
+    processConfCommandInterestResendTime(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "lsa-refresh-time"))
+  {
+    processConfCommandLsaRefreshTime(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "max-faces-per-prefix"))
+  {
+    processConfCommandMaxFacesPerPrefix(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "log-dir"))
+  {
+    processConfCommandLogDir(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "cert-dir"))
+  {
+    processConfCommandCertDir(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "detailed-logging"))
+  {
+    processConfCommandDetailedLogging(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "debugging"))
+  {
+    processConfCommandDebugging(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "chronosync-sync-prefix"))
+  {
+    processConfCommandChronosyncSyncPrefix(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "hyperbolic-cordinate"))
+  {
+    processConfCommandHyperbolicCordinate(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "hyperbolic-routing"))
+  {
+    processConfCommandIsHyperbolicCalc(pnlsr, nt.getRestOfLine());
+  }
+  else if ((nt.getFirstToken() == "tunnel-type"))
+  {
+    processConfCommandTunnelType(pnlsr, nt.getRestOfLine());
+  }
+  else
+  {
+    cout << "Wrong configuration Command: " << nt.getFirstToken() << endl;
+  }
+  return ret;
+}
+
+int
+ConfFileProcessor::processConfCommandNetwork(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Network can not be null or empty :( !" << endl;
+    return -1;
+  }
+  else
+  {
+    if (command[command.size() - 1] == '/')
+    {
+      command.erase(command.size() - 1);
+    }
+    if (command[0] == '/')
+    {
+      command.erase(0, 1);
+    }
+    pnlsr.getConfParameter().setNetwork(command);
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandSiteName(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << "Site name can not be null or empty :( !" << endl;
+    return -1;
+  }
+  else
+  {
+    if (command[command.size() - 1] == '/')
+    {
+      command.erase(command.size() - 1);
+    }
+    if (command[0] == '/')
+    {
+      command.erase(0, 1);
+    }
+    pnlsr.getConfParameter().setSiteName(command);
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << "Root Key Prefix can not be null or empty :( !" << endl;
+    return -1;
+  }
+  else
+  {
+    if (command[command.size() - 1] == '/')
+    {
+      command.erase(command.size() - 1);
+    }
+    if (command[0] == '/')
+    {
+      command.erase(0, 1);
+    }
+    pnlsr.getConfParameter().setRootKeyPrefix(command);
+  }
+  return 0;
+}
+
+
+int
+ConfFileProcessor::processConfCommandRouterName(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Router name can not be null or empty :( !" << endl;
+    return -1;
+  }
+  else
+  {
+    if (command[command.size() - 1] == '/')
+    {
+      command.erase(command.size() - 1);
+    }
+    if (command[0] == '/')
+    {
+      command.erase(0, 1);
+    }
+    pnlsr.getConfParameter().setRouterName(command);
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandInterestRetryNumber(Nlsr& pnlsr,
+                                                         string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [interest-retry-num n]" << endl;
+  }
+  else
+  {
+    int irn;
+    stringstream ss(command.c_str());
+    ss >> irn;
+    if (irn >= 1 && irn <= 5)
+    {
+      pnlsr.getConfParameter().setInterestRetryNumber(irn);
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandInterestResendTime(Nlsr& pnlsr,
+                                                        string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [interest-resend-time s]" << endl;
+  }
+  else
+  {
+    int irt;
+    stringstream ss(command.c_str());
+    ss >> irt;
+    if (irt >= 1 && irt <= 20)
+    {
+      pnlsr.getConfParameter().setInterestResendTime(irt);
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [interest-resend-time s]" << endl;
+  }
+  else
+  {
+    int lrt;
+    stringstream ss(command.c_str());
+    ss >> lrt;
+    if (lrt >= 240 && lrt <= 7200)
+    {
+      pnlsr.getConfParameter().setLsaRefreshTime(lrt);
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr,
+                                                       string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [max-faces-per-prefix n]" << endl;
+  }
+  else
+  {
+    int mfpp;
+    stringstream ss(command.c_str());
+    ss >> mfpp;
+    if (mfpp >= 0 && mfpp <= 60)
+    {
+      pnlsr.getConfParameter().setMaxFacesPerPrefix(mfpp);
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandTunnelType(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [tunnel-type tcp/udp]!" << endl;
+  }
+  else
+  {
+    if (command == "tcp" || command == "TCP")
+    {
+      pnlsr.getConfParameter().setTunnelType(1);
+    }
+    else if (command == "udp" || command == "UDP")
+    {
+      pnlsr.getConfParameter().setTunnelType(0);
+    }
+    else
+    {
+      cerr << " Wrong command format ! [tunnel-type tcp/udp]!" << endl;
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr,
+                                                          string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [chronosync-sync-prefix name/prefix]!" << endl;
+  }
+  else
+  {
+    pnlsr.getConfParameter().setChronosyncSyncPrefix(command);
+  }
+  return 0;
+}
+
+
+int
+ConfFileProcessor::processConfCommandLogDir(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [log-dir /path/to/log/dir]!" << endl;
+  }
+  else
+  {
+    pnlsr.getConfParameter().setLogDir(command);
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandCertDir(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [cert-dir /path/to/cert/dir]!" << endl;
+  }
+  else
+  {
+    pnlsr.getConfParameter().setCertDir(command);
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandDebugging(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [debugging on/of]!" << endl;
+  }
+  else
+  {
+    if (command == "on" || command == "ON")
+    {
+      pnlsr.getConfParameter().setDebugging(1);
+    }
+    else if (command == "off" || command == "off")
+    {
+      pnlsr.getConfParameter().setDebugging(0);
+    }
+    else
+    {
+      cerr << " Wrong command format ! [debugging on/off]!" << endl;
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandDetailedLogging(Nlsr& pnlsr,
+                                                     string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [detailed-logging on/off]!" << endl;
+  }
+  else
+  {
+    if (command == "on" || command == "ON")
+    {
+      pnlsr.getConfParameter().setDetailedLogging(1);
+    }
+    else if (command == "off" || command == "off")
+    {
+      pnlsr.getConfParameter().setDetailedLogging(0);
+    }
+    else
+    {
+      cerr << " Wrong command format ! [detailed-logging on/off]!" << endl;
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandIsHyperbolicCalc(Nlsr& pnlsr,
+                                                      string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [hyperbolic-routing on/off/dry-run]!" << endl;
+  }
+  else
+  {
+    if (command == "on" || command == "ON")
+    {
+      pnlsr.getConfParameter().setIsHyperbolicCalc(1);
+    }
+    else if (command == "dry-run" || command == "DRY-RUN")
+    {
+      pnlsr.getConfParameter().setIsHyperbolicCalc(2);
+    }
+    else if (command == "off" || command == "off")
+    {
+      pnlsr.getConfParameter().setIsHyperbolicCalc(0);
+    }
+    else
+    {
+      cerr << " Wrong command format ! [hyperbolic-routing on/off/dry-run]!" << endl;
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandHyperbolicCordinate(Nlsr& pnlsr,
+                                                         string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [hyperbolic-cordinate r 0]!" << endl;
+    if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0)
+    {
+      return -1;
+    }
+  }
+  else
+  {
+    Tokenizer nt(command, " ");
+    stringstream ssr(nt.getFirstToken().c_str());
+    stringstream sst(nt.getRestOfLine().c_str());
+    double r, theta;
+    ssr >> r;
+    sst >> theta;
+    pnlsr.getConfParameter().setCorR(r);
+    pnlsr.getConfParameter().setCorTheta(theta);
+  }
+  return 0;
+}
+
+
+int
+ConfFileProcessor::processConfCommandNdnNeighbor(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!" << endl;
+  }
+  else
+  {
+    Tokenizer nt(command, " ");
+    if (nt.getRestOfLine().empty())
+    {
+      cerr << " Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!" << endl;
+      return 0;
+    }
+    else
+    {
+      stringstream sst(nt.getRestOfLine().c_str());
+      int faceId;
+      sst >> faceId;
+      Adjacent adj(nt.getFirstToken(), faceId, 0.0, 0, 0);
+      pnlsr.getAdl().insert(adj);
+    }
+  }
+  return 0;
+}
+
+int
+ConfFileProcessor::processConfCommandNdnName(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [ndnname name/prefix]!" << endl;
+  }
+  else
+  {
+    pnlsr.getNpl().insert(command);
+  }
+  return 0;
+}
+
+
+int
+ConfFileProcessor::processConfCommandLinkCost(Nlsr& pnlsr, string command)
+{
+  if (command.empty())
+  {
+    cerr << " Wrong command format ! [link-cost nbr/name cost]!" << endl;
+    if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0)
+    {
+      return -1;
+    }
+  }
+  else
+  {
+    Tokenizer nt(command, " ");
+    stringstream sst(nt.getRestOfLine().c_str());
+    double cost;
+    sst >> cost;
+    pnlsr.getAdl().updateAdjacentLinkCost(nt.getFirstToken(), cost);
+  }
+  return 0;
+}
+
+} //namespace nlsr
+
diff --git a/src/conf-file-processor.hpp b/src/conf-file-processor.hpp
new file mode 100644
index 0000000..a17ba12
--- /dev/null
+++ b/src/conf-file-processor.hpp
@@ -0,0 +1,89 @@
+#ifndef CONF_PROCESSOR_HPP
+#define CONF_PROCESSOR_HPP
+
+#include "nlsr.hpp"
+
+namespace nlsr {
+class ConfFileProcessor
+{
+public:
+  ConfFileProcessor()
+    : m_confFileName()
+  {
+  }
+
+  ConfFileProcessor(const string& cfile)
+  {
+    m_confFileName = cfile;
+  }
+
+  int processConfFile(Nlsr& pnlsr);
+
+private:
+  int
+  processConfCommand(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandNetwork(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandSiteName(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandRouterName(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandInterestRetryNumber(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandInterestResendTime(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandTunnelType(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandLogDir(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandCertDir(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandDebugging(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandHyperbolicCordinate(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandNdnNeighbor(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandNdnName(Nlsr& pnlsr, string command);
+
+  int
+  processConfCommandLinkCost(Nlsr& pnlsr, string command);
+
+
+private:
+  string m_confFileName;
+};
+
+} //namespace nlsr
+#endif //CONF_PROCESSOR_HPP
diff --git a/src/conf-parameter.cpp b/src/conf-parameter.cpp
new file mode 100644
index 0000000..2bb337f
--- /dev/null
+++ b/src/conf-parameter.cpp
@@ -0,0 +1,31 @@
+#include <iostream>
+#include "conf-parameter.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+ostream&
+operator<<(ostream& os, ConfParameter& cfp)
+{
+  os  << "Router Name: " << cfp.getRouterName() << endl;
+  os  << "Site Name: " << cfp.getSiteName() << endl;
+  os  << "Network: " << cfp.getNetwork() << endl;
+  os  << "Router Prefix: " << cfp.getRouterPrefix() << endl;
+  os  << "ChronoSync sync Prifex: " << cfp.getChronosyncSyncPrefix() << endl;
+  os  << "Interest Retry number: " << cfp.getInterestRetryNumber() << endl;
+  os  << "Interest Resend second: " << cfp.getInterestResendTime() << endl;
+  os  << "Info Interest Interval: " << cfp.getInfoInterestInterval() << endl;
+  os  << "LSA refresh time: " << cfp.getLsaRefreshTime() << endl;
+  os  << "Max Faces Per Prefix: " << cfp.getMaxFacesPerPrefix() << endl;
+  os  << "Log Dir: " << cfp.getLogDir() << endl;
+  os  << "Detalied logging: " << cfp.getDetailedLogging() << endl;
+  os  << "Debugging: " << cfp.getDebugging() << endl;
+  os  << "Hyperbolic ROuting: " << cfp.getIsHyperbolicCalc() << endl;
+  os  << "Hyp R: " << cfp.getCorR() << endl;
+  os  << "Hyp theta: " << cfp.getCorTheta() << endl;
+  os  << "Tunnel Type: " << cfp.getTunnelType() << endl;
+  return  os;
+}
+
+} //namespace nlsr
diff --git a/src/conf-parameter.hpp b/src/conf-parameter.hpp
new file mode 100644
index 0000000..7dc8c76
--- /dev/null
+++ b/src/conf-parameter.hpp
@@ -0,0 +1,336 @@
+#ifndef CONF_PARAM_HPP
+#define CONF_PARAM_HPP
+
+#include <iostream>
+
+namespace nlsr {
+class ConfParameter
+{
+
+public:
+  ConfParameter()
+    : m_chronosyncSyncPrefix("ndn/nlsr/sync")
+    , m_chronosyncLsaPrefix("/ndn/nlsr/LSA")
+    , m_rootKeyPrefix("/ndn/keys")
+    , m_interestRetryNumber(3)
+    , m_interestResendTime(5)
+    , m_infoInterestInterval(60)
+    , m_lsaRefreshTime(1800)
+    , m_routerDeadInterval(3600)
+    , m_maxFacesPerPrefix(0)
+    , m_tunnelType(0)
+    , m_detailedLogging(0)
+    , m_certDir()
+    , m_debugging(0)
+    , m_seqFileDir()
+    , m_isHyperbolicCalc(0)
+    , m_corR(0)
+    , m_corTheta(0)
+  {}
+
+  void
+  setRouterName(const std::string& rn)
+  {
+    m_routerName = rn;
+  }
+
+  std::string
+  getRouterName()
+  {
+    return m_routerName;
+  }
+
+  void
+  setSiteName(const std::string& sn)
+  {
+    m_siteName = sn;
+  }
+
+  std::string
+  getSiteName()
+  {
+    return m_siteName;
+  }
+
+  void
+  setNetwork(const std::string& nn)
+  {
+    m_network = nn;
+  }
+
+  std::string
+  getNetwork()
+  {
+    return m_network;
+  }
+
+  void
+  buildRouterPrefix()
+  {
+    m_routerPrefix = "/" + m_network + "/" + m_siteName + "/" + m_routerName;
+  }
+
+  std::string
+  getRouterPrefix()
+  {
+    return m_routerPrefix;
+  }
+
+  std::string
+  getRootKeyPrefix()
+  {
+    return m_rootKeyPrefix;
+  }
+
+  void
+  setRootKeyPrefix(std::string rkp)
+  {
+    m_rootKeyPrefix = rkp;
+  }
+
+  void
+  setInterestRetryNumber(int irn)
+  {
+    m_interestRetryNumber = irn;
+  }
+
+  int
+  getInterestRetryNumber()
+  {
+    return m_interestRetryNumber;
+  }
+
+  void
+  setInterestResendTime(int irt)
+  {
+    m_interestResendTime = irt;
+  }
+
+  int
+  getInterestResendTime()
+  {
+    return m_interestResendTime;
+  }
+
+  void
+  setLsaRefreshTime(int lrt)
+  {
+    m_lsaRefreshTime = lrt;
+    m_routerDeadInterval = 2 * m_lsaRefreshTime;
+  }
+
+  int
+  getLsaRefreshTime()
+  {
+    return m_lsaRefreshTime;
+  }
+
+  void
+  setRouterDeadInterval(int rdt)
+  {
+    m_routerDeadInterval = rdt;
+  }
+
+  long int
+  getRouterDeadInterval()
+  {
+    return m_routerDeadInterval;
+  }
+
+  void
+  setMaxFacesPerPrefix(int mfpp)
+  {
+    m_maxFacesPerPrefix = mfpp;
+  }
+
+  int
+  getMaxFacesPerPrefix()
+  {
+    return m_maxFacesPerPrefix;
+  }
+
+  void
+  setLogDir(std::string ld)
+  {
+    m_logDir = ld;
+  }
+
+  std::string
+  getLogDir()
+  {
+    return m_logDir;
+  }
+
+  void
+  setCertDir(std::string cd)
+  {
+    m_certDir = cd;
+  }
+
+  std::string
+  getCertDir()
+  {
+    return m_certDir;
+  }
+
+  void
+  setSeqFileDir(std::string ssfd)
+  {
+    m_seqFileDir = ssfd;
+  }
+
+  std::string
+  getSeqFileDir()
+  {
+    return m_seqFileDir;
+  }
+
+  void
+  setDetailedLogging(int dl)
+  {
+    m_detailedLogging = dl;
+  }
+
+  int
+  getDetailedLogging()
+  {
+    return m_detailedLogging;
+  }
+
+  void
+  setDebugging(int d)
+  {
+    m_debugging = d;
+  }
+
+  int
+  getDebugging()
+  {
+    return m_debugging;
+  }
+
+  void
+  setIsHyperbolicCalc(int ihc)
+  {
+    m_isHyperbolicCalc = ihc;
+  }
+
+  int
+  getIsHyperbolicCalc()
+  {
+    return m_isHyperbolicCalc;
+  }
+
+  void
+  setCorR(double cr)
+  {
+    m_corR = cr;
+  }
+
+  double
+  getCorR()
+  {
+    return m_corR;
+  }
+
+  void
+  setCorTheta(double ct)
+  {
+    m_corTheta = ct;
+  }
+
+  double
+  getCorTheta()
+  {
+    return m_corTheta;
+  }
+
+  void
+  setTunnelType(int tt)
+  {
+    m_tunnelType = tt;
+  }
+
+  int
+  getTunnelType()
+  {
+    return m_tunnelType;
+  }
+
+  void
+  setChronosyncSyncPrefix(const std::string& csp)
+  {
+    m_chronosyncSyncPrefix = csp;
+  }
+
+  std::string
+  getChronosyncSyncPrefix()
+  {
+    return m_chronosyncSyncPrefix;
+  }
+
+  void
+  setChronosyncLsaPrefix(std::string clp)
+  {
+    m_chronosyncLsaPrefix = clp;
+  }
+
+  std::string
+  getChronosyncLsaPrefix()
+  {
+    return m_chronosyncLsaPrefix;
+  }
+
+  int
+  getInfoInterestInterval()
+  {
+    return m_infoInterestInterval;
+  }
+
+  void
+  setInfoInterestInterval(int iii)
+  {
+    m_infoInterestInterval = iii;
+  }
+
+private:
+  std::string m_routerName;
+  std::string m_siteName;
+  std::string m_network;
+
+  std::string m_routerPrefix;
+  std::string m_lsaRouterPrefix;
+
+  std::string m_chronosyncSyncPrefix;
+  std::string m_chronosyncLsaPrefix;
+  std::string m_rootKeyPrefix;
+
+  int m_interestRetryNumber;
+  int m_interestResendTime;
+  int m_infoInterestInterval;
+  int m_lsaRefreshTime;
+  int m_routerDeadInterval;
+
+  int m_maxFacesPerPrefix;
+  int m_tunnelType;
+  int m_detailedLogging;
+
+  std::string m_certDir;
+  int m_debugging;
+  std::string m_seqFileDir;
+
+  int m_isHyperbolicCalc;
+  double m_corR;
+  double m_corTheta;
+
+  std::string m_logFile;
+  std::string m_logDir;
+
+};
+
+std::ostream&
+operator<<(std::ostream& os, ConfParameter& cfp);
+
+} // namespace nlsr
+
+#endif //CONF_PARAM_HPP
diff --git a/src/lsa.cpp b/src/lsa.cpp
new file mode 100644
index 0000000..0bd450c
--- /dev/null
+++ b/src/lsa.cpp
@@ -0,0 +1,330 @@
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+#include "nlsr.hpp"
+#include "lsa.hpp"
+#include "npl.hpp"
+#include "adjacent.hpp"
+#include "utility/tokenizer.hpp"
+
+
+namespace nlsr {
+
+using namespace std;
+
+
+string
+NameLsa::getKey()
+{
+  string key;
+  key = m_origRouter + "/" + boost::lexical_cast<std::string>(1);
+  return key;
+}
+
+NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
+{
+  m_origRouter = origR;
+  m_lsType = lst;
+  m_lsSeqNo = lsn;
+  m_lifeTime = lt;
+  std::list<string> nl = npl.getNameList();
+  for (std::list<string>::iterator it = nl.begin(); it != nl.end(); it++)
+  {
+    addName((*it));
+  }
+}
+
+string
+NameLsa::getData()
+{
+  string nameLsaData;
+  nameLsaData = m_origRouter + "|" + boost::lexical_cast<std::string>(1) + "|"
+                + boost::lexical_cast<std::string>(m_lsSeqNo) + "|"
+                + boost::lexical_cast<std::string>(m_lifeTime);
+  nameLsaData += "|";
+  nameLsaData += boost::lexical_cast<std::string>(m_npl.getSize());
+  std::list<string> nl = m_npl.getNameList();
+  for (std::list<string>::iterator it = nl.begin(); it != nl.end(); it++)
+  {
+    nameLsaData += "|";
+    nameLsaData += (*it);
+  }
+  return nameLsaData + "|";
+}
+
+bool
+NameLsa::initializeFromContent(string content)
+{
+  uint32_t numName = 0;
+  Tokenizer nt(content, "|");
+  m_origRouter = nt.getNextToken();
+  if (m_origRouter.empty())
+  {
+    return false;
+  }
+  try
+  {
+    m_lsType = boost::lexical_cast<uint8_t>(nt.getNextToken());
+    m_lsSeqNo = boost::lexical_cast<uint32_t>(nt.getNextToken());
+    m_lifeTime = boost::lexical_cast<uint32_t>(nt.getNextToken());
+    numName = boost::lexical_cast<uint32_t>(nt.getNextToken());
+  }
+  catch (std::exception& e)
+  {
+    return false;
+  }
+  for (uint32_t i = 0; i < numName; i++)
+  {
+    string name = nt.getNextToken();
+    addName(name);
+  }
+  return true;
+}
+
+void
+NameLsa::writeLog()
+{
+}
+
+std::ostream&
+operator<<(std::ostream& os, NameLsa& nLsa)
+{
+  os << "Name Lsa: " << endl;
+  os << "  Origination Router: " << nLsa.getOrigRouter() << endl;
+  os << "  Ls Type: " << (unsigned short)nLsa.getLsType() << endl;
+  os << "  Ls Seq No: " << (unsigned int)nLsa.getLsSeqNo() << endl;
+  os << "  Ls Lifetime: " << (unsigned int)nLsa.getLifeTime() << endl;
+  os << "  Names: " << endl;
+  int i = 1;
+  std::list<string> nl = nLsa.getNpl().getNameList();
+  for (std::list<string>::iterator it = nl.begin(); it != nl.end(); it++)
+  {
+    os << "    Name " << i << ": " << (*it) << endl;
+  }
+  return os;
+}
+
+
+
+CorLsa::CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
+               , double r, double theta)
+{
+  m_origRouter = origR;
+  m_lsType = lst;
+  m_lsSeqNo = lsn;
+  m_lifeTime = lt;
+  m_corRad = r;
+  m_corTheta = theta;
+}
+
+string
+CorLsa::getKey()
+{
+  string key;
+  key = m_origRouter + "/" + boost::lexical_cast<std::string>(3);
+  return key;
+}
+
+bool
+CorLsa::isEqual(CorLsa& clsa)
+{
+  return (std::abs(m_corRad - clsa.getCorRadius()) <
+          std::numeric_limits<double>::epsilon()) &&
+         (std::abs(m_corTheta - clsa.getCorTheta()) <
+          std::numeric_limits<double>::epsilon());
+}
+
+string
+CorLsa::getData()
+{
+  string corLsaData;
+  corLsaData = m_origRouter + "|";
+  corLsaData += (boost::lexical_cast<std::string>(3) + "|");
+  corLsaData += (boost::lexical_cast<std::string>(m_lsSeqNo) + "|");
+  corLsaData += (boost::lexical_cast<std::string>(m_lifeTime) + "|");
+  corLsaData += (boost::lexical_cast<std::string>(m_corRad) + "|");
+  corLsaData += (boost::lexical_cast<std::string>(m_corTheta) + "|");
+  return corLsaData;
+}
+
+bool
+CorLsa::initializeFromContent(string content)
+{
+  Tokenizer nt(content, "|");
+  m_origRouter = nt.getNextToken();
+  if (m_origRouter.empty())
+  {
+    return false;
+  }
+  try
+  {
+    m_lsType   = boost::lexical_cast<uint8_t>(nt.getNextToken());
+    m_lsSeqNo  = boost::lexical_cast<uint32_t>(nt.getNextToken());
+    m_lifeTime = boost::lexical_cast<uint32_t>(nt.getNextToken());
+    m_corRad   = boost::lexical_cast<double>(nt.getNextToken());
+    m_corTheta = boost::lexical_cast<double>(nt.getNextToken());
+  }
+  catch (std::exception& e)
+  {
+    return false;
+  }
+  return true;
+}
+
+std::ostream&
+operator<<(std::ostream& os, CorLsa& cLsa)
+{
+  os << "Cor Lsa: " << endl;
+  os << "  Origination Router: " << cLsa.getOrigRouter() << endl;
+  os << "  Ls Type: " << (unsigned short)cLsa.getLsType() << endl;
+  os << "  Ls Seq No: " << (unsigned int)cLsa.getLsSeqNo() << endl;
+  os << "  Ls Lifetime: " << (unsigned int)cLsa.getLifeTime() << endl;
+  os << "    Hyperbolic Radius: " << cLsa.getCorRadius() << endl;
+  os << "    Hyperbolic Theta: " << cLsa.getCorTheta() << endl;
+  return os;
+}
+
+
+AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
+               uint32_t nl , Adl padl)
+{
+  m_origRouter = origR;
+  m_lsType = lst;
+  m_lsSeqNo = lsn;
+  m_lifeTime = lt;
+  m_noLink = nl;
+  std::list<Adjacent> al = padl.getAdjList();
+  for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++)
+  {
+    if ((*it).getStatus() == 1)
+    {
+      addAdjacent((*it));
+    }
+  }
+}
+
+string
+AdjLsa::getKey()
+{
+  string key;
+  key = m_origRouter + "/" + boost::lexical_cast<std::string>(2);
+  return key;
+}
+
+bool
+AdjLsa::isEqual(AdjLsa& alsa)
+{
+  return m_adl.isEqual(alsa.getAdl());
+}
+
+
+string
+AdjLsa::getData()
+{
+  string adjLsaData;
+  adjLsaData = m_origRouter + "|" + boost::lexical_cast<std::string>(2) + "|"
+               + boost::lexical_cast<std::string>(m_lsSeqNo) + "|"
+               + boost::lexical_cast<std::string>(m_lifeTime);
+  adjLsaData += "|";
+  adjLsaData += boost::lexical_cast<std::string>(m_adl.getSize());
+  std::list<Adjacent> al = m_adl.getAdjList();
+  for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++)
+  {
+    adjLsaData += "|";
+    adjLsaData += (*it).getName();
+    adjLsaData += "|";
+    adjLsaData += boost::lexical_cast<std::string>((*it).getConnectingFace());
+    adjLsaData += "|";
+    adjLsaData += boost::lexical_cast<std::string>((*it).getLinkCost());
+  }
+  return adjLsaData + "|";
+}
+
+bool
+AdjLsa::initializeFromContent(string content)
+{
+  uint32_t numLink = 0;
+  Tokenizer nt(content, "|");
+  m_origRouter = nt.getNextToken();
+  if (m_origRouter.empty())
+  {
+    return false;
+  }
+  try
+  {
+    m_lsType   = boost::lexical_cast<uint8_t>(nt.getNextToken());
+    m_lsSeqNo  = boost::lexical_cast<uint32_t>(nt.getNextToken());
+    m_lifeTime = boost::lexical_cast<uint32_t>(nt.getNextToken());
+    numLink    = boost::lexical_cast<uint32_t>(nt.getNextToken());
+  }
+  catch (std::exception& e)
+  {
+    return false;
+  }
+  for (uint32_t i = 0; i < numLink; i++)
+  {
+    try
+    {
+      string adjName = nt.getNextToken();
+      int connectingFace = boost::lexical_cast<int>(nt.getNextToken());
+      double linkCost = boost::lexical_cast<double>(nt.getNextToken());
+      Adjacent adjacent(adjName, connectingFace, linkCost, 0, 0);
+      addAdjacent(adjacent);
+    }
+    catch (std::exception& e)
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+void
+AdjLsa::addNptEntries(Nlsr& pnlsr)
+{
+  if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+  {
+    pnlsr.getNpt().addNpteByDestName(getOrigRouter(), getOrigRouter(), pnlsr);
+  }
+}
+
+
+void
+AdjLsa::removeNptEntries(Nlsr& pnlsr)
+{
+  if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+  {
+    pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(), pnlsr);
+  }
+}
+
+
+
+std::ostream&
+operator<<(std::ostream& os, AdjLsa& aLsa)
+{
+  os << "Adj Lsa: " << endl;
+  os << "  Origination Router: " << aLsa.getOrigRouter() << endl;
+  os << "  Ls Type: " << (unsigned short)aLsa.getLsType() << endl;
+  os << "  Ls Seq No: " << (unsigned int)aLsa.getLsSeqNo() << endl;
+  os << "  Ls Lifetime: " << (unsigned int)aLsa.getLifeTime() << endl;
+  os << "  No Link: " << (unsigned int)aLsa.getNoLink() << endl;
+  os << "  Adjacents: " << endl;
+  int i = 1;
+  std::list<Adjacent> al = aLsa.getAdl().getAdjList();
+  for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++)
+  {
+    os << "    Adjacent " << i << ": " << endl;
+    os << "      Adjacent Name: " << (*it).getName() << endl;
+    os << "      Connecting Face: " << (*it).getConnectingFace() << endl;
+    os << "      Link Cost: " << (*it).getLinkCost() << endl;
+  }
+  return os;
+}
+
+}//namespace nlsr
diff --git a/src/lsa.hpp b/src/lsa.hpp
new file mode 100644
index 0000000..23ff395
--- /dev/null
+++ b/src/lsa.hpp
@@ -0,0 +1,266 @@
+#ifndef NLSR_LSA_HPP
+#define NLSR_LSA_HPP
+
+#include <ndn-cpp-dev/util/scheduler.hpp>
+#include "adjacent.hpp"
+#include "npl.hpp"
+#include "adl.hpp"
+
+namespace nlsr {
+class Lsa
+{
+public:
+  Lsa()
+    : m_origRouter()
+    , m_lsSeqNo()
+    , m_lifeTime()
+    , m_expiringEventId()
+  {
+  }
+
+
+  void
+  setLsType(uint8_t lst)
+  {
+    m_lsType = lst;
+  }
+
+  uint8_t
+  getLsType() const
+  {
+    return m_lsType;
+  }
+
+  void
+  setLsSeqNo(uint32_t lsn)
+  {
+    m_lsSeqNo = lsn;
+  }
+
+  uint32_t
+  getLsSeqNo() const
+  {
+    return m_lsSeqNo;
+  }
+
+  std::string
+  getOrigRouter() const
+  {
+    return m_origRouter;
+  }
+
+  void
+  setOrigRouter(const std::string& org)
+  {
+    m_origRouter = org;
+  }
+
+  uint32_t
+  getLifeTime() const
+  {
+    return m_lifeTime;
+  }
+
+  void
+  setLifeTime(uint32_t lt)
+  {
+    m_lifeTime = lt;
+  }
+
+  void
+  setExpiringEventId(const ndn::EventId leei)
+  {
+    m_expiringEventId = leei;
+  }
+
+  ndn::EventId
+  getExpiringEventId() const
+  {
+    return m_expiringEventId;
+  }
+
+protected:
+  std::string m_origRouter;
+  uint8_t m_lsType;
+  uint32_t m_lsSeqNo;
+  uint32_t m_lifeTime;
+  ndn::EventId m_expiringEventId;
+};
+
+class NameLsa: public Lsa
+{
+public:
+  NameLsa()
+    : Lsa()
+    , m_npl()
+  {
+    setLsType(1);
+  }
+
+  NameLsa(std::string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
+
+  Npl&
+  getNpl()
+  {
+    return m_npl;
+  }
+
+  void
+  addName(std::string& name)
+  {
+    m_npl.insert(name);
+  }
+
+  void
+  removeName(std::string& name)
+  {
+    m_npl.remove(name);
+  }
+
+  std::string
+  getKey();
+
+  std::string
+  getData();
+
+  bool
+  initializeFromContent(std::string content);
+
+  void
+  writeLog();
+
+private:
+  Npl m_npl;
+
+};
+
+std::ostream&
+operator<<(std::ostream& os, NameLsa& nLsa);
+
+class AdjLsa: public Lsa
+{
+public:
+  AdjLsa()
+    : Lsa()
+    , m_adl()
+  {
+    setLsType(2);
+  }
+
+  AdjLsa(std::string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
+         uint32_t nl , Adl padl);
+
+  Adl&
+  getAdl()
+  {
+    return m_adl;
+  }
+
+  void
+  addAdjacent(Adjacent adj)
+  {
+    m_adl.insert(adj);
+  }
+
+  std::string
+  getKey();
+
+  std::string
+  getData();
+
+  bool
+  initializeFromContent(std::string content);
+
+  uint32_t
+  getNoLink()
+  {
+    return m_noLink;
+  }
+
+  bool
+  isEqual(AdjLsa& alsa);
+
+  void
+  addNptEntries(Nlsr& pnlsr);
+
+  void
+  removeNptEntries(Nlsr& pnlsr);
+
+private:
+  uint32_t m_noLink;
+  Adl m_adl;
+};
+
+std::ostream&
+operator<<(std::ostream& os, AdjLsa& aLsa);
+
+class CorLsa: public Lsa
+{
+public:
+  CorLsa()
+    : Lsa()
+    , m_corRad(0)
+    , m_corTheta(0)
+  {
+    setLsType(3);
+  }
+
+  CorLsa(std::string origR, uint8_t lst, uint32_t lsn, uint32_t lt
+         , double r, double theta);
+
+  std::string
+  getKey();
+
+  std::string
+  getData();
+
+  bool
+  initializeFromContent(std::string content);
+
+  double
+  getCorRadius()
+  {
+    if (m_corRad >= 0)
+    {
+      return m_corRad;
+    }
+    else
+    {
+      return -1;
+    }
+  }
+
+  void
+  setCorRadius(double cr)
+  {
+    m_corRad = cr;
+  }
+
+  double
+  getCorTheta()
+  {
+    return m_corTheta;
+  }
+
+  void
+  setCorTheta(double ct)
+  {
+    m_corTheta = ct;
+  }
+
+  bool
+  isEqual(CorLsa& clsa);
+
+private:
+  double m_corRad;
+  double m_corTheta;
+
+};
+
+std::ostream&
+operator<<(std::ostream& os, CorLsa& cLsa);
+
+
+}//namespace nlsr
+
+#endif //NLSR_LSA_HPP
diff --git a/src/lsdb.cpp b/src/lsdb.cpp
new file mode 100644
index 0000000..de65646
--- /dev/null
+++ b/src/lsdb.cpp
@@ -0,0 +1,750 @@
+#include <string>
+#include <utility>
+#include "lsdb.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+void
+Lsdb::cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid)
+{
+  pnlsr.getScheduler().cancelEvent(eid);
+}
+
+static bool
+nameLsaCompareByKey(NameLsa& nlsa1, string& key)
+{
+  return nlsa1.getKey() == key;
+}
+
+
+bool
+Lsdb::buildAndInstallOwnNameLsa(Nlsr& pnlsr)
+{
+  NameLsa nameLsa(pnlsr.getConfParameter().getRouterPrefix()
+                  , 1
+                  , pnlsr.getSm().getNameLsaSeq() + 1
+                  , pnlsr.getConfParameter().getRouterDeadInterval()
+                  , pnlsr.getNpl());
+  pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq() + 1);
+  return installNameLsa(pnlsr, nameLsa);
+}
+
+std::pair<NameLsa&, bool>
+Lsdb::getNameLsa(string key)
+{
+  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
+                                                 m_nameLsdb.end(),
+                                                 bind(nameLsaCompareByKey, _1, key));
+  if (it != m_nameLsdb.end())
+  {
+    return std::make_pair(boost::ref((*it)), true);
+  }
+  NameLsa nlsa;
+  return std::make_pair(boost::ref(nlsa), false);
+}
+
+bool
+Lsdb::isNameLsaNew(string key, uint64_t seqNo)
+{
+  std::pair<NameLsa&, bool>  nameLsaCheck = getNameLsa(key);
+  if (nameLsaCheck.second)
+  {
+    if (nameLsaCheck.first.getLsSeqNo() < seqNo)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+ndn::EventId
+Lsdb::scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+{
+  return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
+                                            ndn::bind(&Lsdb::exprireOrRefreshNameLsa,
+                                                      this, boost::ref(pnlsr), key, seqNo));
+}
+
+bool
+Lsdb::installNameLsa(Nlsr& pnlsr, NameLsa& nlsa)
+{
+  int timeToExpire = m_lsaRefreshTime;
+  std::pair<NameLsa&, bool> chkNameLsa = getNameLsa(nlsa.getKey());
+  if (!chkNameLsa.second)
+  {
+    addNameLsa(nlsa);
+    nlsa.writeLog();
+    printNameLsdb();
+    if (nlsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      pnlsr.getNpt().addNpteByDestName(nlsa.getOrigRouter(), nlsa.getOrigRouter(),
+                                       pnlsr);
+      std::list<string> nameList = nlsa.getNpl().getNameList();
+      for (std::list<string>::iterator it = nameList.begin(); it != nameList.end();
+           it++)
+      {
+        if ((*it) != pnlsr.getConfParameter().getRouterPrefix())
+        {
+          pnlsr.getNpt().addNpteByDestName((*it), nlsa.getOrigRouter(), pnlsr);
+        }
+      }
+    }
+    if (nlsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      timeToExpire = nlsa.getLifeTime();
+    }
+    nlsa.setExpiringEventId(scheduleNameLsaExpiration(pnlsr,
+                                                      nlsa.getKey(),
+                                                      nlsa.getLsSeqNo(),
+                                                      timeToExpire));
+  }
+  else
+  {
+    if (chkNameLsa.first.getLsSeqNo() < nlsa.getLsSeqNo())
+    {
+      chkNameLsa.first.writeLog();
+      chkNameLsa.first.setLsSeqNo(nlsa.getLsSeqNo());
+      chkNameLsa.first.setLifeTime(nlsa.getLifeTime());
+      chkNameLsa.first.getNpl().sort();
+      nlsa.getNpl().sort();
+      std::list<string> nameToAdd;
+      std::set_difference(nlsa.getNpl().getNameList().begin(),
+                          nlsa.getNpl().getNameList().end(),
+                          chkNameLsa.first.getNpl().getNameList().begin(),
+                          chkNameLsa.first.getNpl().getNameList().end(),
+                          std::inserter(nameToAdd, nameToAdd.begin()));
+      for (std::list<string>::iterator it = nameToAdd.begin(); it != nameToAdd.end();
+           ++it)
+      {
+        chkNameLsa.first.addName((*it));
+        if (nlsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+        {
+          if ((*it) != pnlsr.getConfParameter().getRouterPrefix())
+          {
+            pnlsr.getNpt().addNpteByDestName((*it), nlsa.getOrigRouter(), pnlsr);
+          }
+        }
+      }
+      std::list<string> nameToRemove;
+      std::set_difference(chkNameLsa.first.getNpl().getNameList().begin(),
+                          chkNameLsa.first.getNpl().getNameList().end(),
+                          nlsa.getNpl().getNameList().begin(),
+                          nlsa.getNpl().getNameList().end(),
+                          std::inserter(nameToRemove, nameToRemove.begin()));
+      for (std::list<string>::iterator it = nameToRemove.begin();
+           it != nameToRemove.end(); ++it)
+      {
+        chkNameLsa.first.removeName((*it));
+        if (nlsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+        {
+          if ((*it) != pnlsr.getConfParameter().getRouterPrefix())
+          {
+            pnlsr.getNpt().removeNpte((*it), nlsa.getOrigRouter(), pnlsr);
+          }
+        }
+      }
+      if (nlsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+      {
+        timeToExpire = nlsa.getLifeTime();
+      }
+      cancelScheduleLsaExpiringEvent(pnlsr,
+                                     chkNameLsa.first.getExpiringEventId());
+      chkNameLsa.first.setExpiringEventId(scheduleNameLsaExpiration(pnlsr,
+                                                                    nlsa.getKey(),
+                                                                    nlsa.getLsSeqNo(),
+                                                                    timeToExpire));
+      chkNameLsa.first.writeLog();
+    }
+  }
+  return true;
+}
+
+bool
+Lsdb::addNameLsa(NameLsa& nlsa)
+{
+  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
+                                                 m_nameLsdb.end(),
+                                                 bind(nameLsaCompareByKey, _1,
+                                                      nlsa.getKey()));
+  if (it == m_nameLsdb.end())
+  {
+    m_nameLsdb.push_back(nlsa);
+    return true;
+  }
+  return false;
+}
+
+bool
+Lsdb::removeNameLsa(Nlsr& pnlsr, string& key)
+{
+  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
+                                                 m_nameLsdb.end(),
+                                                 bind(nameLsaCompareByKey, _1, key));
+  if (it != m_nameLsdb.end())
+  {
+    (*it).writeLog();
+    if ((*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      pnlsr.getNpt().removeNpte((*it).getOrigRouter(), (*it).getOrigRouter(), pnlsr);
+      for (std::list<string>::iterator nit = (*it).getNpl().getNameList().begin();
+           nit != (*it).getNpl().getNameList().end(); ++nit)
+      {
+        if ((*nit) != pnlsr.getConfParameter().getRouterPrefix())
+        {
+          pnlsr.getNpt().removeNpte((*nit), (*it).getOrigRouter(), pnlsr);
+        }
+      }
+    }
+    m_nameLsdb.erase(it);
+    return true;
+  }
+  return false;
+}
+
+bool
+Lsdb::doesNameLsaExist(string key)
+{
+  std::list<NameLsa>::iterator it = std::find_if(m_nameLsdb.begin(),
+                                                 m_nameLsdb.end(),
+                                                 bind(nameLsaCompareByKey, _1, key));
+  if (it == m_nameLsdb.end())
+  {
+    return false;
+  }
+  return true;
+}
+
+void
+Lsdb::printNameLsdb()
+{
+  cout << "---------------Name LSDB-------------------" << endl;
+  for (std::list<NameLsa>::iterator it = m_nameLsdb.begin();
+       it != m_nameLsdb.end() ; it++)
+  {
+    cout << (*it) << endl;
+  }
+}
+
+// Cor LSA and LSDB related Functions start here
+
+
+static bool
+corLsaCompareByKey(CorLsa& clsa, string& key)
+{
+  return clsa.getKey() == key;
+}
+
+bool
+Lsdb::buildAndInstallOwnCorLsa(Nlsr& pnlsr)
+{
+  CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
+                , 3
+                , pnlsr.getSm().getCorLsaSeq() + 1
+                , pnlsr.getConfParameter().getRouterDeadInterval()
+                , pnlsr.getConfParameter().getCorR()
+                , pnlsr.getConfParameter().getCorTheta());
+  pnlsr.getSm().setCorLsaSeq(pnlsr.getSm().getCorLsaSeq() + 1);
+  installCorLsa(pnlsr, corLsa);
+  return true;
+}
+
+std::pair<CorLsa&, bool>
+Lsdb::getCorLsa(string key)
+{
+  std::list<CorLsa>::iterator it = std::find_if(m_corLsdb.begin(),
+                                                m_corLsdb.end(),
+                                                bind(corLsaCompareByKey, _1, key));
+  if (it != m_corLsdb.end())
+  {
+    return std::make_pair(boost::ref((*it)), true);
+  }
+  CorLsa clsa;
+  return std::make_pair(boost::ref(clsa), false);
+}
+
+bool
+Lsdb::isCorLsaNew(string key, uint64_t seqNo)
+{
+  std::pair<CorLsa&, bool>  corLsaCheck = getCorLsa(key);
+  if (corLsaCheck.second)
+  {
+    if (corLsaCheck.first.getLsSeqNo() < seqNo)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+ndn::EventId
+Lsdb::scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+{
+  return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
+                                            ndn::bind(&Lsdb::exprireOrRefreshCorLsa,
+                                                      this, boost::ref(pnlsr),
+                                                      key, seqNo));
+}
+
+bool
+Lsdb::installCorLsa(Nlsr& pnlsr, CorLsa& clsa)
+{
+  int timeToExpire = m_lsaRefreshTime;
+  std::pair<CorLsa&, bool> chkCorLsa = getCorLsa(clsa.getKey());
+  if (!chkCorLsa.second)
+  {
+    addCorLsa(clsa);
+    printCorLsdb(); //debugging purpose
+    if (clsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      pnlsr.getNpt().addNpteByDestName(clsa.getOrigRouter(), clsa.getOrigRouter(),
+                                       pnlsr);
+    }
+    if (pnlsr.getConfParameter().getIsHyperbolicCalc() >= 1)
+    {
+      pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+    }
+    if (clsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      timeToExpire = clsa.getLifeTime();
+    }
+    scheduleCorLsaExpiration(pnlsr, clsa.getKey(),
+                             clsa.getLsSeqNo(), timeToExpire);
+  }
+  else
+  {
+    if (chkCorLsa.first.getLsSeqNo() < clsa.getLsSeqNo())
+    {
+      chkCorLsa.first.setLsSeqNo(clsa.getLsSeqNo());
+      chkCorLsa.first.setLifeTime(clsa.getLifeTime());
+      if (!chkCorLsa.first.isEqual(clsa))
+      {
+        chkCorLsa.first.setCorRadius(clsa.getCorRadius());
+        chkCorLsa.first.setCorTheta(clsa.getCorTheta());
+        if (pnlsr.getConfParameter().getIsHyperbolicCalc() >= 1)
+        {
+          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+        }
+      }
+      if (clsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+      {
+        timeToExpire = clsa.getLifeTime();
+      }
+      cancelScheduleLsaExpiringEvent(pnlsr,
+                                     chkCorLsa.first.getExpiringEventId());
+      chkCorLsa.first.setExpiringEventId(scheduleCorLsaExpiration(pnlsr,
+                                                                  clsa.getKey(),
+                                                                  clsa.getLsSeqNo(),
+                                                                  timeToExpire));
+    }
+  }
+  return true;
+}
+
+bool
+Lsdb::addCorLsa(CorLsa& clsa)
+{
+  std::list<CorLsa>::iterator it = std::find_if(m_corLsdb.begin(),
+                                                m_corLsdb.end(),
+                                                bind(corLsaCompareByKey, _1,
+                                                     clsa.getKey()));
+  if (it == m_corLsdb.end())
+  {
+    m_corLsdb.push_back(clsa);
+    return true;
+  }
+  return false;
+}
+
+bool
+Lsdb::removeCorLsa(Nlsr& pnlsr, string& key)
+{
+  std::list<CorLsa>::iterator it = std::find_if(m_corLsdb.begin(),
+                                                m_corLsdb.end(),
+                                                bind(corLsaCompareByKey, _1, key));
+  if (it != m_corLsdb.end())
+  {
+    if ((*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      pnlsr.getNpt().removeNpte((*it).getOrigRouter(), (*it).getOrigRouter(), pnlsr);
+    }
+    m_corLsdb.erase(it);
+    return true;
+  }
+  return false;
+}
+
+bool
+Lsdb::doesCorLsaExist(string key)
+{
+  std::list<CorLsa>::iterator it = std::find_if(m_corLsdb.begin(),
+                                                m_corLsdb.end(),
+                                                bind(corLsaCompareByKey, _1, key));
+  if (it == m_corLsdb.end())
+  {
+    return false;
+  }
+  return true;
+}
+
+void
+Lsdb::printCorLsdb() //debugging
+{
+  cout << "---------------Cor LSDB-------------------" << endl;
+  for (std::list<CorLsa>::iterator it = m_corLsdb.begin();
+       it != m_corLsdb.end() ; it++)
+  {
+    cout << (*it) << endl;
+  }
+}
+
+
+// Adj LSA and LSDB related function starts here
+
+static bool
+adjLsaCompareByKey(AdjLsa& alsa, string& key)
+{
+  return alsa.getKey() == key;
+}
+
+
+void
+Lsdb::scheduledAdjLsaBuild(Nlsr& pnlsr)
+{
+  cout << "scheduledAdjLsaBuild Called" << endl;
+  pnlsr.setIsBuildAdjLsaSheduled(0);
+  if (pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
+  {
+    int adjBuildCount = pnlsr.getAdjBuildCount();
+    if (adjBuildCount > 0)
+    {
+      if (pnlsr.getAdl().getNumOfActiveNeighbor() > 0)
+      {
+        buildAndInstallOwnAdjLsa(pnlsr);
+      }
+      else
+      {
+        string key = pnlsr.getConfParameter().getRouterPrefix() + "/2";
+        removeAdjLsa(pnlsr, key);
+        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+      }
+      pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount() - adjBuildCount);
+    }
+  }
+  else
+  {
+    pnlsr.setIsBuildAdjLsaSheduled(1);
+    int schedulingTime = pnlsr.getConfParameter().getInterestRetryNumber() *
+                         pnlsr.getConfParameter().getInterestResendTime();
+    pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(schedulingTime),
+                                       ndn::bind(&Lsdb::scheduledAdjLsaBuild,
+                                                 pnlsr.getLsdb(), boost::ref(pnlsr)));
+  }
+}
+
+
+bool
+Lsdb::addAdjLsa(AdjLsa& alsa)
+{
+  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
+                                                m_adjLsdb.end(),
+                                                bind(adjLsaCompareByKey, _1,
+                                                     alsa.getKey()));
+  if (it == m_adjLsdb.end())
+  {
+    m_adjLsdb.push_back(alsa);
+    return true;
+  }
+  return false;
+}
+
+std::pair<AdjLsa&, bool>
+Lsdb::getAdjLsa(string key)
+{
+  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
+                                                m_adjLsdb.end(),
+                                                bind(adjLsaCompareByKey, _1, key));
+  if (it != m_adjLsdb.end())
+  {
+    return std::make_pair(boost::ref((*it)), true);
+  }
+  AdjLsa alsa;
+  return std::make_pair(boost::ref(alsa), false);
+}
+
+
+bool
+Lsdb::isAdjLsaNew(string key, uint64_t seqNo)
+{
+  std::pair<AdjLsa&, bool>  adjLsaCheck = getAdjLsa(key);
+  if (adjLsaCheck.second)
+  {
+    if (adjLsaCheck.first.getLsSeqNo() < seqNo)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+ndn::EventId
+Lsdb::scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+{
+  return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
+                                            ndn::bind(&Lsdb::exprireOrRefreshAdjLsa,
+                                                      this, boost::ref(pnlsr),
+                                                      key, seqNo));
+}
+
+bool
+Lsdb::installAdjLsa(Nlsr& pnlsr, AdjLsa& alsa)
+{
+  int timeToExpire = m_lsaRefreshTime;
+  std::pair<AdjLsa&, bool> chkAdjLsa = getAdjLsa(alsa.getKey());
+  if (!chkAdjLsa.second)
+  {
+    addAdjLsa(alsa);
+    alsa.addNptEntries(pnlsr);
+    pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+    if (alsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+    {
+      timeToExpire = alsa.getLifeTime();
+    }
+    scheduleAdjLsaExpiration(pnlsr, alsa.getKey(),
+                             alsa.getLsSeqNo(), timeToExpire);
+  }
+  else
+  {
+    if (chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo())
+    {
+      chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
+      chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
+      if (!chkAdjLsa.first.isEqual(alsa))
+      {
+        chkAdjLsa.first.getAdl().reset();
+        chkAdjLsa.first.getAdl().addAdjacentsFromAdl(alsa.getAdl());
+        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+      }
+      if (alsa.getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix())
+      {
+        timeToExpire = alsa.getLifeTime();
+      }
+      cancelScheduleLsaExpiringEvent(pnlsr,
+                                     chkAdjLsa.first.getExpiringEventId());
+      chkAdjLsa.first.setExpiringEventId(scheduleAdjLsaExpiration(pnlsr,
+                                                                  alsa.getKey(),
+                                                                  alsa.getLsSeqNo(),
+                                                                  timeToExpire));
+    }
+  }
+  return true;
+}
+
+bool
+Lsdb::buildAndInstallOwnAdjLsa(Nlsr& pnlsr)
+{
+  AdjLsa adjLsa(pnlsr.getConfParameter().getRouterPrefix()
+                , 2
+                , pnlsr.getSm().getAdjLsaSeq() + 1
+                , pnlsr.getConfParameter().getRouterDeadInterval()
+                , pnlsr.getAdl().getNumOfActiveNeighbor()
+                , pnlsr.getAdl());
+  pnlsr.getSm().setAdjLsaSeq(pnlsr.getSm().getAdjLsaSeq() + 1);
+  string lsaPrefix = pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                     + pnlsr.getConfParameter().getRouterPrefix();
+  pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(), lsaPrefix);
+  return pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+}
+
+bool
+Lsdb::removeAdjLsa(Nlsr& pnlsr, string& key)
+{
+  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
+                                                m_adjLsdb.end(),
+                                                bind(adjLsaCompareByKey, _1, key));
+  if (it != m_adjLsdb.end())
+  {
+    (*it).removeNptEntries(pnlsr);
+    m_adjLsdb.erase(it);
+    return true;
+  }
+  return false;
+}
+
+bool
+Lsdb::doesAdjLsaExist(string key)
+{
+  std::list<AdjLsa>::iterator it = std::find_if(m_adjLsdb.begin(),
+                                                m_adjLsdb.end(),
+                                                bind(adjLsaCompareByKey, _1, key));
+  if (it == m_adjLsdb.end())
+  {
+    return false;
+  }
+  return true;
+}
+
+std::list<AdjLsa>&
+Lsdb::getAdjLsdb()
+{
+  return m_adjLsdb;
+}
+
+void
+Lsdb::setLsaRefreshTime(int lrt)
+{
+  m_lsaRefreshTime = lrt;
+}
+
+void
+Lsdb::setThisRouterPrefix(string trp)
+{
+  m_thisRouterPrefix = trp;
+}
+
+void
+Lsdb::exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, uint64_t seqNo)
+{
+  cout << "Lsdb::exprireOrRefreshNameLsa Called " << endl;
+  cout << "LSA Key : " << lsaKey << " Seq No: " << seqNo << endl;
+  std::pair<NameLsa&, bool> chkNameLsa = getNameLsa(lsaKey);
+  if (chkNameLsa.second)
+  {
+    cout << " LSA Exists with seq no: " << chkNameLsa.first.getLsSeqNo() << endl;
+    if (chkNameLsa.first.getLsSeqNo() == seqNo)
+    {
+      if (chkNameLsa.first.getOrigRouter() == m_thisRouterPrefix)
+      {
+        chkNameLsa.first.writeLog();
+        cout << "Own Name LSA, so refreshing name LSA" << endl;
+        chkNameLsa.first.setLsSeqNo(chkNameLsa.first.getLsSeqNo() + 1);
+        pnlsr.getSm().setNameLsaSeq(chkNameLsa.first.getLsSeqNo());
+        chkNameLsa.first.writeLog();
+        // publish routing update
+        string lsaPrefix = pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                           + pnlsr.getConfParameter().getRouterPrefix();
+        pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(), lsaPrefix);
+      }
+      else
+      {
+        cout << "Other's Name LSA, so removing form LSDB" << endl;
+        removeNameLsa(pnlsr, lsaKey);
+      }
+    }
+  }
+}
+
+void
+Lsdb::exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, uint64_t seqNo)
+{
+  cout << "Lsdb::exprireOrRefreshAdjLsa Called " << endl;
+  cout << "LSA Key : " << lsaKey << " Seq No: " << seqNo << endl;
+  std::pair<AdjLsa&, bool> chkAdjLsa = getAdjLsa(lsaKey);
+  if (chkAdjLsa.second)
+  {
+    cout << " LSA Exists with seq no: " << chkAdjLsa.first.getLsSeqNo() << endl;
+    if (chkAdjLsa.first.getLsSeqNo() == seqNo)
+    {
+      if (chkAdjLsa.first.getOrigRouter() == m_thisRouterPrefix)
+      {
+        cout << "Own Adj LSA, so refreshing Adj LSA" << endl;
+        chkAdjLsa.first.setLsSeqNo(chkAdjLsa.first.getLsSeqNo() + 1);
+        pnlsr.getSm().setAdjLsaSeq(chkAdjLsa.first.getLsSeqNo());
+        // publish routing update
+        string lsaPrefix = pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                           + pnlsr.getConfParameter().getRouterPrefix();
+        pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(), lsaPrefix);
+      }
+      else
+      {
+        cout << "Other's Adj LSA, so removing form LSDB" << endl;
+        removeAdjLsa(pnlsr, lsaKey);
+      }
+      // schedule Routing table calculaiton
+      pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+    }
+  }
+}
+
+void
+Lsdb::exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, uint64_t seqNo)
+{
+  cout << "Lsdb::exprireOrRefreshCorLsa Called " << endl;
+  cout << "LSA Key : " << lsaKey << " Seq No: " << seqNo << endl;
+  std::pair<CorLsa&, bool> chkCorLsa = getCorLsa(lsaKey);
+  if (chkCorLsa.second)
+  {
+    cout << " LSA Exists with seq no: " << chkCorLsa.first.getLsSeqNo() << endl;
+    if (chkCorLsa.first.getLsSeqNo() == seqNo)
+    {
+      if (chkCorLsa.first.getOrigRouter() == m_thisRouterPrefix)
+      {
+        cout << "Own Cor LSA, so refreshing Cor LSA" << endl;
+        chkCorLsa.first.setLsSeqNo(chkCorLsa.first.getLsSeqNo() + 1);
+        pnlsr.getSm().setCorLsaSeq(chkCorLsa.first.getLsSeqNo());
+        // publish routing update
+        string lsaPrefix = pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                           + pnlsr.getConfParameter().getRouterPrefix();
+        pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(), lsaPrefix);
+      }
+      else
+      {
+        cout << "Other's Cor LSA, so removing form LSDB" << endl;
+        removeCorLsa(pnlsr, lsaKey);
+      }
+      if (pnlsr.getConfParameter().getIsHyperbolicCalc() >= 1)
+      {
+        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+      }
+    }
+  }
+}
+
+
+void
+Lsdb::printAdjLsdb()
+{
+  cout << "---------------Adj LSDB-------------------" << endl;
+  for (std::list<AdjLsa>::iterator it = m_adjLsdb.begin();
+       it != m_adjLsdb.end() ; it++)
+  {
+    cout << (*it) << endl;
+  }
+}
+
+//-----utility function -----
+bool
+Lsdb::doesLsaExist(string key, int lsType)
+{
+  if (lsType == 1)
+  {
+    return doesNameLsaExist(key);
+  }
+  else if (lsType == 2)
+  {
+    return doesAdjLsaExist(key);
+  }
+  else if (lsType == 3)
+  {
+    return doesCorLsaExist(key);
+  }
+  return false;
+}
+
+}//namespace nlsr
+
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
new file mode 100644
index 0000000..96f0ff1
--- /dev/null
+++ b/src/lsdb.hpp
@@ -0,0 +1,145 @@
+#ifndef NLSR_LSDB_HPP
+#define NLSR_LSDB_HPP
+
+#include <utility>
+#include "lsa.hpp"
+
+namespace nlsr {
+class Nlsr;
+
+class Lsdb
+{
+public:
+  Lsdb()
+    : m_lsaRefreshTime(0)
+  {
+  }
+
+
+  bool
+  doesLsaExist(std::string key, int lsType);
+  // function related to Name LSDB
+
+  bool
+  buildAndInstallOwnNameLsa(Nlsr& pnlsr);
+
+  std::pair<NameLsa&, bool>
+  getNameLsa(std::string key);
+
+  bool
+  installNameLsa(Nlsr& pnlsr, NameLsa& nlsa);
+
+  bool
+  removeNameLsa(Nlsr& pnlsr, std::string& key);
+
+  bool
+  isNameLsaNew(std::string key, uint64_t seqNo);
+
+  void
+  printNameLsdb(); //debugging
+
+  //function related to Cor LSDB
+  bool
+  buildAndInstallOwnCorLsa(Nlsr& pnlsr);
+
+  std::pair<CorLsa&, bool>
+  getCorLsa(std::string key);
+
+  bool
+  installCorLsa(Nlsr& pnlsr, CorLsa& clsa);
+
+  bool
+  removeCorLsa(Nlsr& pnlsr, std::string& key);
+
+  bool
+  isCorLsaNew(std::string key, uint64_t seqNo);
+
+  void
+  printCorLsdb(); //debugging
+
+  //function related to Adj LSDB
+  void
+  scheduledAdjLsaBuild(Nlsr& pnlsr);
+
+  bool
+  buildAndInstallOwnAdjLsa(Nlsr& pnlsr);
+
+  bool
+  removeAdjLsa(Nlsr& pnlsr, std::string& key);
+
+  bool
+  isAdjLsaNew(std::string key, uint64_t seqNo);
+  bool
+  installAdjLsa(Nlsr& pnlsr, AdjLsa& alsa);
+
+  std::pair<AdjLsa&, bool>
+  getAdjLsa(std::string key);
+
+  std::list<AdjLsa>&
+  getAdjLsdb();
+
+  void
+  printAdjLsdb();
+
+  //void scheduleRefreshLsdb(Nlsr& pnlsr, int interval);
+  void
+  setLsaRefreshTime(int lrt);
+
+  void
+  setThisRouterPrefix(std::string trp);
+
+private:
+  bool
+  addNameLsa(NameLsa& nlsa);
+
+  bool
+  doesNameLsaExist(std::string key);
+
+
+  bool
+  addCorLsa(CorLsa& clsa);
+
+  bool
+  doesCorLsaExist(std::string key);
+
+  bool
+  addAdjLsa(AdjLsa& alsa);
+
+  bool
+  doesAdjLsaExist(std::string key);
+
+  ndn::EventId
+  scheduleNameLsaExpiration(Nlsr& pnlsr, std::string key, int seqNo, int expTime);
+
+  void
+  exprireOrRefreshNameLsa(Nlsr& pnlsr, std::string lsaKey, uint64_t seqNo);
+
+  ndn::EventId
+  scheduleAdjLsaExpiration(Nlsr& pnlsr, std::string key, int seqNo, int expTime);
+
+  void
+  exprireOrRefreshAdjLsa(Nlsr& pnlsr, std::string lsaKey, uint64_t seqNo);
+
+  ndn::EventId
+  scheduleCorLsaExpiration(Nlsr& pnlsr, std::string key, int seqNo, int expTime);
+
+  void
+  exprireOrRefreshCorLsa(Nlsr& pnlsr, std::string lsaKey, uint64_t seqNo);
+
+
+private:
+  void
+  cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, ndn::EventId eid);
+
+  std::list<NameLsa> m_nameLsdb;
+  std::list<AdjLsa> m_adjLsdb;
+  std::list<CorLsa> m_corLsdb;
+
+  int m_lsaRefreshTime;
+  std::string m_thisRouterPrefix;
+
+};
+
+}//namespace nlsr
+
+#endif //NLSR_LSDB_HPP
diff --git a/src/main.cpp b/src/main.cpp
index 6556816..20c132e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,14 +19,13 @@
  **/
 
 #include "nlsr.hpp"
-#include "nlsr_conf_processor.hpp"
+#include "conf-file-processor.hpp"
 
 using namespace nlsr;
 
 int
-main(int argc, char **argv)
+main(int argc, char** argv)
 {
-  src::logger lg;
   nlsr::Nlsr nlsr_;
   string programName(argv[0]);
   nlsr_.setConfFileName("nlsr.conf");
@@ -42,24 +41,26 @@
         nlsr_.setIsDaemonProcess(optarg);
         break;
       case 'p':
-        {
-          stringstream sst(optarg);
-          int ap;
-          sst>>ap;
-          nlsr_.setApiPort(ap);
-        }
-        break;
+      {
+        stringstream sst(optarg);
+        int ap;
+        sst >> ap;
+        nlsr_.setApiPort(ap);
+      }
+      break;
       case 'h':
+
       default:
         nlsr_.usage(programName);
         return EXIT_FAILURE;
       }
   }
   ConfFileProcessor cfp(nlsr_.getConfFileName());
-  int res=cfp.processConfFile(nlsr_);
-  if ( res < 0 )
+  int res = cfp.processConfFile(nlsr_);
+  if (res < 0)
   {
-    std::cerr<<"Error in configuration file processing! Exiting from NLSR"<<std::endl;
+    std::cerr << "Error in configuration file processing! Exiting from NLSR" <<
+              std::endl;
     return EXIT_FAILURE;
   }
   nlsr_.initialize();
@@ -67,7 +68,7 @@
   {
     nlsr_.startEventLoop();
   }
-  catch(std::exception &e)
+  catch (std::exception& e)
   {
     std::cerr << "ERROR: " << e.what() << std::endl;
   }
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index 726c53a..00bd510 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -9,88 +9,77 @@
 
 
 #include "nlsr.hpp"
-#include "nlsr_conf_processor.hpp"
-#include "utility/nlsr_logger.hpp"
-#include "security/nlsr_km.hpp"
-#include "security/nlsr_cert_store.hpp"
-#include "security/nlsr_cse.hpp"
 
-#define THIS_FILE "nlsr.cpp"
 
-namespace nlsr
+namespace nlsr {
+
+using namespace ndn;
+using namespace std;
+
+void
+Nlsr::registrationFailed(const ndn::Name& name)
 {
+  cerr << "ERROR: Failed to register prefix in local hub's daemon" << endl;
+  getNlsrFace()->shutdown();
+}
 
-  using namespace ndn;
-  using namespace std;
 
-  void
-  Nlsr::nlsrRegistrationFailed(const ndn::Name& name)
+void
+Nlsr::setInterestFilterNlsr(const string& name)
+{
+  getNlsrFace()->setInterestFilter(name,
+                                   func_lib::bind(&InterestManager::processInterest, &m_im,
+                                                  boost::ref(*this), _1, _2),
+                                   func_lib::bind(&Nlsr::registrationFailed, this, _1));
+}
+
+void
+Nlsr::initialize()
+{
+  m_confParam.buildRouterPrefix();
+  m_nlsrLsdb.setLsaRefreshTime(m_confParam.getLsaRefreshTime());
+  m_nlsrLsdb.setThisRouterPrefix(m_confParam.getRouterPrefix());
+  m_fib.setEntryRefreshTime(2 * m_confParam.getLsaRefreshTime());
+  if (!m_km.initialize(m_confParam))
   {
-    cerr << "ERROR: Failed to register prefix in local hub's daemon" << endl;
-    getNlsrFace()->shutdown();
+    std::cerr << "Can not initiate/load certificate" << endl;
   }
+  m_sm.setSeqFileName(m_confParam.getSeqFileDir());
+  m_sm.initiateSeqNoFromFile();
+  /* debugging purpose start */
+  cout <<	m_confParam;
+  m_adl.printAdl();
+  m_npl.print();
+  /* debugging purpose end */
+  m_nlsrLsdb.buildAndInstallOwnNameLsa(boost::ref(*this));
+  m_nlsrLsdb.buildAndInstallOwnCorLsa(boost::ref(*this));
+  setInterestFilterNlsr(m_confParam.getRouterPrefix());
+  setInterestFilterNlsr(m_confParam.getChronosyncLsaPrefix() +
+                        m_confParam.getRouterPrefix());
+  setInterestFilterNlsr(m_confParam.getRootKeyPrefix());
+  m_slh.setSyncPrefix(m_confParam.getChronosyncSyncPrefix());
+  m_slh.createSyncSocket(boost::ref(*this));
+  m_slh.publishKeyUpdate(m_km);
+  m_im.scheduleInfoInterest(boost::ref(*this), 10);
+}
 
+void
+Nlsr::startEventLoop()
+{
+  m_io->run();
+}
 
-  void
-  Nlsr::setInterestFilterNlsr(const string& name)
-  {
-    getNlsrFace()->setInterestFilter(name,
-                                     func_lib::bind(&InterestManager::processInterest, &m_im,
-                                         boost::ref(*this), _1, _2),
-                                     func_lib::bind(&Nlsr::nlsrRegistrationFailed, this, _1));
-  }
-
-  void
-  Nlsr::initialize()
-  {
-    src::logger lg;
-    m_confParam.buildRouterPrefix();
-    m_nlsrLogger.initNlsrLogger(m_confParam.getLogDir());
-    m_nlsrLsdb.setLsaRefreshTime(m_confParam.getLsaRefreshTime());
-    m_nlsrLsdb.setThisRouterPrefix(m_confParam.getRouterPrefix());
-    m_fib.setEntryRefreshTime(2*m_confParam.getLsaRefreshTime());
-    if( ! m_km.initialize(m_confParam) )
-    {
-      std::cerr<<"Can not initiate/load certificate"<<endl;
-      BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Certificate initiation"
-                   <<" error";
-    }
-    m_sm.setSeqFileName(m_confParam.getSeqFileDir());
-    m_sm.initiateSeqNoFromFile();
-    /* debugging purpose start */
-    cout <<	m_confParam;
-    m_adl.printAdl();
-    m_npl.print();
-    /* debugging purpose end */
-    m_nlsrLsdb.buildAndInstallOwnNameLsa(boost::ref(*this));
-    m_nlsrLsdb.buildAndInstallOwnCorLsa(boost::ref(*this));
-    setInterestFilterNlsr(m_confParam.getRouterPrefix());
-    setInterestFilterNlsr(m_confParam.getChronosyncLsaPrefix()+
-                          m_confParam.getRouterPrefix());
-    setInterestFilterNlsr(m_confParam.getRootKeyPrefix());
-    m_slh.setSyncPrefix(m_confParam.getChronosyncSyncPrefix());
-    m_slh.createSyncSocket(boost::ref(*this));
-    m_slh.publishKeyUpdate(m_km);
-    m_im.scheduleInfoInterest(boost::ref(*this),10);
-  }
-
-  void
-  Nlsr::startEventLoop()
-  {
-    m_io->run();
-  }
-
-  int
-  Nlsr::usage(const string& progname)
-  {
-    cout << "Usage: " << progname << " [OPTIONS...]"<<endl;
-    cout << "   NDN routing...." << endl;
-    cout << "       -d, --daemon        Run in daemon mode" << endl;
-    cout << "       -f, --config_file   Specify configuration file name" <<endl;
-    cout << "       -p, --api_port      port where api client will connect" <<endl;
-    cout << "       -h, --help          Display this help message" << endl;
-    exit(EXIT_FAILURE);
-  }
+int
+Nlsr::usage(const string& progname)
+{
+  cout << "Usage: " << progname << " [OPTIONS...]" << endl;
+  cout << "   NDN routing...." << endl;
+  cout << "       -d, --daemon        Run in daemon mode" << endl;
+  cout << "       -f, --config_file   Specify configuration file name" << endl;
+  cout << "       -p, --api_port      port where api client will connect" << endl;
+  cout << "       -h, --help          Display this help message" << endl;
+  exit(EXIT_FAILURE);
+}
 
 
 } // namespace nlsr
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index 40a7de0..bef8189 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -5,258 +5,286 @@
 #include <ndn-cpp-dev/security/key-chain.hpp>
 #include <ndn-cpp-dev/util/scheduler.hpp>
 
-#include "nlsr_conf_param.hpp"
-#include "nlsr_adl.hpp"
-#include "nlsr_npl.hpp"
-#include "communication/nlsr_im.hpp"
-#include "communication/nlsr_dm.hpp"
-#include "nlsr_lsdb.hpp"
-#include "nlsr_sm.hpp"
-#include "route/nlsr_rt.hpp"
-#include "route/nlsr_npt.hpp"
-#include "route/nlsr_fib.hpp"
-#include "utility/nlsr_logger.hpp"
-#include "security/nlsr_km.hpp"
-#include "communication/nlsr_slh.hpp"
+#include "conf-parameter.hpp"
+#include "adl.hpp"
+#include "npl.hpp"
+#include "communication/interest-manager.hpp"
+#include "communication/data-manager.hpp"
+#include "lsdb.hpp"
+#include "sequencing-manager.hpp"
+#include "route/routing-table.hpp"
+#include "route/npt.hpp"
+#include "route/fib.hpp"
+#include "security/key-manager.hpp"
+#include "communication/sync-logic-handler.hpp"
 
 
-namespace nlsr
+namespace nlsr {
+
+inline static void
+NullDeleter(boost::asio::io_service* variable)
 {
+  // do nothing
+}
 
-  using namespace ndn;
-  using namespace std;
+class Nlsr
+{
+public:
+  Nlsr()
+    : m_io(new boost::asio::io_service)
+    , m_nlsrFace(new Face(ndn::shared_ptr<boost::asio::io_service>(&*m_io,
+                                                              &NullDeleter)))
+    , m_scheduler(*m_io)
+    , m_confParam()
+    , m_adl()
+    , m_npl()
+    , m_im()
+    , m_dm()
+    , m_sm()
+    , m_km()
+    , m_isDaemonProcess(false)
+    , m_configFileName("nlsr.conf")
+    , m_nlsrLsdb()
+    , m_adjBuildCount(0)
+    , m_isBuildAdjLsaSheduled(false)
+    , m_isRouteCalculationScheduled(false)
+    , m_isRoutingTableCalculating(false)
+    , m_routingTable()
+    , m_npt()
+    , m_fib()
+    , m_slh(m_io)
+  {}
 
-  inline static void
-  NullDeleter(boost::asio::io_service* variable)
+  void
+  registrationFailed(const ndn::Name& name);
+
+  void
+  setInterestFilterNlsr(const string& name);
+
+  void
+  startEventLoop();
+
+  int
+  usage(const string& progname);
+
+  std::string
+  getConfFileName()
   {
-    // do nothing
+    return m_configFileName;
   }
 
-  class Nlsr
+  void
+  setConfFileName(const string& fileName)
   {
-  public:
-    Nlsr()
-      : m_io(new boost::asio::io_service)
-      , m_nlsrFace(new Face(shared_ptr<boost::asio::io_service>(&*m_io, &NullDeleter)))
-      , m_scheduler(*m_io)
-      , m_confParam()
-      , m_adl()
-      , m_npl()
-      , m_im()
-      , m_dm()
-      , m_sm()
-      , m_km()
-      , isDaemonProcess(false)
-      , m_configFileName("nlsr.conf")
-      , m_nlsrLsdb()
-      , m_adjBuildCount(0)
-      , isBuildAdjLsaSheduled(0)
-      , isRouteCalculationScheduled(0)
-      , isRoutingTableCalculating(0)
-      , m_routingTable()
-      , m_npt()
-      , m_fib()
-      , m_slh(m_io)
-      , m_nlsrLogger()
-    {}
+    m_configFileName = fileName;
+  }
 
-    void nlsrRegistrationFailed(const ndn::Name& name);
+  bool
+  getIsSetDaemonProcess()
+  {
+    return m_isDaemonProcess;
+  }
 
-    void setInterestFilterNlsr(const string& name);
-    void startEventLoop();
+  void
+  setIsDaemonProcess(bool value)
+  {
+    m_isDaemonProcess = value;
+  }
 
-    int usage(const string& progname);
+  ConfParameter&
+  getConfParameter()
+  {
+    return m_confParam;
+  }
 
-    string getConfFileName()
-    {
-      return m_configFileName;
-    }
+  Adl&
+  getAdl()
+  {
+    return m_adl;
+  }
 
-    void setConfFileName(const string& fileName)
-    {
-      m_configFileName=fileName;
-    }
+  Npl&
+  getNpl()
+  {
+    return m_npl;
+  }
 
-    bool getIsSetDaemonProcess()
-    {
-      return isDaemonProcess;
-    }
+  ndn::shared_ptr<boost::asio::io_service>&
+  getIo()
+  {
+    return m_io;
+  }
 
-    void setIsDaemonProcess(bool value)
-    {
-      isDaemonProcess=value;
-    }
+  ndn::Scheduler&
+  getScheduler()
+  {
+    return m_scheduler;
+  }
 
-    ConfParameter& getConfParameter()
-    {
-      return m_confParam;
-    }
+  ndn::shared_ptr<ndn::Face>
+  getNlsrFace()
+  {
+    return m_nlsrFace;
+  }
 
-    Adl& getAdl()
-    {
-      return m_adl;
-    }
-
-    Npl& getNpl()
-    {
-      return m_npl;
-    }
-
-    ndn::shared_ptr<boost::asio::io_service>& getIo()
-    {
-      return m_io;
-    }
-
-    ndn::Scheduler& getScheduler()
-    {
-      return m_scheduler;
-    }
-
-    ndn::shared_ptr<ndn::Face> getNlsrFace()
-    {
-      return m_nlsrFace;
-    }
-
-    KeyManager& getKeyManager()
-    {
-      return m_km;
-    }
+  KeyManager&
+  getKeyManager()
+  {
+    return m_km;
+  }
 
 
-    InterestManager& getIm()
-    {
-      return m_im;
-    }
+  InterestManager&
+  getIm()
+  {
+    return m_im;
+  }
 
-    DataManager& getDm()
-    {
-      return m_dm;
-    }
+  DataManager&
+  getDm()
+  {
+    return m_dm;
+  }
 
-    SequencingManager& getSm()
-    {
-      return m_sm;
-    }
+  SequencingManager&
+  getSm()
+  {
+    return m_sm;
+  }
 
-    Lsdb& getLsdb()
-    {
-      return m_nlsrLsdb;
-    }
+  Lsdb&
+  getLsdb()
+  {
+    return m_nlsrLsdb;
+  }
 
-    RoutingTable& getRoutingTable()
-    {
-      return m_routingTable;
-    }
+  RoutingTable&
+  getRoutingTable()
+  {
+    return m_routingTable;
+  }
 
-    Npt& getNpt()
-    {
-      return m_npt;
-    }
+  Npt&
+  getNpt()
+  {
+    return m_npt;
+  }
 
-    Fib& getFib()
-    {
-      return m_fib;
-    }
+  Fib&
+  getFib()
+  {
+    return m_fib;
+  }
 
-    long int getAdjBuildCount()
-    {
-      return m_adjBuildCount;
-    }
+  long int
+  getAdjBuildCount()
+  {
+    return m_adjBuildCount;
+  }
 
-    void incrementAdjBuildCount()
-    {
-      m_adjBuildCount++;
-    }
+  void
+  incrementAdjBuildCount()
+  {
+    m_adjBuildCount++;
+  }
 
-    void setAdjBuildCount(long int abc)
-    {
-      m_adjBuildCount=abc;
-    }
+  void
+  setAdjBuildCount(long int abc)
+  {
+    m_adjBuildCount = abc;
+  }
 
-    int getIsBuildAdjLsaSheduled()
-    {
-      return isBuildAdjLsaSheduled;
-    }
+  int
+  getIsBuildAdjLsaSheduled()
+  {
+    return m_isBuildAdjLsaSheduled;
+  }
 
-    void setIsBuildAdjLsaSheduled(bool iabls)
-    {
-      isBuildAdjLsaSheduled=iabls;
-    }
+  void
+  setIsBuildAdjLsaSheduled(bool iabls)
+  {
+    m_isBuildAdjLsaSheduled = iabls;
+  }
 
 
-    void setApiPort(int ap)
-    {
-      m_apiPort=ap;
-    }
+  void
+  setApiPort(int ap)
+  {
+    m_apiPort = ap;
+  }
 
-    int getApiPort()
-    {
-      return m_apiPort;
-    }
+  int
+  getApiPort()
+  {
+    return m_apiPort;
+  }
 
-    bool getIsRoutingTableCalculating()
-    {
-      return isRoutingTableCalculating;
-    }
+  bool
+  getIsRoutingTableCalculating()
+  {
+    return m_isRoutingTableCalculating;
+  }
 
-    void setIsRoutingTableCalculating(bool irtc)
-    {
-      isRoutingTableCalculating=irtc;
-    }
+  void
+  setIsRoutingTableCalculating(bool irtc)
+  {
+    m_isRoutingTableCalculating = irtc;
+  }
 
-    bool getIsRouteCalculationScheduled()
-    {
-      return isRouteCalculationScheduled;
-    }
+  bool
+  getIsRouteCalculationScheduled()
+  {
+    return m_isRouteCalculationScheduled;
+  }
 
-    void setIsRouteCalculationScheduled(bool ircs)
-    {
-      isRouteCalculationScheduled=ircs;
-    }
+  void
+  setIsRouteCalculationScheduled(bool ircs)
+  {
+    m_isRouteCalculationScheduled = ircs;
+  }
 
-    SyncLogicHandler& getSlh()
-    {
-      return m_slh;
-    }
+  SyncLogicHandler&
+  getSlh()
+  {
+    return m_slh;
+  }
 
-    NlsrLogger& getNlsrLogger()
-    {
-      return m_nlsrLogger;
-    }
+  void
+  initialize();
 
-    void initialize();
-
-  private:
-    ConfParameter m_confParam;
-    Adl m_adl;
-    Npl m_npl;
-    ndn::shared_ptr<boost::asio::io_service> m_io;
-    ndn::Scheduler m_scheduler;
-    ndn::shared_ptr<ndn::Face> m_nlsrFace;
-    InterestManager m_im;
-    DataManager m_dm;
-    SequencingManager m_sm;
-    KeyManager m_km;
-    bool isDaemonProcess;
-    string m_configFileName;
-    int m_apiPort;
-
-    Lsdb m_nlsrLsdb;
-    RoutingTable m_routingTable;
-    Npt m_npt;
-    Fib m_fib;
-    SyncLogicHandler m_slh;
-    NlsrLogger m_nlsrLogger;
-
-    long int m_adjBuildCount;
-    bool isBuildAdjLsaSheduled;
-    bool isRouteCalculationScheduled;
-    bool isRoutingTableCalculating;
+private:
+  ndn::shared_ptr<boost::asio::io_service> m_io;
+  ndn::shared_ptr<ndn::Face> m_nlsrFace;
+  ndn::Scheduler m_scheduler;
+  ConfParameter m_confParam;
+  Adl m_adl;
+  Npl m_npl;
+  InterestManager m_im;
+  DataManager m_dm;
+  SequencingManager m_sm;
+  KeyManager m_km;
+  bool m_isDaemonProcess;
+  string m_configFileName;
 
 
+  Lsdb m_nlsrLsdb;
 
-  };
+
+  long int m_adjBuildCount;
+  bool m_isBuildAdjLsaSheduled;
+  bool m_isRouteCalculationScheduled;
+  bool m_isRoutingTableCalculating;
+
+  RoutingTable m_routingTable;
+  Npt m_npt;
+  Fib m_fib;
+  SyncLogicHandler m_slh;
+
+  int m_apiPort;
+
+
+};
 
 } //namespace nlsr
 
-#endif
+#endif //NLSR_HPP
diff --git a/src/nlsr_adjacent.cpp b/src/nlsr_adjacent.cpp
deleted file mode 100644
index 6ef9c0b..0000000
--- a/src/nlsr_adjacent.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include<iostream>
-#include<string>
-#include<cmath>
-#include<limits>
-#include "nlsr_adjacent.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_adjacent.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  Adjacent::Adjacent(const string& an, int cf, double lc, int s, int iton)
-  {
-    m_name=an;
-    m_connectingFace=cf;
-    m_linkCost=lc;
-    m_status=s;
-    m_interestTimedOutNo=iton;
-  }
-
-  bool
-  Adjacent::isEqual(Adjacent& adj)
-  {
-    return ( m_name == adj.getName() ) &&
-           ( m_connectingFace == adj.getConnectingFace() ) &&
-           (std::abs(m_linkCost - adj.getLinkCost()) <
-            std::numeric_limits<double>::epsilon()) ;
-  }
-
-  std::ostream&
-  operator << (std::ostream &os, Adjacent &adj)
-  {
-    cout<<"Adjacent : "<< adj.getName()	<< endl;
-    cout<<"Connecting Face: "<<adj.getConnectingFace()<<endl;
-    cout<<"Link Cost: "<<adj.getLinkCost()<<endl;
-    cout<<"Status: "<<adj.getStatus()<<endl;
-    cout<<"Interest Timed out: "<<adj.getInterestTimedOutNo()<<endl;
-    return os;
-  }
-
-} //namespace nlsr
diff --git a/src/nlsr_adjacent.hpp b/src/nlsr_adjacent.hpp
deleted file mode 100644
index f9a789a..0000000
--- a/src/nlsr_adjacent.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef ADJACENT_HPP
-#define ADJACENT_HPP
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class Adjacent
-  {
-
-  public:
-    Adjacent()
-      :m_name()
-      ,m_connectingFace(0)
-      ,m_linkCost(10.0)
-      ,m_status(0)
-      ,m_interestTimedOutNo(0)
-    {
-    }
-
-    Adjacent(const string& an)
-      :m_connectingFace(0)
-      ,m_linkCost(0.0)
-      ,m_status(0)
-      ,m_interestTimedOutNo(0)
-    {
-      m_name=an;
-    }
-
-    Adjacent(const string& an, int cf, double lc, int s, int iton);
-
-    string getName()
-    {
-      return m_name;
-    }
-
-    void setName(const string& an)
-    {
-      m_name=an;
-    }
-
-    int getConnectingFace()
-    {
-      return m_connectingFace;
-    }
-
-    void setConnectingFace(int cf)
-    {
-      m_connectingFace=cf;
-    }
-
-    double getLinkCost()
-    {
-      return m_linkCost;
-    }
-
-    void setLinkCost(double lc)
-    {
-      m_linkCost=lc;
-    }
-
-    int getStatus()
-    {
-      return m_status;
-    }
-
-    void setStatus(int s)
-    {
-      m_status=s;
-    }
-
-    int getInterestTimedOutNo()
-    {
-      return m_interestTimedOutNo;
-    }
-
-    void setInterestTimedOutNo(int iton)
-    {
-      m_interestTimedOutNo=iton;
-    }
-
-    bool isEqual(Adjacent& adj);
-  private:
-    string m_name;
-    int m_connectingFace;
-    double m_linkCost;
-    int m_status;
-    int m_interestTimedOutNo;
-  };
-
-  std::ostream&
-  operator << (std::ostream &os, Adjacent &adj);
-
-} // namespace nlsr
-
-#endif
diff --git a/src/nlsr_adl.cpp b/src/nlsr_adl.cpp
deleted file mode 100644
index fd84f9e..0000000
--- a/src/nlsr_adl.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-#include<iostream>
-#include<algorithm>
-
-#include "nlsr_adl.hpp"
-#include "nlsr_adjacent.hpp"
-#include "nlsr.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_adl.cpp"
-
-namespace nlsr
-{
-
-  Adl::Adl()
-  {
-  }
-
-  Adl::~Adl()
-  {
-  }
-
-  static bool
-  adjacent_compare(Adjacent& adj1, Adjacent& adj2)
-  {
-    return adj1.getName()==adj2.getName();
-  }
-
-  int
-  Adl::insert(Adjacent& adj)
-  {
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if ( it != m_adjList.end() )
-    {
-      return -1;
-    }
-    m_adjList.push_back(adj);
-    return 0;
-  }
-
-  void
-  Adl::addAdjacentsFromAdl(Adl& adl)
-  {
-    for(std::list<Adjacent >::iterator it=adl.getAdjList().begin();
-        it!=adl.getAdjList().end(); ++it)
-    {
-      insert((*it));
-    }
-  }
-
-  int
-  Adl::updateAdjacentStatus(string adjName, int s)
-  {
-    Adjacent adj(adjName);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it == m_adjList.end())
-    {
-      return -1;
-    }
-    (*it).setStatus(s);
-    return 0;
-  }
-
-  Adjacent
-  Adl::getAdjacent(string adjName)
-  {
-    Adjacent adj(adjName);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it != m_adjList.end())
-    {
-      return (*it);
-    }
-    return adj;
-  }
-
-
-  bool
-  Adl::isEqual(Adl& adl)
-  {
-    if ( getSize() != adl.getSize() )
-    {
-      return false;
-    }
-    m_adjList.sort(adjacent_compare);
-    adl.getAdjList().sort(adjacent_compare);
-    int equalAdjCount=0;
-    std::list< Adjacent > adjList2=adl.getAdjList();
-    std::list<Adjacent>::iterator it1;
-    std::list<Adjacent>::iterator it2;
-    for(it1=m_adjList.begin() , it2=adjList2.begin() ;
-        it1!=m_adjList.end(); it1++,it2++)
-    {
-      if ( !(*it1).isEqual((*it2)) )
-      {
-        break;
-      }
-      equalAdjCount++;
-    }
-    return equalAdjCount==getSize();
-  }
-
-
-  int
-  Adl::updateAdjacentLinkCost(string adjName, double lc)
-  {
-    Adjacent adj(adjName);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it == m_adjList.end())
-    {
-      return -1;
-    }
-    (*it).setLinkCost(lc);
-    return 0;
-  }
-
-  bool
-  Adl::isNeighbor(string adjName)
-  {
-    Adjacent adj(adjName);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it == m_adjList.end())
-    {
-      return false;
-    }
-    return true;
-  }
-
-  void
-  Adl::incrementTimedOutInterestCount(string& neighbor)
-  {
-    Adjacent adj(neighbor);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it == m_adjList.end())
-    {
-      return ;
-    }
-    (*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
-  }
-
-  void
-  Adl::setTimedOutInterestCount(string& neighbor, int count)
-  {
-    Adjacent adj(neighbor);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it != m_adjList.end())
-    {
-      (*it).setInterestTimedOutNo(count);
-    }
-  }
-
-  int
-  Adl::getTimedOutInterestCount(string& neighbor)
-  {
-    Adjacent adj(neighbor);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it == m_adjList.end())
-    {
-      return -1;
-    }
-    return (*it).getInterestTimedOutNo();
-  }
-
-  int
-  Adl::getStatusOfNeighbor(string& neighbor)
-  {
-    Adjacent adj(neighbor);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it == m_adjList.end())
-    {
-      return -1;
-    }
-    return (*it).getStatus();
-  }
-
-  void
-  Adl::setStatusOfNeighbor(string& neighbor, int status)
-  {
-    Adjacent adj(neighbor);
-    std::list<Adjacent >::iterator it = std::find_if( m_adjList.begin(),
-                                        m_adjList.end(),
-                                        bind(&adjacent_compare, _1, adj));
-    if( it != m_adjList.end())
-    {
-      (*it).setStatus(status);
-    }
-  }
-
-  std::list<Adjacent>&
-  Adl::getAdjList()
-  {
-    return m_adjList;
-  }
-
-  bool
-  Adl::isAdjLsaBuildable(Nlsr& pnlsr)
-  {
-    int nbrCount=0;
-    for( std::list<Adjacent>::iterator it=m_adjList.begin();
-         it!= m_adjList.end() ; it++)
-    {
-      if ( ((*it).getStatus() == 1 ) )
-      {
-        nbrCount++;
-      }
-      else
-      {
-        if ( (*it).getInterestTimedOutNo() >=
-             pnlsr.getConfParameter().getInterestRetryNumber())
-        {
-          nbrCount++;
-        }
-      }
-    }
-    if( nbrCount == m_adjList.size())
-    {
-      return true;
-    }
-    return false;
-  }
-
-  int
-  Adl::getNumOfActiveNeighbor()
-  {
-    int actNbrCount=0;
-    for( std::list<Adjacent>::iterator it=m_adjList.begin();
-         it!= m_adjList.end() ; it++)
-    {
-      if ( ((*it).getStatus() == 1 ) )
-      {
-        actNbrCount++;
-      }
-    }
-    return actNbrCount;
-  }
-
-// used for debugging purpose
-  void
-  Adl::printAdl()
-  {
-    for( std::list<Adjacent>::iterator it=m_adjList.begin(); it!= m_adjList.end() ;
-         it++)
-    {
-      cout<< (*it) <<endl;
-    }
-  }
-
-} //namespace nlsr
diff --git a/src/nlsr_adl.hpp b/src/nlsr_adl.hpp
deleted file mode 100644
index ad85f01..0000000
--- a/src/nlsr_adl.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef NLSR_ADL_HPP
-#define NLSR_ADL_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include "nlsr_adjacent.hpp"
-#include<list>
-
-namespace nlsr
-{
-
-  class Nlsr;
-
-  using namespace std;
-
-  class Adl
-  {
-
-  public:
-    Adl();
-    ~Adl();
-    int insert(Adjacent& adj);
-    int updateAdjacentStatus(string adjName, int s);
-    int updateAdjacentLinkCost(string adjName, double lc);
-    std::list<Adjacent>& getAdjList();
-    bool isNeighbor(string adjName);
-    void incrementTimedOutInterestCount(string& neighbor);
-    int getTimedOutInterestCount(string& neighbor);
-    int getStatusOfNeighbor(string& neighbor);
-    void setStatusOfNeighbor(string& neighbor, int status);
-    void setTimedOutInterestCount(string& neighbor, int count);
-    void addAdjacentsFromAdl(Adl& adl);
-
-    bool isAdjLsaBuildable(Nlsr& pnlsr);
-    int getNumOfActiveNeighbor();
-    Adjacent getAdjacent(string adjName);
-
-    bool isEqual(Adl& adl);
-
-    int getSize()
-    {
-      return m_adjList.size();
-    }
-
-    void reset()
-    {
-      if( m_adjList.size() > 0 )
-      {
-        m_adjList.clear();
-      }
-    }
-
-    void printAdl();
-
-  private:
-    std::list< Adjacent > m_adjList;
-  };
-
-} //namespace nlsr
-#endif
diff --git a/src/nlsr_conf_param.cpp b/src/nlsr_conf_param.cpp
deleted file mode 100644
index 84f0f74..0000000
--- a/src/nlsr_conf_param.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include<iostream>
-#include "nlsr_conf_param.hpp"
-#include "utility/nlsr_logger.hpp"
-#define THIS_FILE "nlsr_conf_param.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  ostream&
-  operator << (ostream& os, ConfParameter& cfp)
-  {
-    os  <<"Router Name: "<< cfp.getRouterName()<<endl;
-    os  <<"Site Name: "<< cfp.getSiteName()<<endl;
-    os  <<"Network: "<< cfp.getNetwork()<<endl;
-    os  <<"Router Prefix: "<< cfp.getRouterPrefix()<<endl;
-    os  <<"ChronoSync sync Prifex: "<< cfp.getChronosyncSyncPrefix()<<endl;
-    os  <<"Interest Retry number: "<< cfp.getInterestRetryNumber()<<endl;
-    os  <<"Interest Resend second: "<< cfp.getInterestResendTime()<<endl;
-    os  <<"Info Interest Interval: "<<cfp.getInfoInterestInterval()<<endl;
-    os  <<"LSA refresh time: "<< cfp.getLsaRefreshTime()<<endl;
-    os  <<"Max Faces Per Prefix: "<< cfp.getMaxFacesPerPrefix()<<endl;
-    os  <<"Log Dir: "<< cfp.getLogDir()<<endl;
-    os  <<"Detalied logging: "<< cfp.getDetailedLogging()<<endl;
-    os  <<"Debugging: "<< cfp.getDebugging()<<endl;
-    os  <<"Hyperbolic ROuting: "<< cfp.getIsHyperbolicCalc()<<endl;
-    os  <<"Hyp R: "<< cfp.getCorR()<<endl;
-    os  <<"Hyp theta: "<< cfp.getCorTheta()<<endl;
-    os  <<"Tunnel Type: "<< cfp.getTunnelType()<<endl;
-    return os;
-  }
-
-} //namespace nlsr
diff --git a/src/nlsr_conf_param.hpp b/src/nlsr_conf_param.hpp
deleted file mode 100644
index ddfa1a0..0000000
--- a/src/nlsr_conf_param.hpp
+++ /dev/null
@@ -1,298 +0,0 @@
-#ifndef CONF_PARAM_HPP
-#define CONF_PARAM_HPP
-
-#include<iostream>
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class ConfParameter
-  {
-
-  public:
-    ConfParameter()
-      : m_chronosyncSyncPrefix("ndn/nlsr/sync")
-      , m_chronosyncLsaPrefix("/ndn/nlsr/LSA")
-      , m_rootKeyPrefix("/ndn/keys")
-      , isStrictHierchicalKeyCheck(0)
-      , m_interestRetryNumber(3)
-      , m_interestResendTime(5)
-      , m_infoInterestInterval(60)
-      , m_lsaRefreshTime(1800)
-      , m_routerDeadInterval(3600)
-      , m_maxFacesPerPrefix(0)
-      , m_tunnelType(0)
-      , m_detailedLogging(0)
-      , m_certDir()
-      , m_debugging(0)
-      , isHyperbolicCalc(0)
-      , m_seqFileDir()
-      , m_corR(0)
-      , m_corTheta(0)
-    {}
-
-    void setRouterName(const string& rn)
-    {
-      m_routerName=rn;
-    }
-
-    string getRouterName()
-    {
-      return m_routerName;
-    }
-
-    void setSiteName(const string& sn)
-    {
-      m_siteName=sn;
-    }
-
-    string getSiteName()
-    {
-      return m_siteName;
-    }
-
-    void setNetwork(const string& nn)
-    {
-      m_network=nn;
-    }
-
-    string getNetwork()
-    {
-      return m_network;
-    }
-
-    void buildRouterPrefix()
-    {
-      m_routerPrefix="/"+m_network+"/"+m_siteName+"/"+m_routerName;
-    }
-
-    string getRouterPrefix()
-    {
-      return m_routerPrefix;
-    }
-
-    string getRootKeyPrefix()
-    {
-      return m_rootKeyPrefix;
-    }
-
-    void setRootKeyPrefix(string rkp)
-    {
-      m_rootKeyPrefix=rkp;
-    }
-
-    void setInterestRetryNumber(int irn)
-    {
-      m_interestRetryNumber=irn;
-    }
-
-    int getInterestRetryNumber()
-    {
-      return m_interestRetryNumber;
-    }
-
-    void setInterestResendTime(int irt)
-    {
-      m_interestResendTime=irt;
-    }
-
-    int getInterestResendTime()
-    {
-      return m_interestResendTime;
-    }
-
-    void setLsaRefreshTime(int lrt)
-    {
-      m_lsaRefreshTime=lrt;
-      m_routerDeadInterval=2*m_lsaRefreshTime;
-    }
-
-    int getLsaRefreshTime()
-    {
-      return m_lsaRefreshTime;
-    }
-
-    void setRouterDeadInterval(int rdt)
-    {
-      m_routerDeadInterval=rdt;
-    }
-
-    long int getRouterDeadInterval()
-    {
-      return m_routerDeadInterval;
-    }
-
-    void setMaxFacesPerPrefix(int mfpp)
-    {
-      m_maxFacesPerPrefix=mfpp;
-    }
-
-    int getMaxFacesPerPrefix()
-    {
-      return m_maxFacesPerPrefix;
-    }
-
-    void setLogDir(string ld)
-    {
-      m_logDir=ld;
-    }
-
-    string getLogDir()
-    {
-      return m_logDir;
-    }
-
-    void setCertDir(std::string cd)
-    {
-      m_certDir=cd;
-    }
-
-    std::string getCertDir()
-    {
-      return m_certDir;
-    }
-
-    void setSeqFileDir(string ssfd)
-    {
-      m_seqFileDir=ssfd;
-    }
-
-    string getSeqFileDir()
-    {
-      return m_seqFileDir;
-    }
-
-    void setDetailedLogging(int dl)
-    {
-      m_detailedLogging=dl;
-    }
-
-    int getDetailedLogging()
-    {
-      return m_detailedLogging;
-    }
-
-    void setDebugging(int d)
-    {
-      m_debugging=d;
-    }
-
-    int getDebugging()
-    {
-      return m_debugging;
-    }
-
-    void setIsHyperbolicCalc(bool ihc)
-    {
-      isHyperbolicCalc=ihc;
-    }
-
-    bool getIsHyperbolicCalc()
-    {
-      return isHyperbolicCalc;
-    }
-
-    void setCorR(double cr)
-    {
-      m_corR=cr;
-    }
-
-    double getCorR()
-    {
-      return m_corR;
-    }
-
-    void setCorTheta(double ct)
-    {
-      m_corTheta=ct;
-    }
-
-    double getCorTheta()
-    {
-      return m_corTheta;
-    }
-
-    void setTunnelType(int tt)
-    {
-      m_tunnelType=tt;
-    }
-
-    int getTunnelType()
-    {
-      return m_tunnelType;
-    }
-
-    void setChronosyncSyncPrefix(const string& csp)
-    {
-      m_chronosyncSyncPrefix=csp;
-    }
-
-    string getChronosyncSyncPrefix()
-    {
-      return m_chronosyncSyncPrefix;
-    }
-
-    void setChronosyncLsaPrefix(string clp)
-    {
-      m_chronosyncLsaPrefix=clp;
-    }
-
-    string getChronosyncLsaPrefix()
-    {
-      return m_chronosyncLsaPrefix;
-    }
-
-    int getInfoInterestInterval()
-    {
-      return m_infoInterestInterval;
-    }
-
-    void setInfoInterestInterval(int iii)
-    {
-      m_infoInterestInterval=iii;
-    }
-
-  private:
-    string m_routerName;
-    string m_siteName;
-    string m_network;
-
-    string m_routerPrefix;
-    string m_lsaRouterPrefix;
-
-    string m_chronosyncSyncPrefix;
-    string m_chronosyncLsaPrefix;
-
-    string m_rootKeyPrefix;
-
-    int m_interestRetryNumber;
-    int m_interestResendTime;
-    int m_infoInterestInterval;
-    int m_lsaRefreshTime;
-    int m_routerDeadInterval;
-
-    int m_maxFacesPerPrefix;
-    string m_logDir;
-    string m_certDir;
-    string m_seqFileDir;
-    string m_logFile;
-    int m_detailedLogging;
-    int m_debugging;
-
-    bool isHyperbolicCalc;
-    double m_corR;
-    double m_corTheta;
-
-    int m_tunnelType;
-    bool isStrictHierchicalKeyCheck;
-
-  };
-
-  std::ostream&
-  operator << (std::ostream& os, ConfParameter& cfp);
-
-} // namespace nlsr
-
-#endif
diff --git a/src/nlsr_conf_processor.cpp b/src/nlsr_conf_processor.cpp
deleted file mode 100644
index fd3c9ef..0000000
--- a/src/nlsr_conf_processor.cpp
+++ /dev/null
@@ -1,562 +0,0 @@
-#include<iostream>
-#include<fstream>
-#include<string>
-#include<cstdlib>
-#include <sstream>
-
-#include "nlsr_conf_processor.hpp"
-#include "nlsr_conf_param.hpp"
-#include "utility/nlsr_tokenizer.hpp"
-#include "nlsr_adjacent.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_conf_processor.cpp"
-
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  int
-  ConfFileProcessor::processConfFile(Nlsr& pnlsr)
-  {
-    int ret=0;
-    if ( !m_confFileName.empty())
-    {
-      std::ifstream inputFile(m_confFileName.c_str());
-      if ( inputFile.is_open())
-      {
-        for( string line; getline( inputFile, line ); )
-        {
-          if (!line.empty() )
-          {
-            if(line[0]!= '#' && line[0]!='!')
-            {
-              ret=processConfCommand(pnlsr, line);
-              if( ret == -1 )
-              {
-                break;
-              }
-            }
-          }
-        }
-      }
-      else
-      {
-        std::cerr <<"Configuration file: ("<<m_confFileName<<") does not exist :(";
-        std::cerr <<endl;
-        ret=-1;
-      }
-    }
-    return ret;
-  }
-
-
-  int
-  ConfFileProcessor::processConfCommand(Nlsr& pnlsr, string command)
-  {
-    int ret=0;
-    nlsrTokenizer nt(command," ");
-    if( (nt.getFirstToken() == "network"))
-    {
-      ret=processConfCommandNetwork(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "site-name"))
-    {
-      ret=processConfCommandSiteName(pnlsr,nt.getRestOfLine());
-    }
-    else if ( (nt.getFirstToken() == "root-key-prefix"))
-    {
-      ret=processConfCommandRootKeyPrefix(pnlsr,nt.getRestOfLine());
-    }
-    else if ( (nt.getFirstToken() == "router-name"))
-    {
-      ret=processConfCommandRouterName(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "ndnneighbor") )
-    {
-      ret=processConfCommandNdnNeighbor(pnlsr, nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "link-cost"))
-    {
-      ret=processConfCommandLinkCost(pnlsr, nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "ndnname") )
-    {
-      ret=processConfCommandNdnName(pnlsr, nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "interest-retry-num"))
-    {
-      processConfCommandInterestRetryNumber(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "interest-resend-time"))
-    {
-      processConfCommandInterestResendTime(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "lsa-refresh-time"))
-    {
-      processConfCommandLsaRefreshTime(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "max-faces-per-prefix"))
-    {
-      processConfCommandMaxFacesPerPrefix(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "log-dir"))
-    {
-      processConfCommandLogDir(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "cert-dir"))
-    {
-      processConfCommandCertDir(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "detailed-logging") )
-    {
-      processConfCommandDetailedLogging(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "debugging") )
-    {
-      processConfCommandDebugging(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "chronosync-sync-prefix") )
-    {
-      processConfCommandChronosyncSyncPrefix(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "hyperbolic-cordinate") )
-    {
-      processConfCommandHyperbolicCordinate(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "hyperbolic-routing"))
-    {
-      processConfCommandIsHyperbolicCalc(pnlsr,nt.getRestOfLine());
-    }
-    else if( (nt.getFirstToken() == "tunnel-type"))
-    {
-      processConfCommandTunnelType(pnlsr,nt.getRestOfLine());
-    }
-    else
-    {
-      cout << "Wrong configuration Command: "<< nt.getFirstToken()<<endl;
-    }
-    return ret;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandNetwork(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Network can not be null or empty :( !"<<endl;
-      return -1;
-    }
-    else
-    {
-      if(command[command.size()-1] == '/' )
-      {
-        command.erase(command.size() - 1);
-      }
-      if(command[0] == '/' )
-      {
-        command.erase(0,1);
-      }
-      pnlsr.getConfParameter().setNetwork(command);
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandSiteName(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<"Site name can not be null or empty :( !"<<endl;
-      return -1;
-    }
-    else
-    {
-      if(command[command.size()-1] == '/' )
-      {
-        command.erase(command.size() - 1);
-      }
-      if(command[0] == '/' )
-      {
-        command.erase(0,1);
-      }
-      pnlsr.getConfParameter().setSiteName(command);
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<"Root Key Prefix can not be null or empty :( !"<<endl;
-      return -1;
-    }
-    else
-    {
-      if(command[command.size()-1] == '/' )
-      {
-        command.erase(command.size() - 1);
-      }
-      if(command[0] == '/' )
-      {
-        command.erase(0,1);
-      }
-      pnlsr.getConfParameter().setRootKeyPrefix(command);
-    }
-    return 0;
-  }
-
-
-  int
-  ConfFileProcessor::processConfCommandRouterName(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Router name can not be null or empty :( !"<<endl;
-      return -1;
-    }
-    else
-    {
-      if(command[command.size()-1] == '/' )
-      {
-        command.erase(command.size() - 1);
-      }
-      if(command[0] == '/' )
-      {
-        command.erase(0,1);
-      }
-      pnlsr.getConfParameter().setRouterName(command);
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandInterestRetryNumber(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [interest-retry-num n]"<<endl;
-    }
-    else
-    {
-      int irn;
-      stringstream ss(command.c_str());
-      ss>>irn;
-      if ( irn >=1 && irn <=5)
-      {
-        pnlsr.getConfParameter().setInterestRetryNumber(irn);
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandInterestResendTime(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
-    }
-    else
-    {
-      int irt;
-      stringstream ss(command.c_str());
-      ss>>irt;
-      if( irt>=1 && irt <=20)
-      {
-        pnlsr.getConfParameter().setInterestResendTime(irt);
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
-    }
-    else
-    {
-      int lrt;
-      stringstream ss(command.c_str());
-      ss>>lrt;
-      if ( lrt>= 240 && lrt<=7200)
-      {
-        pnlsr.getConfParameter().setLsaRefreshTime(lrt);
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [max-faces-per-prefix n]"<<endl;
-    }
-    else
-    {
-      int mfpp;
-      stringstream ss(command.c_str());
-      ss>>mfpp;
-      if ( mfpp>=0 && mfpp<=60)
-      {
-        pnlsr.getConfParameter().setMaxFacesPerPrefix(mfpp);
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandTunnelType(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
-    }
-    else
-    {
-      if(command == "tcp" || command == "TCP" )
-      {
-        pnlsr.getConfParameter().setTunnelType(1);
-      }
-      else if(command == "udp" || command == "UDP")
-      {
-        pnlsr.getConfParameter().setTunnelType(0);
-      }
-      else
-      {
-        cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [chronosync-sync-prefix name/prefix]!"<<endl;
-    }
-    else
-    {
-      pnlsr.getConfParameter().setChronosyncSyncPrefix(command);
-    }
-    return 0;
-  }
-
-
-  int
-  ConfFileProcessor::processConfCommandLogDir(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [log-dir /path/to/log/dir]!"<<endl;
-    }
-    else
-    {
-      pnlsr.getConfParameter().setLogDir(command);
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandCertDir(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [cert-dir /path/to/cert/dir]!"<<endl;
-    }
-    else
-    {
-      pnlsr.getConfParameter().setCertDir(command);
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandDebugging(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [debugging on/of]!"<<endl;
-    }
-    else
-    {
-      if(command == "on" || command == "ON" )
-      {
-        pnlsr.getConfParameter().setDebugging(1);
-      }
-      else if(command == "off" || command == "off")
-      {
-        pnlsr.getConfParameter().setDebugging(0);
-      }
-      else
-      {
-        cerr <<" Wrong command format ! [debugging on/off]!"<<endl;
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandDetailedLogging(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
-    }
-    else
-    {
-      if(command == "on" || command == "ON" )
-      {
-        pnlsr.getConfParameter().setDetailedLogging(1);
-      }
-      else if(command == "off" || command == "off")
-      {
-        pnlsr.getConfParameter().setDetailedLogging(0);
-      }
-      else
-      {
-        cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandIsHyperbolicCalc(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
-    }
-    else
-    {
-      if(command == "on" || command == "ON" )
-      {
-        pnlsr.getConfParameter().setIsHyperbolicCalc(1);
-      }
-      else if(command == "dry-run" || command == "DRY-RUN")
-      {
-        pnlsr.getConfParameter().setIsHyperbolicCalc(2);
-      }
-      else if(command == "off" || command == "off")
-      {
-        pnlsr.getConfParameter().setIsHyperbolicCalc(0);
-      }
-      else
-      {
-        cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandHyperbolicCordinate(Nlsr& pnlsr,
-      string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [hyperbolic-cordinate r 0]!"<<endl;
-      if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
-      {
-        return -1;
-      }
-    }
-    else
-    {
-      nlsrTokenizer nt(command," ");
-      stringstream ssr(nt.getFirstToken().c_str());
-      stringstream sst(nt.getRestOfLine().c_str());
-      double r,theta;
-      ssr>>r;
-      sst>>theta;
-      pnlsr.getConfParameter().setCorR(r);
-      pnlsr.getConfParameter().setCorTheta(theta);
-    }
-    return 0;
-  }
-
-
-  int
-  ConfFileProcessor::processConfCommandNdnNeighbor(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
-    }
-    else
-    {
-      nlsrTokenizer nt(command," ");
-      if( nt.getRestOfLine().empty())
-      {
-        cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
-        return 0;
-      }
-      else
-      {
-        stringstream sst(nt.getRestOfLine().c_str());
-        int faceId;
-        sst>>faceId;
-        Adjacent adj(nt.getFirstToken(),faceId,0.0,0,0);
-        pnlsr.getAdl().insert(adj);
-      }
-    }
-    return 0;
-  }
-
-  int
-  ConfFileProcessor::processConfCommandNdnName(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [ndnname name/prefix]!"<<endl;
-    }
-    else
-    {
-      pnlsr.getNpl().insert(command);
-    }
-    return 0;
-  }
-
-
-  int
-  ConfFileProcessor::processConfCommandLinkCost(Nlsr& pnlsr, string command)
-  {
-    if(command.empty() )
-    {
-      cerr <<" Wrong command format ! [link-cost nbr/name cost]!"<<endl;
-      if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
-      {
-        return -1;
-      }
-    }
-    else
-    {
-      nlsrTokenizer nt(command," ");
-      stringstream sst(nt.getRestOfLine().c_str());
-      double cost;
-      sst>>cost;
-      pnlsr.getAdl().updateAdjacentLinkCost(nt.getFirstToken(),cost);
-    }
-    return 0;
-  }
-
-} //namespace nlsr
-
diff --git a/src/nlsr_conf_processor.hpp b/src/nlsr_conf_processor.hpp
deleted file mode 100644
index 8448823..0000000
--- a/src/nlsr_conf_processor.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef CONF_PROCESSOR_HPP
-#define CONF_PROCESSOR_HPP
-
-#include "nlsr.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class ConfFileProcessor
-  {
-  public:
-    ConfFileProcessor()
-      :m_confFileName()
-    {
-    }
-    ConfFileProcessor(const string& cfile)
-    {
-      m_confFileName=cfile;
-    }
-
-    int processConfFile(Nlsr& pnlsr);
-
-  private:
-    int processConfCommand(Nlsr& pnlsr, string command);
-    int processConfCommandNetwork(Nlsr& pnlsr, string command);
-    int processConfCommandSiteName(Nlsr& pnlsr, string command);
-    int processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command);
-    int processConfCommandRouterName(Nlsr& pnlsr, string command);
-    int processConfCommandInterestRetryNumber(Nlsr& pnlsr, string command);
-    int processConfCommandInterestResendTime(Nlsr& pnlsr, string command);
-    int processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command);
-    int processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr, string command);
-    int processConfCommandTunnelType(Nlsr& pnlsr, string command);
-
-    int processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
-    int processConfCommandLogDir(Nlsr& pnlsr, string command);
-    int processConfCommandCertDir(Nlsr& pnlsr, string command);
-    int processConfCommandDebugging(Nlsr& pnlsr, string command);
-    int processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
-    int processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
-
-    int processConfCommandHyperbolicCordinate(Nlsr& pnlsr, string command);
-
-    int processConfCommandNdnNeighbor(Nlsr& pnlsr, string command);
-    int processConfCommandNdnName(Nlsr& pnlsr, string command);
-    int processConfCommandLinkCost(Nlsr& pnlsr, string command);
-
-
-  private:
-    string m_confFileName;
-  };
-
-} //namespace nlsr
-#endif
diff --git a/src/nlsr_lsa.cpp b/src/nlsr_lsa.cpp
deleted file mode 100644
index 0f97568..0000000
--- a/src/nlsr_lsa.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-#include<string>
-#include<iostream>
-#include<sstream>
-#include<algorithm>
-#include<cmath>
-#include<limits>
-
-#include "nlsr.hpp"
-#include "nlsr_lsa.hpp"
-#include "nlsr_npl.hpp"
-#include "nlsr_adjacent.hpp"
-#include "utility/nlsr_tokenizer.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_lsa.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-
-  string
-  NameLsa::getKey()
-  {
-    string key;
-    key=m_origRouter + "/" + boost::lexical_cast<std::string>(1);
-    return key;
-  }
-
-  NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
-  {
-    m_origRouter=origR;
-    m_lsType=lst;
-    m_lsSeqNo=lsn;
-    m_lifeTime=lt;
-    std::list<string> nl=npl.getNameList();
-    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-    {
-      addName((*it));
-    }
-  }
-
-  string
-  NameLsa::getData()
-  {
-    string nameLsaData;
-    nameLsaData=m_origRouter + "|" + boost::lexical_cast<std::string>(1) + "|"
-                + boost::lexical_cast<std::string>(m_lsSeqNo) + "|"
-                + boost::lexical_cast<std::string>(m_lifeTime);
-    nameLsaData+="|";
-    nameLsaData+=boost::lexical_cast<std::string>(m_npl.getSize());
-    std::list<string> nl=m_npl.getNameList();
-    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-    {
-      nameLsaData+="|";
-      nameLsaData+=(*it);
-    }
-    return nameLsaData+"|";
-  }
-
-  bool
-  NameLsa::initializeFromContent(string content)
-  {
-    uint32_t numName=0;
-    nlsrTokenizer nt(content, "|");
-    m_origRouter=nt.getNextToken();
-    if(m_origRouter.empty())
-    {
-      return false;
-    }
-    try
-    {
-      m_lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
-      m_lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
-      m_lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
-      numName=boost::lexical_cast<uint32_t>(nt.getNextToken());
-    }
-    catch(std::exception &e)
-    {
-      return false;
-    }
-    for(int i=0; i<numName; i++)
-    {
-      string name=nt.getNextToken();
-      addName(name);
-    }
-    return true;
-  }
-  
-  void
-  NameLsa::writeLog()
-  {
-    src::logger lg;
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Name-LSA";
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"  Origination Router: "
-                 <<m_origRouter;
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"  LS Type: "<<m_lsType;
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"  LS Seq: "<<m_lsSeqNo;
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"  LS Lifetime: "<<m_lifeTime;
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"  LS Data: ";
-    int i=1;
-    std::list<string> nl=m_npl.getNameList();
-    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-    {
-      BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"    Name "<<i<<": "<<(*it);
-    }
-    BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"name_lsa_end";
-  }
-
-  std::ostream&
-  operator<<(std::ostream& os, NameLsa& nLsa)
-  {
-    os<<"Name Lsa: "<<endl;
-    os<<"  Origination Router: "<<nLsa.getOrigRouter()<<endl;
-    os<<"  Ls Type: "<<(unsigned short)nLsa.getLsType()<<endl;
-    os<<"  Ls Seq No: "<<(unsigned int)nLsa.getLsSeqNo()<<endl;
-    os<<"  Ls Lifetime: "<<(unsigned int)nLsa.getLifeTime()<<endl;
-    os<<"  Names: "<<endl;
-    int i=1;
-    std::list<string> nl=nLsa.getNpl().getNameList();
-    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-    {
-      os<<"    Name "<<i<<": "<<(*it)<<endl;
-    }
-    return os;
-  }
-
-
-
-  CorLsa::CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
-                 , double r, double theta)
-  {
-    m_origRouter=origR;
-    m_lsType=lst;
-    m_lsSeqNo=lsn;
-    m_lifeTime=lt;
-    m_corRad=r;
-    m_corTheta=theta;
-  }
-
-  string
-  CorLsa::getKey()
-  {
-    string key;
-    key=m_origRouter + "/" + boost::lexical_cast<std::string>(3);
-    return key;
-  }
-
-  bool
-  CorLsa::isEqual(CorLsa& clsa)
-  {
-    return (std::abs(m_corRad - clsa.getCorRadius()) <
-            std::numeric_limits<double>::epsilon()) &&
-           (std::abs(m_corTheta - clsa.getCorTheta()) <
-            std::numeric_limits<double>::epsilon());
-  }
-
-  string
-  CorLsa::getData()
-  {
-    string corLsaData;
-    corLsaData=m_origRouter + "|";
-    corLsaData+=(boost::lexical_cast<std::string>(3) + "|");
-    corLsaData+=(boost::lexical_cast<std::string>(m_lsSeqNo) + "|");
-    corLsaData+=(boost::lexical_cast<std::string>(m_lifeTime) + "|");
-    corLsaData+=(boost::lexical_cast<std::string>(m_corRad) + "|");
-    corLsaData+=(boost::lexical_cast<std::string>(m_corTheta) + "|");
-    return corLsaData;
-  }
-
-  bool
-  CorLsa::initializeFromContent(string content)
-  {
-    nlsrTokenizer nt(content, "|");
-    m_origRouter=nt.getNextToken();
-    if(m_origRouter.empty())
-    {
-      return false;
-    }
-    try
-    {
-      m_lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
-      m_lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
-      m_lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
-      m_corRad=boost::lexical_cast<double>(nt.getNextToken());
-      m_corTheta=boost::lexical_cast<double>(nt.getNextToken());
-    }
-    catch(std::exception &e)
-    {
-      return false;
-    }
-    return true;
-  }
-
-  std::ostream&
-  operator<<(std::ostream& os, CorLsa& cLsa)
-  {
-    os<<"Cor Lsa: "<<endl;
-    os<<"  Origination Router: "<<cLsa.getOrigRouter()<<endl;
-    os<<"  Ls Type: "<<(unsigned short)cLsa.getLsType()<<endl;
-    os<<"  Ls Seq No: "<<(unsigned int)cLsa.getLsSeqNo()<<endl;
-    os<<"  Ls Lifetime: "<<(unsigned int)cLsa.getLifeTime()<<endl;
-    os<<"    Hyperbolic Radius: "<<cLsa.getCorRadius()<<endl;
-    os<<"    Hyperbolic Theta: "<<cLsa.getCorTheta()<<endl;
-    return os;
-  }
-
-
-  AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
-                 uint32_t nl ,Adl padl)
-  {
-    m_origRouter=origR;
-    m_lsType=lst;
-    m_lsSeqNo=lsn;
-    m_lifeTime=lt;
-    m_noLink=nl;
-    std::list<Adjacent> al=padl.getAdjList();
-    for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-    {
-      if((*it).getStatus()==1)
-      {
-        addAdjacent((*it));
-      }
-    }
-  }
-
-  string
-  AdjLsa::getKey()
-  {
-    string key;
-    key=m_origRouter + "/" + boost::lexical_cast<std::string>(2);
-    return key;
-  }
-
-  bool
-  AdjLsa::isEqual(AdjLsa& alsa)
-  {
-    return m_adl.isEqual(alsa.getAdl());
-  }
-
-
-  string
-  AdjLsa::getData()
-  {
-    string adjLsaData;
-    adjLsaData=m_origRouter + "|" + boost::lexical_cast<std::string>(2) + "|"
-               + boost::lexical_cast<std::string>(m_lsSeqNo) + "|"
-               + boost::lexical_cast<std::string>(m_lifeTime);
-    adjLsaData+="|";
-    adjLsaData+=boost::lexical_cast<std::string>(m_adl.getSize());
-    std::list<Adjacent> al=m_adl.getAdjList();
-    for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-    {
-      adjLsaData+="|";
-      adjLsaData+=(*it).getName();
-      adjLsaData+="|";
-      adjLsaData+=boost::lexical_cast<std::string>((*it).getConnectingFace());
-      adjLsaData+="|";
-      adjLsaData+=boost::lexical_cast<std::string>((*it).getLinkCost());
-    }
-    return adjLsaData+"|";
-  }
-
-  bool
-  AdjLsa::initializeFromContent(string content)
-  {
-    uint32_t numLink=0;
-    nlsrTokenizer nt(content, "|");
-    m_origRouter=nt.getNextToken();
-    if(m_origRouter.empty())
-    {
-      return false;
-    }
-    try
-    {
-      m_lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
-      m_lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
-      m_lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
-      numLink=boost::lexical_cast<uint32_t>(nt.getNextToken());
-    }
-    catch(std::exception &e)
-    {
-      return false;
-    }
-    for(int i=0; i< numLink; i++)
-    {
-      try
-      {
-        string adjName=nt.getNextToken();
-        int connectingFace=boost::lexical_cast<int>(nt.getNextToken());
-        double linkCost=boost::lexical_cast<double>(nt.getNextToken());
-        Adjacent adjacent(adjName, connectingFace, linkCost, 0, 0);
-        addAdjacent(adjacent);
-      }
-      catch( std::exception &e )
-      {
-        return false;
-      }
-    }
-    return true;
-  }
-
-
-  void
-  AdjLsa::addNptEntries(Nlsr& pnlsr)
-  {
-    if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-    {
-      pnlsr.getNpt().addNpteByDestName(getOrigRouter(), getOrigRouter(),pnlsr);
-    }
-  }
-
-
-  void
-  AdjLsa::removeNptEntries(Nlsr& pnlsr)
-  {
-    if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-    {
-      pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(),pnlsr);
-    }
-  }
-
-
-
-  std::ostream&
-  operator<<(std::ostream& os, AdjLsa& aLsa)
-  {
-    os<<"Adj Lsa: "<<endl;
-    os<<"  Origination Router: "<<aLsa.getOrigRouter()<<endl;
-    os<<"  Ls Type: "<<(unsigned short)aLsa.getLsType()<<endl;
-    os<<"  Ls Seq No: "<<(unsigned int)aLsa.getLsSeqNo()<<endl;
-    os<<"  Ls Lifetime: "<<(unsigned int)aLsa.getLifeTime()<<endl;
-    os<<"  No Link: "<<(unsigned int)aLsa.getNoLink()<<endl;
-    os<<"  Adjacents: "<<endl;
-    int i=1;
-    std::list<Adjacent> al=aLsa.getAdl().getAdjList();
-    for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-    {
-      os<<"    Adjacent "<<i<<": "<<endl;
-      os<<"      Adjacent Name: "<<(*it).getName()<<endl;
-      os<<"      Connecting Face: "<<(*it).getConnectingFace()<<endl;
-      os<<"      Link Cost: "<<(*it).getLinkCost()<<endl;
-    }
-    return os;
-  }
-
-}//namespace nlsr
diff --git a/src/nlsr_lsa.hpp b/src/nlsr_lsa.hpp
deleted file mode 100644
index 878d688..0000000
--- a/src/nlsr_lsa.hpp
+++ /dev/null
@@ -1,223 +0,0 @@
-#ifndef NLSR_LSA_HPP
-#define NLSR_LSA_HPP
-
-#include <ndn-cpp-dev/util/scheduler.hpp>
-#include "nlsr_adjacent.hpp"
-#include "nlsr_npl.hpp"
-#include "nlsr_adl.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-  using namespace ndn;
-
-  class Lsa
-  {
-  public:
-    Lsa()
-      : m_origRouter()
-      , m_lsSeqNo()
-      , m_lifeTime()
-      , m_expiringEventId()
-    {
-    }
-
-
-    void setLsType(uint8_t lst)
-    {
-      m_lsType=lst;
-    }
-
-    uint8_t getLsType()
-    {
-      return m_lsType;
-    }
-
-    void setLsSeqNo(uint32_t lsn)
-    {
-      m_lsSeqNo=lsn;
-    }
-
-    uint32_t getLsSeqNo()
-    {
-      return m_lsSeqNo;
-    }
-
-    string& getOrigRouter()
-    {
-      return m_origRouter;
-    }
-
-    void setOrigRouter(string& org)
-    {
-      m_origRouter=org;
-    }
-
-    uint32_t getLifeTime()
-    {
-      return m_lifeTime;
-    }
-
-    void setLifeTime(uint32_t lt)
-    {
-      m_lifeTime=lt;
-    }
-
-    void setExpiringEventId(ndn::EventId leei)
-    {
-      m_expiringEventId=leei;
-    }
-
-    ndn::EventId getExpiringEventId()
-    {
-      return m_expiringEventId;
-    }
-
-  protected:
-    string m_origRouter;
-    uint8_t m_lsType;
-    uint32_t m_lsSeqNo;
-    uint32_t m_lifeTime;
-    ndn::EventId m_expiringEventId;
-  };
-
-  class NameLsa:public Lsa
-  {
-  public:
-    NameLsa()
-      : Lsa()
-      , m_npl()
-    {
-      setLsType(1);
-    }
-
-    NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
-
-    Npl& getNpl()
-    {
-      return m_npl;
-    }
-
-    void addName(string& name)
-    {
-      m_npl.insert(name);
-    }
-
-    void removeName(string& name)
-    {
-      m_npl.remove(name);
-    }
-
-    string getKey();
-
-    string getData();
-    bool initializeFromContent(string content);
-    void writeLog();
-
-  private:
-    Npl m_npl;
-
-  };
-
-  std::ostream&
-  operator<<(std::ostream& os, NameLsa& nLsa);
-
-  class AdjLsa: public Lsa
-  {
-  public:
-    AdjLsa()
-      : Lsa()
-      , m_adl()
-    {
-      setLsType(2);
-    }
-
-    AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
-           uint32_t nl ,Adl padl);
-    Adl& getAdl()
-    {
-      return m_adl;
-    }
-
-    void addAdjacent(Adjacent adj)
-    {
-      m_adl.insert(adj);
-    }
-    string getKey();
-    string getData();
-    bool initializeFromContent(string content);
-    uint32_t getNoLink()
-    {
-      return m_noLink;
-    }
-
-    bool isEqual(AdjLsa& alsa);
-    void addNptEntries(Nlsr& pnlsr);
-    void removeNptEntries(Nlsr& pnlsr);
-
-  private:
-    uint32_t m_noLink;
-    Adl m_adl;
-  };
-
-  std::ostream&
-  operator<<(std::ostream& os, AdjLsa& aLsa);
-
-  class CorLsa:public Lsa
-  {
-  public:
-    CorLsa()
-      : Lsa()
-      , m_corRad(0)
-      , m_corTheta(0)
-    {
-      setLsType(3);
-    }
-
-    CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
-           , double r, double theta);
-    string getKey();
-    string getData();
-    bool initializeFromContent(string content);
-    double getCorRadius()
-    {
-      if ( m_corRad >= 0 )
-      {
-        return m_corRad;
-      }
-      else
-      {
-        return -1;
-      }
-    }
-
-    void setCorRadius(double cr)
-    {
-      m_corRad=cr;
-    }
-
-    double getCorTheta()
-    {
-      return m_corTheta;
-    }
-
-    void setCorTheta(double ct)
-    {
-      m_corTheta=ct;
-    }
-
-    bool isEqual(CorLsa& clsa);
-  private:
-    double m_corRad;
-    double m_corTheta;
-
-  };
-
-  std::ostream&
-  operator<<(std::ostream& os, CorLsa& cLsa);
-
-
-}//namespace nlsr
-
-#endif
diff --git a/src/nlsr_lsdb.cpp b/src/nlsr_lsdb.cpp
deleted file mode 100644
index f2e4433..0000000
--- a/src/nlsr_lsdb.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-#include<string>
-#include<utility>
-#include "nlsr_lsdb.hpp"
-#include "nlsr.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_lsdb.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  void
-  Lsdb::cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid)
-  {
-    pnlsr.getScheduler().cancelEvent(eid);
-  }
-
-  static bool
-  nameLsaCompareByKey(NameLsa& nlsa1, string& key)
-  {
-    return nlsa1.getKey()==key;
-  }
-
-
-  bool
-  Lsdb::buildAndInstallOwnNameLsa(Nlsr& pnlsr)
-  {
-    NameLsa nameLsa(pnlsr.getConfParameter().getRouterPrefix()
-                    , 1
-                    , pnlsr.getSm().getNameLsaSeq()+1
-                    , pnlsr.getConfParameter().getRouterDeadInterval()
-                    , pnlsr.getNpl() );
-    pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq()+1);
-    return installNameLsa(pnlsr,nameLsa);
-  }
-
-  std::pair<NameLsa&, bool>
-  Lsdb::getNameLsa(string key)
-  {
-    std::list<NameLsa >::iterator it = std::find_if( m_nameLsdb.begin(),
-                                       m_nameLsdb.end(),
-                                       bind(nameLsaCompareByKey, _1, key));
-    if( it != m_nameLsdb.end())
-    {
-      return std::make_pair(boost::ref((*it)),true);
-    }
-    NameLsa nlsa;
-    return std::make_pair(boost::ref(nlsa),false);
-  }
-
-  bool
-  Lsdb::isNameLsaNew(string key, uint64_t seqNo)
-  {
-    std::pair<NameLsa& , bool>  nameLsaCheck=getNameLsa(key);
-    if(nameLsaCheck.second)
-    {
-      if(nameLsaCheck.first.getLsSeqNo() < seqNo)
-      {
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  ndn::EventId
-  Lsdb::scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
-  {
-    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-           ndn::bind(&Lsdb::exprireOrRefreshNameLsa,
-                     this,boost::ref(pnlsr), key, seqNo));
-  }
-
-  bool
-  Lsdb::installNameLsa(Nlsr& pnlsr, NameLsa &nlsa)
-  {
-    src::logger lg;
-    int timeToExpire=m_lsaRefreshTime;
-    std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(nlsa.getKey());
-    if ( !chkNameLsa.second )
-    {
-      BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Adding name lsa";
-      addNameLsa(nlsa);
-      nlsa.writeLog();
-      printNameLsdb();
-      if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      {
-        pnlsr.getNpt().addNpteByDestName(nlsa.getOrigRouter(),nlsa.getOrigRouter(),
-                                         pnlsr);
-        std::list<string> nameList=nlsa.getNpl().getNameList();
-        for(std::list<string>::iterator it=nameList.begin(); it!=nameList.end(); it++)
-        {
-          if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-          {
-            pnlsr.getNpt().addNpteByDestName((*it),nlsa.getOrigRouter(),pnlsr);
-          }
-        }
-      }
-      if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      {
-        timeToExpire=nlsa.getLifeTime();
-      }
-      nlsa.setExpiringEventId(scheduleNameLsaExpiration( pnlsr,
-                                 nlsa.getKey(), nlsa.getLsSeqNo(), timeToExpire));
-    }
-    else
-    {
-      if ( chkNameLsa.first.getLsSeqNo() < nlsa.getLsSeqNo() )
-      {
-        BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Deleting name lsa";
-        chkNameLsa.first.writeLog();
-        chkNameLsa.first.setLsSeqNo(nlsa.getLsSeqNo());
-        chkNameLsa.first.setLifeTime(nlsa.getLifeTime());
-        chkNameLsa.first.getNpl().sort();
-        nlsa.getNpl().sort();
-        std::list<string> nameToAdd;
-        std::set_difference(nlsa.getNpl().getNameList().begin(),
-                            nlsa.getNpl().getNameList().end(),
-                            chkNameLsa.first.getNpl().getNameList().begin(),
-                            chkNameLsa.first.getNpl().getNameList().end(),
-                            std::inserter(nameToAdd, nameToAdd.begin()));
-        for(std::list<string>::iterator it=nameToAdd.begin(); it!=nameToAdd.end();
-            ++it)
-        {
-          chkNameLsa.first.addName((*it));
-          if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-          {
-            if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-            {
-              pnlsr.getNpt().addNpteByDestName((*it),nlsa.getOrigRouter(),pnlsr);
-            }
-          }
-        }
-        std::list<string> nameToRemove;
-        std::set_difference(chkNameLsa.first.getNpl().getNameList().begin(),
-                            chkNameLsa.first.getNpl().getNameList().end(),
-                            nlsa.getNpl().getNameList().begin(),
-                            nlsa.getNpl().getNameList().end(),
-                            std::inserter(nameToRemove, nameToRemove.begin()));
-        for(std::list<string>::iterator it=nameToRemove.begin();
-            it!=nameToRemove.end(); ++it)
-        {
-          chkNameLsa.first.removeName((*it));
-          if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-          {
-            if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-            {
-              pnlsr.getNpt().removeNpte((*it),nlsa.getOrigRouter(),pnlsr);
-            }
-          }
-        }
-        if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-        {
-          timeToExpire=nlsa.getLifeTime();
-        }
-        cancelScheduleLsaExpiringEvent(pnlsr,
-                                       chkNameLsa.first.getExpiringEventId());
-        chkNameLsa.first.setExpiringEventId(scheduleNameLsaExpiration( pnlsr,
-                                               nlsa.getKey(), nlsa.getLsSeqNo(), timeToExpire));
-        BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Adding name lsa";
-        chkNameLsa.first.writeLog();
-      }
-    }
-    return true;
-  }
-
-  bool
-  Lsdb::addNameLsa(NameLsa &nlsa)
-  {
-    std::list<NameLsa >::iterator it = std::find_if( m_nameLsdb.begin(),
-                                       m_nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getKey()));
-    if( it == m_nameLsdb.end())
-    {
-      m_nameLsdb.push_back(nlsa);
-      return true;
-    }
-    return false;
-  }
-
-  bool
-  Lsdb::removeNameLsa(Nlsr& pnlsr, string& key)
-  {
-    src::logger lg;
-    std::list<NameLsa >::iterator it = std::find_if( m_nameLsdb.begin(),
-                                       m_nameLsdb.end(),
-                                       bind(nameLsaCompareByKey, _1, key));
-    if ( it != m_nameLsdb.end() )
-    {
-      BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Deleting name lsa";
-      (*it).writeLog();
-      if ( (*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()  )
-      {
-        pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
-        for( std::list<string>::iterator nit=(*it).getNpl().getNameList().begin();
-             nit!=(*it).getNpl().getNameList().end(); ++nit)
-        {
-          if ( (*nit) !=pnlsr.getConfParameter().getRouterPrefix())
-          {
-            pnlsr.getNpt().removeNpte((*nit),(*it).getOrigRouter(),pnlsr);
-          }
-        }
-      }
-      m_nameLsdb.erase(it);
-      return true;
-    }
-    return false;
-  }
-
-  bool
-  Lsdb::doesNameLsaExist(string key)
-  {
-    std::list<NameLsa >::iterator it = std::find_if( m_nameLsdb.begin(),
-                                       m_nameLsdb.end(),
-                                       bind(nameLsaCompareByKey, _1, key));
-    if( it == m_nameLsdb.end())
-    {
-      return false;
-    }
-    return true;
-  }
-
-  void
-  Lsdb::printNameLsdb()
-  {
-    cout<<"---------------Name LSDB-------------------"<<endl;
-    for( std::list<NameLsa>::iterator it=m_nameLsdb.begin();
-         it!= m_nameLsdb.end() ; it++)
-    {
-      cout<< (*it) <<endl;
-    }
-  }
-
-// Cor LSA and LSDB related Functions start here
-
-
-  static bool
-  corLsaCompareByKey(CorLsa& clsa, string& key)
-  {
-    return clsa.getKey()==key;
-  }
-
-  bool
-  Lsdb::buildAndInstallOwnCorLsa(Nlsr& pnlsr)
-  {
-    CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
-                  , 3
-                  , pnlsr.getSm().getCorLsaSeq()+1
-                  , pnlsr.getConfParameter().getRouterDeadInterval()
-                  , pnlsr.getConfParameter().getCorR()
-                  , pnlsr.getConfParameter().getCorTheta() );
-    pnlsr.getSm().setCorLsaSeq(pnlsr.getSm().getCorLsaSeq()+1);
-    installCorLsa(pnlsr, corLsa);
-    return true;
-  }
-
-  std::pair<CorLsa&, bool>
-  Lsdb::getCorLsa(string key)
-  {
-    std::list< CorLsa >::iterator it = std::find_if( m_corLsdb.begin(),
-                                       m_corLsdb.end(),
-                                       bind(corLsaCompareByKey, _1, key));
-    if( it != m_corLsdb.end())
-    {
-      return std::make_pair(boost::ref((*it)), true);
-    }
-    CorLsa clsa;
-    return std::make_pair(boost::ref(clsa),false);
-  }
-
-  bool
-  Lsdb::isCorLsaNew(string key, uint64_t seqNo)
-  {
-    std::pair<CorLsa& , bool>  corLsaCheck=getCorLsa(key);
-    if(corLsaCheck.second)
-    {
-      if(corLsaCheck.first.getLsSeqNo() < seqNo)
-      {
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  ndn::EventId
-  Lsdb::scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
-  {
-    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-           ndn::bind(&Lsdb::exprireOrRefreshCorLsa,
-                     this,boost::ref(pnlsr),key,seqNo));
-  }
-
-  bool
-  Lsdb::installCorLsa(Nlsr& pnlsr, CorLsa &clsa)
-  {
-    int timeToExpire=m_lsaRefreshTime;
-    std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(clsa.getKey());
-    if ( !chkCorLsa.second )
-    {
-      addCorLsa(clsa);
-      printCorLsdb(); //debugging purpose
-      if ( clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      {
-        pnlsr.getNpt().addNpteByDestName(clsa.getOrigRouter(),clsa.getOrigRouter(),
-                                         pnlsr);
-      }
-      if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-      {
-        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-      }
-      if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      {
-        timeToExpire=clsa.getLifeTime();
-      }
-      scheduleCorLsaExpiration(pnlsr,clsa.getKey(),
-                               clsa.getLsSeqNo(), timeToExpire);
-    }
-    else
-    {
-      if ( chkCorLsa.first.getLsSeqNo() < clsa.getLsSeqNo() )
-      {
-        chkCorLsa.first.setLsSeqNo(clsa.getLsSeqNo());
-        chkCorLsa.first.setLifeTime(clsa.getLifeTime());
-        if ( !chkCorLsa.first.isEqual(clsa) )
-        {
-          chkCorLsa.first.setCorRadius(clsa.getCorRadius());
-          chkCorLsa.first.setCorTheta(clsa.getCorTheta());
-          if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-          {
-            pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-          }
-        }
-        if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-        {
-          timeToExpire=clsa.getLifeTime();
-        }
-        cancelScheduleLsaExpiringEvent(pnlsr,
-                                       chkCorLsa.first.getExpiringEventId());
-        chkCorLsa.first.setExpiringEventId(scheduleCorLsaExpiration(pnlsr,
-                                              clsa.getKey(),
-                                              clsa.getLsSeqNo(), timeToExpire));
-      }
-    }
-    return true;
-  }
-
-  bool
-  Lsdb::addCorLsa(CorLsa& clsa)
-  {
-    std::list<CorLsa >::iterator it = std::find_if( m_corLsdb.begin(),
-                                      m_corLsdb.end(),
-                                      bind(corLsaCompareByKey, _1, clsa.getKey()));
-    if( it == m_corLsdb.end())
-    {
-      m_corLsdb.push_back(clsa);
-      return true;
-    }
-    return false;
-  }
-
-  bool
-  Lsdb::removeCorLsa(Nlsr& pnlsr, string& key)
-  {
-    std::list<CorLsa >::iterator it = std::find_if( m_corLsdb.begin(),
-                                      m_corLsdb.end(),
-                                      bind(corLsaCompareByKey, _1, key));
-    if ( it != m_corLsdb.end() )
-    {
-      if ( (*it).getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      {
-        pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
-      }
-      m_corLsdb.erase(it);
-      return true;
-    }
-    return false;
-  }
-
-  bool
-  Lsdb::doesCorLsaExist(string key)
-  {
-    std::list<CorLsa >::iterator it = std::find_if( m_corLsdb.begin(),
-                                      m_corLsdb.end(),
-                                      bind(corLsaCompareByKey, _1, key));
-    if( it == m_corLsdb.end())
-    {
-      return false;
-    }
-    return true;
-  }
-
-  void
-  Lsdb::printCorLsdb() //debugging
-  {
-    cout<<"---------------Cor LSDB-------------------"<<endl;
-    for( std::list<CorLsa>::iterator it=m_corLsdb.begin();
-         it!= m_corLsdb.end() ; it++)
-    {
-      cout<< (*it) <<endl;
-    }
-  }
-
-
-// Adj LSA and LSDB related function starts here
-
-  static bool
-  adjLsaCompareByKey(AdjLsa& alsa, string& key)
-  {
-    return alsa.getKey()==key;
-  }
-
-
-  void
-  Lsdb::scheduledAdjLsaBuild(Nlsr& pnlsr)
-  {
-    cout<<"scheduledAdjLsaBuild Called"<<endl;
-    pnlsr.setIsBuildAdjLsaSheduled(0);
-    if( pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
-    {
-      int adjBuildCount=pnlsr.getAdjBuildCount();
-      if(adjBuildCount>0 )
-      {
-        if (pnlsr.getAdl().getNumOfActiveNeighbor()>0)
-        {
-          buildAndInstallOwnAdjLsa(pnlsr);
-        }
-        else
-        {
-          string key=pnlsr.getConfParameter().getRouterPrefix()+"/2";
-          removeAdjLsa(pnlsr,key);
-          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-        }
-        pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount()-adjBuildCount);
-      }
-    }
-    else
-    {
-      pnlsr.setIsBuildAdjLsaSheduled(1);
-      int schedulingTime=pnlsr.getConfParameter().getInterestRetryNumber()*
-                         pnlsr.getConfParameter().getInterestResendTime();
-      pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(schedulingTime),
-                                         ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
-                                             boost::ref(pnlsr)));
-    }
-  }
-
-
-  bool
-  Lsdb::addAdjLsa(AdjLsa &alsa)
-  {
-    std::list<AdjLsa >::iterator it = std::find_if( m_adjLsdb.begin(),
-                                      m_adjLsdb.end(),
-                                      bind(adjLsaCompareByKey, _1, alsa.getKey()));
-    if( it == m_adjLsdb.end())
-    {
-      m_adjLsdb.push_back(alsa);
-      return true;
-    }
-    return false;
-  }
-
-  std::pair<AdjLsa& , bool>
-  Lsdb::getAdjLsa(string key)
-  {
-    std::list<AdjLsa >::iterator it = std::find_if( m_adjLsdb.begin(),
-                                      m_adjLsdb.end(),
-                                      bind(adjLsaCompareByKey, _1, key));
-    if( it != m_adjLsdb.end())
-    {
-      return std::make_pair(boost::ref((*it)),true);
-    }
-    AdjLsa alsa;
-    return std::make_pair(boost::ref(alsa),false);
-  }
-
-
-  bool
-  Lsdb::isAdjLsaNew(string key, uint64_t seqNo)
-  {
-    std::pair<AdjLsa& , bool>  adjLsaCheck=getAdjLsa(key);
-    if(adjLsaCheck.second)
-    {
-      if(adjLsaCheck.first.getLsSeqNo() < seqNo)
-      {
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-    return true;
-  }
-
-
-  ndn::EventId
-  Lsdb::scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
-  {
-    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-           ndn::bind(&Lsdb::exprireOrRefreshAdjLsa,
-                     this,boost::ref(pnlsr),key,seqNo));
-  }
-
-  bool
-  Lsdb::installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa)
-  {
-    int timeToExpire=m_lsaRefreshTime;
-    std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(alsa.getKey());
-    if ( !chkAdjLsa.second )
-    {
-      addAdjLsa(alsa);
-      alsa.addNptEntries(pnlsr);
-      pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-      if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      {
-        timeToExpire=alsa.getLifeTime();
-      }
-      scheduleAdjLsaExpiration(pnlsr,alsa.getKey(),
-                               alsa.getLsSeqNo(),timeToExpire);
-    }
-    else
-    {
-      if ( chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo() )
-      {
-        chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
-        chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
-        if ( !	chkAdjLsa.first.isEqual(alsa))
-        {
-          chkAdjLsa.first.getAdl().reset();
-          chkAdjLsa.first.getAdl().addAdjacentsFromAdl(alsa.getAdl());
-          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-        }
-        if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-        {
-          timeToExpire=alsa.getLifeTime();
-        }
-        cancelScheduleLsaExpiringEvent(pnlsr,
-                                       chkAdjLsa.first.getExpiringEventId());
-        chkAdjLsa.first.setExpiringEventId(scheduleAdjLsaExpiration(pnlsr,
-                                              alsa.getKey(), alsa.getLsSeqNo(),timeToExpire));
-      }
-    }
-    return true;
-  }
-
-  bool
-  Lsdb::buildAndInstallOwnAdjLsa(Nlsr& pnlsr)
-  {
-    AdjLsa adjLsa(pnlsr.getConfParameter().getRouterPrefix()
-                  , 2
-                  , pnlsr.getSm().getAdjLsaSeq()+1
-                  , pnlsr.getConfParameter().getRouterDeadInterval()
-                  , pnlsr.getAdl().getNumOfActiveNeighbor()
-                  , pnlsr.getAdl() );
-    pnlsr.getSm().setAdjLsaSeq(pnlsr.getSm().getAdjLsaSeq()+1);
-    string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                     + pnlsr.getConfParameter().getRouterPrefix();
-    pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-    return pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
-  }
-
-  bool
-  Lsdb::removeAdjLsa(Nlsr& pnlsr, string& key)
-  {
-    std::list<AdjLsa >::iterator it = std::find_if( m_adjLsdb.begin(),
-                                      m_adjLsdb.end(),
-                                      bind(adjLsaCompareByKey, _1, key));
-    if ( it != m_adjLsdb.end() )
-    {
-      (*it).removeNptEntries(pnlsr);
-      m_adjLsdb.erase(it);
-      return true;
-    }
-    return false;
-  }
-
-  bool
-  Lsdb::doesAdjLsaExist(string key)
-  {
-    std::list< AdjLsa >::iterator it = std::find_if( m_adjLsdb.begin(),
-                                       m_adjLsdb.end(),
-                                       bind(adjLsaCompareByKey, _1, key));
-    if( it == m_adjLsdb.end())
-    {
-      return false;
-    }
-    return true;
-  }
-
-  std::list<AdjLsa>&
-  Lsdb::getAdjLsdb()
-  {
-    return m_adjLsdb;
-  }
-
-  void
-  Lsdb::setLsaRefreshTime(int lrt)
-  {
-    m_lsaRefreshTime=lrt;
-  }
-
-  void
-  Lsdb::setThisRouterPrefix(string trp)
-  {
-    m_thisRouterPrefix=trp;
-  }
-
-  void
-  Lsdb::exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-  {
-    cout<<"Lsdb::exprireOrRefreshNameLsa Called "<<endl;
-    cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
-    std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(lsaKey);
-    if( chkNameLsa.second )
-    {
-      cout<<" LSA Exists with seq no: "<<chkNameLsa.first.getLsSeqNo()<<endl;
-      if ( chkNameLsa.first.getLsSeqNo() == seqNo )
-      {
-        if(chkNameLsa.first.getOrigRouter() == m_thisRouterPrefix )
-        {
-          src::logger lg;
-          BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Deleting name lsa";
-          chkNameLsa.first.writeLog();
-          cout<<"Own Name LSA, so refreshing name LSA"<<endl;
-          chkNameLsa.first.setLsSeqNo(chkNameLsa.first.getLsSeqNo()+1);
-          pnlsr.getSm().setNameLsaSeq(chkNameLsa.first.getLsSeqNo());
-          BOOST_LOG(lg)<<" "<<THIS_FILE<<" "<<__LINE__<<": "<<"Adding name lsa";
-          chkNameLsa.first.writeLog();
-          // publish routing update
-          string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                           + pnlsr.getConfParameter().getRouterPrefix();
-          pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-        }
-        else
-        {
-          cout<<"Other's Name LSA, so removing form LSDB"<<endl;
-          removeNameLsa(pnlsr, lsaKey);
-        }
-      }
-    }
-  }
-
-  void
-  Lsdb::exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-  {
-    cout<<"Lsdb::exprireOrRefreshAdjLsa Called "<<endl;
-    cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
-    std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(lsaKey);
-    if( chkAdjLsa.second )
-    {
-      cout<<" LSA Exists with seq no: "<<chkAdjLsa.first.getLsSeqNo()<<endl;
-      if ( chkAdjLsa.first.getLsSeqNo() == seqNo )
-      {
-        if(chkAdjLsa.first.getOrigRouter() == m_thisRouterPrefix )
-        {
-          cout<<"Own Adj LSA, so refreshing Adj LSA"<<endl;
-          chkAdjLsa.first.setLsSeqNo(chkAdjLsa.first.getLsSeqNo()+1);
-          pnlsr.getSm().setAdjLsaSeq(chkAdjLsa.first.getLsSeqNo());
-          // publish routing update
-          string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                           + pnlsr.getConfParameter().getRouterPrefix();
-          pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-        }
-        else
-        {
-          cout<<"Other's Adj LSA, so removing form LSDB"<<endl;
-          removeAdjLsa(pnlsr, lsaKey);
-        }
-        // schedule Routing table calculaiton
-        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-      }
-    }
-  }
-
-  void
-  Lsdb::exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-  {
-    cout<<"Lsdb::exprireOrRefreshCorLsa Called "<<endl;
-    cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
-    std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(lsaKey);
-    if( chkCorLsa.second )
-    {
-      cout<<" LSA Exists with seq no: "<<chkCorLsa.first.getLsSeqNo()<<endl;
-      if ( chkCorLsa.first.getLsSeqNo() == seqNo )
-      {
-        if(chkCorLsa.first.getOrigRouter() == m_thisRouterPrefix )
-        {
-          cout<<"Own Cor LSA, so refreshing Cor LSA"<<endl;
-          chkCorLsa.first.setLsSeqNo(chkCorLsa.first.getLsSeqNo()+1);
-          pnlsr.getSm().setCorLsaSeq(chkCorLsa.first.getLsSeqNo());
-          // publish routing update
-          string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                           + pnlsr.getConfParameter().getRouterPrefix();
-          pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-        }
-        else
-        {
-          cout<<"Other's Cor LSA, so removing form LSDB"<<endl;
-          removeCorLsa(pnlsr, lsaKey);
-        }
-        if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-        {
-          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-        }
-      }
-    }
-  }
-
-
-  void
-  Lsdb::printAdjLsdb()
-  {
-    cout<<"---------------Adj LSDB-------------------"<<endl;
-    for( std::list<AdjLsa>::iterator it=m_adjLsdb.begin();
-         it!= m_adjLsdb.end() ; it++)
-    {
-      cout<< (*it) <<endl;
-    }
-  }
-
-//-----utility function -----
-  bool
-  Lsdb::doesLsaExist(string key, int lsType)
-  {
-    if ( lsType == 1)
-    {
-      return doesNameLsaExist(key);
-    }
-    else if ( lsType == 2)
-    {
-      return doesAdjLsaExist(key);
-    }
-    else if ( lsType == 3)
-    {
-      return doesCorLsaExist(key);
-    }
-    return false;
-  }
-
-}//namespace nlsr
-
diff --git a/src/nlsr_lsdb.hpp b/src/nlsr_lsdb.hpp
deleted file mode 100644
index 444001a..0000000
--- a/src/nlsr_lsdb.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef NLSR_LSDB_HPP
-#define NLSR_LSDB_HPP
-
-#include <utility>
-#include "nlsr_lsa.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class Nlsr;
-
-  class Lsdb
-  {
-  public:
-    Lsdb()
-      : m_lsaRefreshTime(0)
-    {
-    }
-
-
-    bool doesLsaExist(string key, int lsType);
-    // function related to Name LSDB
-    bool buildAndInstallOwnNameLsa(Nlsr& pnlsr);
-    std::pair<NameLsa&, bool>  getNameLsa(string key);
-    bool installNameLsa(Nlsr& pnlsr, NameLsa &nlsa);
-    bool removeNameLsa(Nlsr& pnlsr, string& key);
-    bool isNameLsaNew(string key, uint64_t seqNo);
-    void printNameLsdb(); //debugging
-
-    //function related to Cor LSDB
-    bool buildAndInstallOwnCorLsa(Nlsr& pnlsr);
-    std::pair<CorLsa&, bool> getCorLsa(string key);
-    bool installCorLsa(Nlsr& pnlsr, CorLsa &clsa);
-    bool removeCorLsa(Nlsr& pnlsr, string& key);
-    bool isCorLsaNew(string key, uint64_t seqNo);
-    void printCorLsdb(); //debugging
-
-    //function related to Adj LSDB
-    void scheduledAdjLsaBuild(Nlsr& pnlsr);
-    bool buildAndInstallOwnAdjLsa(Nlsr& pnlsr);
-    bool removeAdjLsa(Nlsr& pnlsr, string& key);
-    bool isAdjLsaNew(string key, uint64_t seqNo);
-    bool installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa);
-    std::pair<AdjLsa& , bool> getAdjLsa(string key);
-    std::list<AdjLsa>& getAdjLsdb();
-    void printAdjLsdb();
-
-    //void scheduleRefreshLsdb(Nlsr& pnlsr, int interval);
-    void setLsaRefreshTime(int lrt);
-    void setThisRouterPrefix(string trp);
-
-  private:
-    bool addNameLsa(NameLsa &nlsa);
-    bool doesNameLsaExist(string key);
-
-
-    bool addCorLsa(CorLsa& clsa);
-    bool doesCorLsaExist(string key);
-
-    bool addAdjLsa(AdjLsa &alsa);
-    bool doesAdjLsaExist(string key);
-
-    ndn::EventId
-    scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
-    void exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
-    ndn::EventId
-    scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
-    void exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
-    ndn::EventId
-    scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
-    void exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
-
-
-  private:
-    void cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid);
-
-    std::list<NameLsa> m_nameLsdb;
-    std::list<AdjLsa> m_adjLsdb;
-    std::list<CorLsa> m_corLsdb;
-
-    int m_lsaRefreshTime;
-    string m_thisRouterPrefix;
-
-  };
-
-}//namespace nlsr
-
-#endif
diff --git a/src/nlsr_npl.cpp b/src/nlsr_npl.cpp
deleted file mode 100644
index e6cd819..0000000
--- a/src/nlsr_npl.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#include<iostream>
-#include<algorithm>
-
-#include "nlsr_npl.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_npl.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  Npl::Npl()
-  {
-  }
-
-  Npl::~Npl()
-  {
-  }
-
-  static bool
-  nameCompare(string& s1, string& s2)
-  {
-    return s1==s2;
-  }
-
-  int
-  Npl::insert(string& name)
-  {
-    std::list<string >::iterator it = std::find_if( m_nameList.begin(),
-                                      m_nameList.end(),
-                                      bind(&nameCompare, _1 , name));
-    if( it != m_nameList.end() )
-    {
-      return -1;
-    }
-    m_nameList.push_back(name);
-    return 0;
-  }
-
-  int
-  Npl::remove(string& name)
-  {
-    std::list<string >::iterator it = std::find_if( m_nameList.begin(),
-                                      m_nameList.end(),
-                                      bind(&nameCompare, _1 , name));
-    if( it != m_nameList.end() )
-    {
-      m_nameList.erase(it);
-    }
-    return -1;
-  }
-
-  void
-  Npl::sort()
-  {
-    m_nameList.sort();
-  }
-
-  void
-  Npl::print()
-  {
-    int i=1;
-    for( std::list<string>::iterator it=m_nameList.begin(); it != m_nameList.end();
-         it++)
-    {
-      cout<<"Name "<<i<<" : "<<(*it)<<endl;
-      i++;
-    }
-  }
-
-}//namespace nlsr
diff --git a/src/nlsr_npl.hpp b/src/nlsr_npl.hpp
deleted file mode 100644
index b69b352..0000000
--- a/src/nlsr_npl.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef NPL_HPP
-#define NPL_HPP
-
-#include<list>
-#include<string>
-#include <ndn-cpp-dev/face.hpp>
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class Npl
-  {
-
-  public:
-    Npl();
-    ~Npl();
-
-    int insert(string& name);
-    int remove(string& name);
-    void sort();
-    int getSize()
-    {
-      return m_nameList.size();
-    }
-    std::list<string>& getNameList()
-    {
-      return m_nameList;
-    }
-    void print();
-
-  private:
-    std::list<string> m_nameList;
-
-  };
-
-}//namespace nlsr
-
-#endif
diff --git a/src/nlsr_sm.cpp b/src/nlsr_sm.cpp
deleted file mode 100644
index e44c433..0000000
--- a/src/nlsr_sm.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <pwd.h>
-#include <cstdlib>
-#include <unistd.h>
-
-#include "nlsr_sm.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_sm.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  void
-  SequencingManager::splittSequenceNo(uint64_t seqNo)
-  {
-    m_combinedSeqNo=seqNo;
-    m_adjLsaSeq = (m_combinedSeqNo & 0xFFFFF);
-    m_corLsaSeq = ((m_combinedSeqNo >> 20) & 0xFFFFF);
-    m_nameLsaSeq = ((m_combinedSeqNo >> 40) & 0xFFFFF);
-  }
-
-  void
-  SequencingManager::combineSequenceNo()
-  {
-    m_combinedSeqNo=0;
-    m_combinedSeqNo = m_combinedSeqNo | m_adjLsaSeq;
-    m_combinedSeqNo = m_combinedSeqNo | (m_corLsaSeq<<20);
-    m_combinedSeqNo = m_combinedSeqNo | (m_nameLsaSeq<<40);
-  }
-
-  void
-  SequencingManager::writeSeqNoToFile()
-  {
-    std::ofstream outputFile(m_seqFileNameWithPath.c_str(),ios::binary);
-    outputFile<<m_combinedSeqNo;
-    outputFile.close();
-  }
-
-  void
-  SequencingManager::initiateSeqNoFromFile()
-  {
-    cout<<"Seq File Name: "<< m_seqFileNameWithPath<<endl;
-    std::ifstream inputFile(m_seqFileNameWithPath.c_str(),ios::binary);
-    if ( inputFile.good() )
-    {
-      inputFile>>m_combinedSeqNo;
-      splittSequenceNo(m_combinedSeqNo);
-      m_adjLsaSeq+=10;
-      m_corLsaSeq+=10;
-      m_nameLsaSeq+=10;
-      combineSequenceNo();
-      inputFile.close();
-    }
-    else
-    {
-      splittSequenceNo(0);
-    }
-  }
-
-  void
-  SequencingManager::setSeqFileName(string filePath)
-  {
-    m_seqFileNameWithPath=filePath;
-    if( m_seqFileNameWithPath.empty() )
-    {
-      m_seqFileNameWithPath=getUserHomeDirectory();
-    }
-    m_seqFileNameWithPath=m_seqFileNameWithPath+"/nlsrSeqNo.txt";
-  }
-
-  string
-  SequencingManager::getUserHomeDirectory()
-  {
-    string homeDirPath(getpwuid(getuid())->pw_dir);
-    if( homeDirPath.empty() )
-    {
-      homeDirPath = getenv("HOME");
-    }
-    return homeDirPath;
-  }
-
-  ostream&
-  operator <<(ostream& os, const SequencingManager& sm)
-  {
-    std::cout<<"----SequencingManager----"<<std::endl;
-    std::cout<<"Adj LSA seq no: "<<sm.getAdjLsaSeq()<<endl;
-    std::cout<<"Cor LSA Seq no: "<<sm.getCorLsaSeq()<<endl;
-    std::cout<<"Name LSA Seq no: "<<sm.getNameLsaSeq()<<endl;
-    std::cout<<"Combined LSDB Seq no: "<<sm.getCombinedSeqNo()<<endl;
-    return os;
-  }
-
-}//namespace nlsr
-
-
diff --git a/src/nlsr_sm.hpp b/src/nlsr_sm.hpp
deleted file mode 100644
index 4861009..0000000
--- a/src/nlsr_sm.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef NLSR_SM_HPP
-#define NLSR_SM_HPP
-
-#include<list>
-#include<string>
-#include <ndn-cpp-dev/face.hpp>
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class SequencingManager
-  {
-  public:
-    SequencingManager()
-      : m_nameLsaSeq(0)
-      , m_adjLsaSeq(0)
-      , m_corLsaSeq(0)
-      , m_combinedSeqNo(0)
-      , m_seqFileNameWithPath()
-    {
-    }
-
-    SequencingManager(uint64_t seqNo)
-    {
-      splittSequenceNo(seqNo);
-    }
-
-    SequencingManager(uint64_t nlsn, uint64_t alsn, uint64_t clsn)
-    {
-      m_nameLsaSeq=nlsn;
-      m_adjLsaSeq=alsn;
-      m_corLsaSeq=clsn;
-      combineSequenceNo();
-    }
-
-    uint64_t getNameLsaSeq() const
-    {
-      return m_nameLsaSeq;
-    }
-
-    void setNameLsaSeq(uint64_t nlsn)
-    {
-      m_nameLsaSeq=nlsn;
-      combineSequenceNo();
-    }
-
-    uint64_t getAdjLsaSeq() const
-    {
-      return m_adjLsaSeq;
-    }
-
-    void setAdjLsaSeq(uint64_t alsn)
-    {
-      m_adjLsaSeq=alsn;
-      combineSequenceNo();
-    }
-
-    uint64_t getCorLsaSeq() const
-    {
-      return m_corLsaSeq;
-    }
-
-    void setCorLsaSeq(uint64_t clsn)
-    {
-      m_corLsaSeq=clsn;
-      combineSequenceNo();
-    }
-
-    uint64_t getCombinedSeqNo() const
-    {
-      return m_combinedSeqNo;
-    }
-
-    void writeSeqNoToFile();
-    void initiateSeqNoFromFile();
-    void setSeqFileName(string filePath);
-    string getUserHomeDirectory();
-
-  private:
-    void splittSequenceNo(uint64_t seqNo);
-    void combineSequenceNo();
-
-
-  private:
-    uint64_t m_nameLsaSeq;
-    uint64_t m_adjLsaSeq;
-    uint64_t m_corLsaSeq;
-    uint64_t m_combinedSeqNo;
-    string m_seqFileNameWithPath;
-  };
-
-
-  ostream& operator <<(ostream& os, const SequencingManager& sm);
-}//namespace nlsr
-#endif
diff --git a/src/npl.cpp b/src/npl.cpp
new file mode 100644
index 0000000..557640f
--- /dev/null
+++ b/src/npl.cpp
@@ -0,0 +1,70 @@
+#include <iostream>
+#include <algorithm>
+
+#include "npl.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+Npl::Npl()
+{
+}
+
+Npl::~Npl()
+{
+}
+
+static bool
+nameCompare(string& s1, string& s2)
+{
+  return s1 == s2;
+}
+
+int
+Npl::insert(string& name)
+{
+  std::list<string>::iterator it = std::find_if(m_nameList.begin(),
+                                                m_nameList.end(),
+                                                bind(&nameCompare, _1 , name));
+  if (it != m_nameList.end())
+  {
+    return -1;
+  }
+  m_nameList.push_back(name);
+  return 0;
+}
+
+int
+Npl::remove(string& name)
+{
+  std::list<string>::iterator it = std::find_if(m_nameList.begin(),
+                                                m_nameList.end(),
+                                                bind(&nameCompare, _1 , name));
+  if (it != m_nameList.end())
+  {
+    m_nameList.erase(it);
+  }
+  return -1;
+}
+
+void
+Npl::sort()
+{
+  m_nameList.sort();
+}
+
+void
+Npl::print()
+{
+  int i = 1;
+  for (std::list<string>::iterator it = m_nameList.begin();
+       it != m_nameList.end();
+       it++)
+  {
+    cout << "Name " << i << " : " << (*it) << endl;
+    i++;
+  }
+}
+
+}//namespace nlsr
diff --git a/src/npl.hpp b/src/npl.hpp
new file mode 100644
index 0000000..91de260
--- /dev/null
+++ b/src/npl.hpp
@@ -0,0 +1,48 @@
+#ifndef NPL_HPP
+#define NPL_HPP
+
+#include <list>
+#include <string>
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr {
+class Npl
+{
+
+public:
+  Npl();
+
+  ~Npl();
+
+  int
+  insert(std::string& name);
+
+  int
+  remove(std::string& name);
+
+  void
+  sort();
+
+  int
+  getSize()
+  {
+    return m_nameList.size();
+  }
+
+  std::list<std::string>&
+  getNameList()
+  {
+    return m_nameList;
+  }
+
+  void
+  print();
+
+private:
+  std::list<std::string> m_nameList;
+
+};
+
+}//namespace nlsr
+
+#endif //NPL_HPP
diff --git a/src/route/fib-entry.cpp b/src/route/fib-entry.cpp
new file mode 100644
index 0000000..ddb5dbd
--- /dev/null
+++ b/src/route/fib-entry.cpp
@@ -0,0 +1,47 @@
+#include <list>
+#include "fib-entry.hpp"
+#include "nexthop.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+bool
+FibEntry::isEqualNextHops(Nhl& nhlOther)
+{
+  if (m_nhl.getSize() != nhlOther.getSize())
+  {
+    return false;
+  }
+  else
+  {
+    int nhCount = 0;
+    std::list<NextHop>::iterator it1, it2;
+    for (it1 = m_nhl.getNextHopList().begin(),
+         it2 = nhlOther.getNextHopList().begin() ;
+         it1 != m_nhl.getNextHopList().end() ; it1++, it2++)
+    {
+      if (it1->getConnectingFace() == it2->getConnectingFace())
+      {
+        it1->setRouteCost(it2->getRouteCost());
+        nhCount++;
+      }
+      else
+      {
+        break;
+      }
+    }
+    return nhCount == m_nhl.getSize();
+  }
+}
+
+ostream&
+operator<<(ostream& os, FibEntry fe)
+{
+  os << "Name Prefix: " << fe.getName() << endl;
+  os << "Time to Refresh: " << fe.getTimeToRefresh() << endl;
+  os << fe.getNhl() << endl;
+  return os;
+}
+
+}//namespace nlsr
diff --git a/src/route/fib-entry.hpp b/src/route/fib-entry.hpp
new file mode 100644
index 0000000..66e2e8b
--- /dev/null
+++ b/src/route/fib-entry.hpp
@@ -0,0 +1,98 @@
+#ifndef NLSR_FE_HPP
+#define NLSR_FE_HPP
+
+#include <list>
+#include <iostream>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nexthop.hpp"
+#include "nhl.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+class FibEntry
+{
+public:
+  FibEntry()
+    : m_name()
+    , m_timeToRefresh(0)
+    , m_seqNo(0)
+    , m_nhl()
+  {
+  }
+
+  FibEntry(string n)
+    : m_timeToRefresh(0)
+    , m_seqNo(0)
+    , m_nhl()
+  {
+    m_name = n;
+  }
+
+  std::string
+  getName() const
+  {
+    return m_name;
+  }
+
+  Nhl&
+  getNhl()
+  {
+    return m_nhl;
+  }
+
+  int
+  getTimeToRefresh() const
+  {
+    return m_timeToRefresh;
+  }
+
+  void
+  setTimeToRefresh(int ttr)
+  {
+    m_timeToRefresh = ttr;
+  }
+
+  void
+  setExpiringEventId(ndn::EventId feid)
+  {
+    m_expiringEventId = feid;
+  }
+
+  ndn::EventId
+  getExpiringEventId() const
+  {
+    return m_expiringEventId;
+  }
+
+  void
+  setSeqNo(int fsn)
+  {
+    m_seqNo = fsn;
+  }
+
+  int
+  getSeqNo()
+  {
+    return m_seqNo;
+  }
+
+  bool
+  isEqualNextHops(Nhl& nhlOther);
+
+private:
+  std::string m_name;
+  int m_timeToRefresh;
+  ndn::EventId m_expiringEventId;
+  int m_seqNo;
+  Nhl m_nhl;
+};
+
+std::ostream&
+operator<<(std::ostream& os, FibEntry fe);
+
+} //namespace nlsr
+
+#endif //NLSR_FE_HPP
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
new file mode 100644
index 0000000..5304d0e
--- /dev/null
+++ b/src/route/fib.cpp
@@ -0,0 +1,186 @@
+#include <list>
+#include "fib-entry.hpp"
+#include "fib.hpp"
+#include "nhl.hpp"
+#include "nlsr.hpp"
+
+
+namespace nlsr {
+
+using namespace std;
+using namespace ndn;
+
+static bool
+fibEntryNameCompare(FibEntry& fe, string name)
+{
+  return fe.getName() == name ;
+}
+
+void
+Fib::cancelScheduledExpiringEvent(Nlsr& pnlsr, EventId eid)
+{
+  pnlsr.getScheduler().cancelEvent(eid);
+}
+
+
+ndn::EventId
+Fib::scheduleEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                             int refreshTime)
+{
+  return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
+                                            ndn::bind(&Fib::refreshEntry, this, name, feSeqNum));
+}
+
+void
+Fib::refreshEntry(string name, int feSeqNum)
+{
+}
+
+void
+Fib::remove(Nlsr& pnlsr, string name)
+{
+  std::list<FibEntry>::iterator it = std::find_if(m_table.begin(),
+                                                  m_table.end(), bind(&fibEntryNameCompare, _1, name));
+  if (it != m_table.end())
+  {
+    for (std::list<NextHop>::iterator nhit =
+           (*it).getNhl().getNextHopList().begin();
+         nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+    {
+      //remove entry from NDN-FIB
+    }
+    cancelScheduledExpiringEvent(pnlsr, (*it).getExpiringEventId());
+    m_table.erase(it);
+  }
+}
+
+
+void
+Fib::update(Nlsr& pnlsr, string name, Nhl& nextHopList)
+{
+  std::cout << "Fib::updateFib Called" << std::endl;
+  int startFace = 0;
+  int endFace = getNumberOfFacesForName(nextHopList,
+                                        pnlsr.getConfParameter().getMaxFacesPerPrefix());
+  std::list<FibEntry>::iterator it = std::find_if(m_table.begin(),
+                                                  m_table.end(),
+                                                  bind(&fibEntryNameCompare, _1, name));
+  if (it == m_table.end())
+  {
+    if (nextHopList.getSize() > 0)
+    {
+      nextHopList.sort();
+      FibEntry newEntry(name);
+      std::list<NextHop> nhl = nextHopList.getNextHopList();
+      std::list<NextHop>::iterator nhit = nhl.begin();
+      for (int i = startFace; i < endFace && nhit != nhl.end(); ++nhit, i++)
+      {
+        newEntry.getNhl().addNextHop((*nhit));
+        //Add entry to NDN-FIB
+      }
+      newEntry.getNhl().sort();
+      newEntry.setTimeToRefresh(m_refreshTime);
+      newEntry.setSeqNo(1);
+      newEntry.setExpiringEventId(scheduleEntryRefreshing(pnlsr,
+                                                          name , 1, m_refreshTime));
+      m_table.push_back(newEntry);
+    }
+  }
+  else
+  {
+    std::cout << "Old FIB Entry" << std::endl;
+    if (nextHopList.getSize() > 0)
+    {
+      nextHopList.sort();
+      if (!it->isEqualNextHops(nextHopList))
+      {
+        std::list<NextHop> nhl = nextHopList.getNextHopList();
+        std::list<NextHop>::iterator nhit = nhl.begin();
+        // Add first Entry to NDN-FIB
+        removeHop(pnlsr, it->getNhl(), nhit->getConnectingFace());
+        it->getNhl().reset();
+        it->getNhl().addNextHop((*nhit));
+        ++startFace;
+        ++nhit;
+        for (int i = startFace; i < endFace && nhit != nhl.end(); ++nhit, i++)
+        {
+          it->getNhl().addNextHop((*nhit));
+          //Add Entry to NDN_FIB
+        }
+      }
+      it->setTimeToRefresh(m_refreshTime);
+      cancelScheduledExpiringEvent(pnlsr, it->getExpiringEventId());
+      it->setSeqNo(it->getSeqNo() + 1);
+      (*it).setExpiringEventId(scheduleEntryRefreshing(pnlsr,
+                                                       it->getName() ,
+                                                       it->getSeqNo(), m_refreshTime));
+    }
+    else
+    {
+      remove(pnlsr, name);
+    }
+  }
+}
+
+
+
+void
+Fib::clean(Nlsr& pnlsr)
+{
+  for (std::list<FibEntry>::iterator it = m_table.begin(); it != m_table.end();
+       ++it)
+  {
+    for (std::list<NextHop>::iterator nhit =
+           (*it).getNhl().getNextHopList().begin();
+         nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+    {
+      cancelScheduledExpiringEvent(pnlsr, (*it).getExpiringEventId());
+      //Remove entry from NDN-FIB
+    }
+  }
+  if (m_table.size() > 0)
+  {
+    m_table.clear();
+  }
+}
+
+int
+Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+{
+  int endFace = 0;
+  if ((maxFacesPerPrefix == 0) || (nextHopList.getSize() <= maxFacesPerPrefix))
+  {
+    return nextHopList.getSize();
+  }
+  else
+  {
+    return maxFacesPerPrefix;
+  }
+  return endFace;
+}
+
+void
+Fib::removeHop(Nlsr& pnlsr, Nhl& nl, int doNotRemoveHopFaceId)
+{
+  for (std::list<NextHop>::iterator it = nl.getNextHopList().begin();
+       it != nl.getNextHopList().end();   ++it)
+  {
+    if (it->getConnectingFace() != doNotRemoveHopFaceId)
+    {
+      //Remove FIB Entry from NDN-FIB
+    }
+  }
+}
+
+void
+Fib::print()
+{
+  cout << "-------------------FIB-----------------------------" << endl;
+  for (std::list<FibEntry>::iterator it = m_table.begin(); it != m_table.end();
+       ++it)
+  {
+    cout << (*it);
+  }
+}
+
+} //namespace nlsr
diff --git a/src/route/fib.hpp b/src/route/fib.hpp
new file mode 100644
index 0000000..f042362
--- /dev/null
+++ b/src/route/fib.hpp
@@ -0,0 +1,63 @@
+#ifndef NLSR_FIB_HPP
+#define NLSR_FIB_HPP
+
+#include <list>
+#include "fib-entry.hpp"
+
+namespace nlsr {
+
+class Nlsr;
+
+using namespace std;
+using namespace ndn;
+
+class Fib
+{
+public:
+  Fib()
+    : m_table()
+    , m_refreshTime(0)
+  {
+  }
+
+  void
+  remove(Nlsr& pnlsr, string name);
+
+  void
+  update(Nlsr& pnlsr, string name, Nhl& nextHopList);
+
+  void
+  clean(Nlsr& pnlsr);
+
+  void
+  setEntryRefreshTime(int fert)
+  {
+    m_refreshTime = fert;
+  }
+
+  void
+  print();
+
+private:
+  void
+  removeHop(Nlsr& pnlsr, Nhl& nl, int doNotRemoveHopFaceId);
+
+  int
+  getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
+
+  ndn::EventId
+  scheduleEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                          int refreshTime);
+  void
+  cancelScheduledExpiringEvent(Nlsr& pnlsr, EventId eid);
+
+  void
+  refreshEntry(string name, int feSeqNum);
+
+private:
+  std::list<FibEntry> m_table;
+  int m_refreshTime;
+};
+
+}//namespace nlsr
+#endif //NLSR_FIB_HPP
diff --git a/src/route/map.cpp b/src/route/map.cpp
new file mode 100644
index 0000000..e7ab979
--- /dev/null
+++ b/src/route/map.cpp
@@ -0,0 +1,125 @@
+#include <iostream>
+#include <list>
+
+#include "nlsr.hpp"
+#include "adjacent.hpp"
+#include "lsa.hpp"
+#include "lsdb.hpp"
+#include "map.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+ostream&
+operator<< (ostream& os, MapEntry& mpe)
+{
+  os << "MapEntry: ( Router: " << mpe.getRouter() << " Mapping No: ";
+  os << mpe.getMappingNumber() << " )" << endl;
+  return os;
+}
+
+static bool
+mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
+{
+  return mpe1.getRouter() == rtrName;
+}
+
+static bool
+mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
+{
+  return mpe1.getMappingNumber() == mappingNo;
+}
+
+void
+Map::addElement(string& rtrName)
+{
+  MapEntry me(rtrName, m_mappingIndex);
+  if (addElement(me))
+  {
+    m_mappingIndex++;
+  }
+}
+
+bool
+Map::addElement(MapEntry& mpe)
+{
+  //cout << mpe;
+  std::list<MapEntry>::iterator it = std::find_if(m_table.begin(),
+                                                  m_table.end(),
+                                                  bind(&mapEntryCompareByRouter, _1, mpe.getRouter()));
+  if (it == m_table.end())
+  {
+    m_table.push_back(mpe);
+    return true;
+  }
+  return false;
+}
+
+string
+Map::getRouterNameByMappingNo(int mn)
+{
+  std::list<MapEntry>::iterator it = std::find_if(m_table.begin(),
+                                                  m_table.end(),
+                                                  bind(&mapEntryCompareByMappingNo,
+                                                       _1, mn));
+  if (it != m_table.end())
+  {
+    return (*it).getRouter();
+  }
+  return "";
+}
+
+int
+Map::getMappingNoByRouterName(string& rName)
+{
+  std::list<MapEntry>::iterator it = std::find_if(m_table.begin(),
+                                                  m_table.end(),
+                                                  bind(&mapEntryCompareByRouter,
+                                                       _1, rName));
+  if (it != m_table.end())
+  {
+    return (*it).getMappingNumber();
+  }
+  return -1;
+}
+
+void
+Map::createFromAdjLsdb(Nlsr& pnlsr)
+{
+  std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
+  for (std::list<AdjLsa>::iterator it = adjLsdb.begin();
+       it != adjLsdb.end() ; it++)
+  {
+    string linkStartRouter = (*it).getOrigRouter();
+    addElement(linkStartRouter);
+    std::list<Adjacent> adl = (*it).getAdl().getAdjList();
+    for (std::list<Adjacent>::iterator itAdl = adl.begin();
+         itAdl != adl.end() ; itAdl++)
+    {
+      string linkEndRouter = (*itAdl).getName();
+      addElement(linkEndRouter);
+    }
+  }
+}
+
+void
+Map::reset()
+{
+  m_table.clear();
+  m_mappingIndex = 0;
+}
+
+ostream&
+operator<<(ostream& os, Map& map)
+{
+  os << "---------------Map----------------------" << endl;
+  std::list<MapEntry> ml = map.getMapList();
+  for (std::list<MapEntry>::iterator it = ml.begin(); it != ml.end() ; it++)
+  {
+    os << (*it);
+  }
+  return os;
+}
+
+} //namespace nlsr
diff --git a/src/route/map.hpp b/src/route/map.hpp
new file mode 100644
index 0000000..9c9e6e8
--- /dev/null
+++ b/src/route/map.hpp
@@ -0,0 +1,101 @@
+#ifndef NLSR_MAP_HPP
+#define NLSR_MAP_HPP
+
+#include <iostream>
+#include <list>
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr {
+
+class Nlsr;
+
+class MapEntry
+{
+public:
+  MapEntry()
+    : m_router()
+    , m_mappingNumber(-1)
+  {
+  }
+
+  ~MapEntry()
+  {
+  }
+
+  MapEntry(std::string rtr, int mn)
+  {
+    m_router = rtr;
+    m_mappingNumber = mn;
+  }
+
+  std::string
+  getRouter() const
+  {
+    return m_router;
+  }
+
+  int
+  getMappingNumber() const
+  {
+    return m_mappingNumber;
+  }
+
+private:
+  std::string m_router;
+  int m_mappingNumber;
+};
+
+std::ostream&
+operator<<(std::ostream& os, MapEntry& mpe);
+
+class Map
+{
+public:
+  Map()
+    : m_mappingIndex(0)
+  {
+  }
+
+
+  void
+  addElement(std::string& rtrName);
+
+  void
+  createFromAdjLsdb(Nlsr& pnlsr);
+
+  std::string
+  getRouterNameByMappingNo(int mn);
+
+  int
+  getMappingNoByRouterName(std::string& rName);
+
+  void
+  reset();
+
+  std::list<MapEntry>&
+  getMapList()
+  {
+    return m_table;
+  }
+
+  int
+  getMapSize() const
+  {
+    return m_table.size();
+  }
+
+
+private:
+  bool
+  addElement(MapEntry& mpe);
+
+  int m_mappingIndex;
+  std::list<MapEntry> m_table;
+};
+
+std::ostream&
+operator<<(std::ostream& os, Map& map);
+
+} // namespace nlsr
+#endif //NLSR_MAP_HPP
diff --git a/src/route/nexthop.cpp b/src/route/nexthop.cpp
new file mode 100644
index 0000000..0a375b0
--- /dev/null
+++ b/src/route/nexthop.cpp
@@ -0,0 +1,13 @@
+#include "nexthop.hpp"
+
+namespace nlsr {
+
+std::ostream&
+operator<<(std::ostream& os, NextHop& nh)
+{
+  os << "Face: " << nh.getConnectingFace() << "  Route Cost: " <<
+     nh.getRouteCost();
+  return os;
+}
+
+}//namespace nlsr
diff --git a/src/route/nexthop.hpp b/src/route/nexthop.hpp
new file mode 100644
index 0000000..7153e0f
--- /dev/null
+++ b/src/route/nexthop.hpp
@@ -0,0 +1,57 @@
+#ifndef NLSR_NEXTHOP_HPP
+#define NLSR_NEXTHOP_HPP
+
+#include <iostream>
+
+namespace nlsr {
+class NextHop
+{
+public:
+  NextHop()
+    : m_connectingFace(0)
+    , m_routeCost(0)
+  {
+  }
+
+  NextHop(int cf, double rc)
+  {
+    m_connectingFace = cf;
+    m_routeCost = rc;
+  }
+
+  int
+  getConnectingFace() const
+  {
+    return m_connectingFace;
+  }
+
+  void
+  setConnectingFace(int cf)
+  {
+    m_connectingFace = cf;
+  }
+
+  double
+  getRouteCost() const
+  {
+    return m_routeCost;
+  }
+
+  void
+  setRouteCost(double rc)
+  {
+    m_routeCost = rc;
+  }
+
+private:
+  int m_connectingFace;
+  double m_routeCost;
+};
+
+
+std::ostream&
+operator<<(std::ostream& os, NextHop& nh);
+
+}//namespace nlsr
+
+#endif //NLSR_NEXTHOP_HPP
diff --git a/src/route/nhl.cpp b/src/route/nhl.cpp
new file mode 100644
index 0000000..50d6303
--- /dev/null
+++ b/src/route/nhl.cpp
@@ -0,0 +1,88 @@
+#include <iostream>
+#include "nhl.hpp"
+#include "nexthop.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+static bool
+nexthopCompare(NextHop& nh1, NextHop& nh2)
+{
+  return nh1.getConnectingFace() == nh2.getConnectingFace();
+}
+
+static bool
+nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+{
+  return (nh1.getConnectingFace() == nh2.getConnectingFace() &&
+          nh1.getRouteCost() == nh2.getRouteCost()) ;
+}
+
+static bool
+nextHopSortingComparator(const NextHop& nh1, const NextHop& nh2)
+{
+  return nh1.getRouteCost() < nh2.getRouteCost();
+}
+
+/**
+Add next hop to the Next Hop list
+If next hop is new it is added
+If next hop already exists in next
+hop list then updates the route
+cost with new next hop's route cost
+*/
+
+void
+Nhl::addNextHop(NextHop& nh)
+{
+  std::list<NextHop>::iterator it = std::find_if(m_nexthopList.begin(),
+                                                 m_nexthopList.end(),
+                                                 bind(&nexthopCompare, _1, nh));
+  if (it == m_nexthopList.end())
+  {
+    m_nexthopList.push_back(nh);
+  }
+  if ((*it).getRouteCost() > nh.getRouteCost())
+  {
+    (*it).setRouteCost(nh.getRouteCost());
+  }
+}
+
+/**
+Remove a next hop only if both next hop face and route cost are same
+
+*/
+
+void
+Nhl::removeNextHop(NextHop& nh)
+{
+  std::list<NextHop>::iterator it = std::find_if(m_nexthopList.begin(),
+                                                 m_nexthopList.end(),
+                                                 bind(&nexthopRemoveCompare, _1, nh));
+  if (it != m_nexthopList.end())
+  {
+    m_nexthopList.erase(it);
+  }
+}
+
+void
+Nhl::sort()
+{
+  m_nexthopList.sort(nextHopSortingComparator);
+}
+
+ostream&
+operator<<(ostream& os, Nhl& nhl)
+{
+  std::list<NextHop> nexthopList = nhl.getNextHopList();
+  int i = 1;
+  for (std::list<NextHop>::iterator it = nexthopList.begin();
+       it != nexthopList.end() ; it++, i++)
+  {
+    os << "Nexthop " << i << ": " << (*it) << endl;
+  }
+  return os;
+}
+
+}//namespace nlsr
diff --git a/src/route/nhl.hpp b/src/route/nhl.hpp
new file mode 100644
index 0000000..ef43373
--- /dev/null
+++ b/src/route/nhl.hpp
@@ -0,0 +1,63 @@
+#ifndef NLSR_NHL_HPP
+#define NLSR_NHL_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <list>
+#include <iostream>
+
+#include "nexthop.hpp"
+#include "adjacent.hpp"
+
+namespace nlsr {
+
+class Nhl
+{
+public:
+  Nhl()
+    : m_nexthopList()
+  {
+  }
+
+  ~Nhl()
+  {
+  }
+  void
+  addNextHop(NextHop& nh);
+
+  void
+  removeNextHop(NextHop& nh);
+
+  void
+  sort();
+
+  int
+  getSize()
+  {
+    return m_nexthopList.size();
+  }
+
+  void
+  reset()
+  {
+    if (m_nexthopList.size() > 0)
+    {
+      m_nexthopList.clear();
+    }
+  }
+
+  std::list<NextHop>&
+  getNextHopList()
+  {
+    return m_nexthopList;
+  }
+
+private:
+  std::list<NextHop> m_nexthopList;
+};
+
+std::ostream&
+operator<<(std::ostream& os, Nhl& nhl);
+
+}//namespace nlsr
+
+#endif //NLSR_NLH_HPP
diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
deleted file mode 100644
index cc724fe..0000000
--- a/src/route/nlsr_fe.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <list>
-#include "nlsr_fe.hpp"
-#include "nlsr_nexthop.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_fe.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  bool
-  FibEntry::isEqualNextHops(Nhl& nhlOther)
-  {
-    if ( m_nhl.getSize() != nhlOther.getSize() )
-    {
-      return false;
-    }
-    else
-    {
-      int nhCount=0;
-      std::list<NextHop>::iterator it1, it2;
-      for ( it1=m_nhl.getNextHopList().begin(),
-            it2 = nhlOther.getNextHopList().begin() ;
-            it1 != m_nhl.getNextHopList().end() ; it1++, it2++)
-      {
-        if (it1->getConnectingFace() == it2->getConnectingFace() )
-        {
-          it1->setRouteCost(it2->getRouteCost());
-          nhCount++;
-        }
-        else
-        {
-          break;
-        }
-      }
-      return nhCount == m_nhl.getSize();
-    }
-  }
-
-  ostream&
-  operator<<(ostream& os, FibEntry fe)
-  {
-    os<<"Name Prefix: "<<fe.getName()<<endl;
-    os<<"Time to Refresh: "<<fe.getTimeToRefresh()<<endl;
-    os<<fe.getNhl()<<endl;
-    return os;
-  }
-
-}//namespace nlsr
diff --git a/src/route/nlsr_fe.hpp b/src/route/nlsr_fe.hpp
deleted file mode 100644
index 3cac2fc..0000000
--- a/src/route/nlsr_fe.hpp
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef NLSR_FE_HPP
-#define NLSR_FE_HPP
-
-#include<list>
-#include <iostream>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include "nlsr_nexthop.hpp"
-#include "nlsr_nhl.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class FibEntry
-  {
-  public:
-    FibEntry()
-      : m_name()
-      , m_timeToRefresh(0)
-      , m_seqNo(0)
-      , m_nhl()
-    {
-    }
-
-    FibEntry(string n)
-      : m_timeToRefresh(0)
-      , m_seqNo(0)
-      , m_nhl()
-    {
-      m_name=n;
-    }
-
-    string getName()
-    {
-      return m_name;
-    }
-
-    Nhl& getNhl()
-    {
-      return m_nhl;
-    }
-
-    int getTimeToRefresh()
-    {
-      return m_timeToRefresh;
-    }
-
-    void setTimeToRefresh(int ttr)
-    {
-      m_timeToRefresh=ttr;
-    }
-
-    void setExpiringEventId(ndn::EventId feid)
-    {
-      m_expiringEventId=feid;
-    }
-
-    ndn::EventId getExpiringEventId()
-    {
-      return m_expiringEventId;
-    }
-
-    void setSeqNo(int fsn)
-    {
-      m_seqNo=fsn;
-    }
-
-    int getSeqNo()
-    {
-      return m_seqNo;
-    }
-
-    bool isEqualNextHops(Nhl& nhlOther);
-
-  private:
-    string m_name;
-    int m_timeToRefresh;
-    ndn::EventId m_expiringEventId;
-    int m_seqNo;
-    Nhl m_nhl;
-  };
-
-  ostream& operator<<(ostream& os,FibEntry fe);
-
-} //namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
deleted file mode 100644
index 141bf3a..0000000
--- a/src/route/nlsr_fib.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-#include<list>
-#include "nlsr_fe.hpp"
-#include "nlsr_fib.hpp"
-#include "nlsr_nhl.hpp"
-#include "nlsr.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_fib.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-  using namespace ndn;
-
-  static bool
-  fibEntryNameCompare(FibEntry& fe, string name)
-  {
-    return fe.getName() == name ;
-  }
-
-  void
-  Fib::cancelScheduledExpiringEvent(Nlsr& pnlsr, EventId eid)
-  {
-    pnlsr.getScheduler().cancelEvent(eid);
-  }
-
-
-  ndn::EventId
-  Fib::scheduleEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
-                                  int refreshTime)
-  {
-    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
-           ndn::bind(&Fib::refreshEntry,this,name,feSeqNum));
-  }
-
-  void
-  Fib::refreshEntry(string name, int feSeqNum)
-  {
-  }
-
-  void
-  Fib::remove(Nlsr& pnlsr, string name)
-  {
-    std::list<FibEntry >::iterator it = std::find_if( m_table.begin(),
-                                        m_table.end(), bind(&fibEntryNameCompare, _1, name));
-    if( it != m_table.end() )
-    {
-      for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
-          nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
-      {
-        //remove entry from NDN-FIB
-      }
-      cancelScheduledExpiringEvent(pnlsr, (*it).getExpiringEventId());
-      m_table.erase(it);
-    }
-  }
-
-
-  void
-  Fib::update(Nlsr& pnlsr,string name, Nhl& nextHopList)
-  {
-    std::cout<<"Fib::updateFib Called"<<std::endl;
-    int startFace=0;
-    int endFace=getNumberOfFacesForName(nextHopList,
-                                        pnlsr.getConfParameter().getMaxFacesPerPrefix());
-    std::list<FibEntry >::iterator it = std::find_if( m_table.begin(),
-                                        m_table.end(),
-                                        bind(&fibEntryNameCompare, _1, name));
-    if( it == m_table.end() )
-    {
-      if( nextHopList.getSize() > 0 )
-      {
-        nextHopList.sort();
-        FibEntry newEntry(name);
-        std::list<NextHop> nhl=nextHopList.getNextHopList();
-        std::list<NextHop>::iterator nhit=nhl.begin();
-        for(int i=startFace; i< endFace && nhit!=nhl.end(); ++nhit, i++)
-        {
-          newEntry.getNhl().addNextHop((*nhit));
-          //Add entry to NDN-FIB
-        }
-        newEntry.getNhl().sort();
-        newEntry.setTimeToRefresh(m_refreshTime);
-        newEntry.setSeqNo(1);
-        newEntry.setExpiringEventId(scheduleEntryRefreshing(pnlsr,
-                                      name ,1,m_refreshTime));
-        m_table.push_back(newEntry);
-      }
-    }
-    else
-    {
-      std::cout<<"Old FIB Entry"<<std::endl;
-      if( nextHopList.getSize() > 0 )
-      {
-        nextHopList.sort();
-        if ( !it->isEqualNextHops(nextHopList) )
-        {
-          std::list<NextHop> nhl=nextHopList.getNextHopList();
-          std::list<NextHop>::iterator nhit=nhl.begin();
-          // Add first Entry to NDN-FIB
-          removeHop(pnlsr, it->getNhl(),nhit->getConnectingFace());
-          it->getNhl().reset();
-          it->getNhl().addNextHop((*nhit));
-          ++startFace;
-          ++nhit;
-          for(int i=startFace; i< endFace && nhit!=nhl.end(); ++nhit, i++)
-          {
-            it->getNhl().addNextHop((*nhit));
-            //Add Entry to NDN_FIB
-          }
-        }
-        it->setTimeToRefresh(m_refreshTime);
-        cancelScheduledExpiringEvent(pnlsr, it->getExpiringEventId());
-        it->setSeqNo(it->getSeqNo()+1);
-        (*it).setExpiringEventId(scheduleEntryRefreshing(pnlsr,
-                                   it->getName() ,
-                                   it->getSeqNo(),m_refreshTime));
-      }
-      else
-      {
-        remove(pnlsr,name);
-      }
-    }
-  }
-
-
-
-  void Fib::clean(Nlsr& pnlsr)
-  {
-    for( std::list<FibEntry >::iterator it=m_table.begin(); it != m_table.end();
-         ++it)
-    {
-      for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
-          nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
-      {
-        cancelScheduledExpiringEvent(pnlsr,(*it).getExpiringEventId());
-        //Remove entry from NDN-FIB
-      }
-    }
-    if ( m_table.size() > 0 )
-    {
-      m_table.clear();
-    }
-  }
-
-  int
-  Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
-  {
-    int endFace=0;
-    if((maxFacesPerPrefix == 0) || (nextHopList.getSize() <= maxFacesPerPrefix))
-    {
-      return nextHopList.getSize();
-    }
-    else
-    {
-      return maxFacesPerPrefix;
-    }
-    return endFace;
-  }
-
-  void
-  Fib::removeHop(Nlsr& pnlsr, Nhl& nl, int doNotRemoveHopFaceId)
-  {
-    for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
-         it != nl.getNextHopList().end();   ++it)
-    {
-      if ( it->getConnectingFace() != doNotRemoveHopFaceId )
-      {
-        //Remove FIB Entry from NDN-FIB
-      }
-    }
-  }
-
-  void
-  Fib::print()
-  {
-    cout<<"-------------------FIB-----------------------------"<<endl;
-    for(std::list<FibEntry>::iterator it = m_table.begin(); it!=m_table.end();
-        ++it)
-    {
-      cout<<(*it);
-    }
-  }
-
-} //namespace nlsr
diff --git a/src/route/nlsr_fib.hpp b/src/route/nlsr_fib.hpp
deleted file mode 100644
index b36d0d8..0000000
--- a/src/route/nlsr_fib.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef NLSR_FIB_HPP
-#define NLSR_FIB_HPP
-
-#include <list>
-#include "nlsr_fe.hpp"
-
-namespace nlsr
-{
-
-  class Nlsr;
-
-  using namespace std;
-  using namespace ndn;
-
-  class Fib
-  {
-  public:
-    Fib()
-      : m_table()
-      , m_refreshTime(0)
-    {
-    }
-
-    void remove(Nlsr& pnlsr, string name);
-    void update(Nlsr& pnlsr, string name, Nhl& nextHopList);
-    void clean(Nlsr& pnlsr);
-    void setEntryRefreshTime(int fert)
-    {
-      m_refreshTime=fert;
-    }
-
-    void print();
-
-  private:
-    void removeHop(Nlsr& pnlsr, Nhl& nl, int doNotRemoveHopFaceId);
-    int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
-    ndn::EventId
-    scheduleEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
-                               int refreshTime);
-    void cancelScheduledExpiringEvent(Nlsr& pnlsr, EventId eid);
-    void refreshEntry(string name, int feSeqNum);
-
-  private:
-    std::list<FibEntry> m_table;
-    int m_refreshTime;
-  };
-
-}//namespace nlsr
-#endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
deleted file mode 100644
index f08f1ae..0000000
--- a/src/route/nlsr_map.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include<iostream>
-#include<list>
-
-#include "nlsr.hpp"
-#include "nlsr_adjacent.hpp"
-#include "nlsr_lsa.hpp"
-#include "nlsr_lsdb.hpp"
-#include "nlsr_map.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_map.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  ostream&
-  operator<<(ostream& os, MapEntry& mpe)
-  {
-    os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
-    os<<mpe.getMappingNumber()<<" )"<<endl;
-    return os;
-  }
-
-  static bool
-  mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
-  {
-    return mpe1.getRouter()==rtrName;
-  }
-
-  static bool
-  mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
-  {
-    return mpe1.getMappingNumber()==mappingNo;
-  }
-
-  void
-  Map::addElement(string& rtrName)
-  {
-    MapEntry me(rtrName,m_mappingIndex);
-    if (  addElement(me) )
-    {
-      m_mappingIndex++;
-    }
-  }
-
-  bool
-  Map::addElement(MapEntry& mpe)
-  {
-    //cout << mpe;
-    std::list<MapEntry >::iterator it = std::find_if( m_table.begin(),
-                                        m_table.end(),
-                                        bind(&mapEntryCompareByRouter, _1, mpe.getRouter()));
-    if ( it == m_table.end() )
-    {
-      m_table.push_back(mpe);
-      return true;
-    }
-    return false;
-  }
-
-  string
-  Map::getRouterNameByMappingNo(int mn)
-  {
-    std::list<MapEntry >::iterator it = std::find_if( m_table.begin(),
-                                        m_table.end(),
-                                        bind(&mapEntryCompareByMappingNo, _1, mn));
-    if ( it != m_table.end() )
-    {
-      return (*it).getRouter();
-    }
-    return "";
-  }
-
-  int
-  Map::getMappingNoByRouterName(string& rName)
-  {
-    std::list<MapEntry >::iterator it = std::find_if( m_table.begin(),
-                                        m_table.end(),
-                                        bind(&mapEntryCompareByRouter, _1, rName));
-    if ( it != m_table.end() )
-    {
-      return (*it).getMappingNumber();
-    }
-    return -1;
-  }
-
-  void
-  Map::createFromAdjLsdb(Nlsr& pnlsr)
-  {
-    std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
-    for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
-         it!= adjLsdb.end() ; it++)
-    {
-      string linkStartRouter=(*it).getOrigRouter();
-      addElement(linkStartRouter);
-      std::list<Adjacent> adl=(*it).getAdl().getAdjList();
-      for( std::list<Adjacent>::iterator itAdl=adl.begin();
-           itAdl!= adl.end() ; itAdl++)
-      {
-        string linkEndRouter=(*itAdl).getName();
-        addElement(linkEndRouter);
-      }
-    }
-  }
-
-  void
-  Map::reset()
-  {
-    m_table.clear();
-    m_mappingIndex=0;
-  }
-
-  ostream&
-  operator<<(ostream& os, Map& map)
-  {
-    os<<"---------------Map----------------------"<<endl;
-    std::list< MapEntry > ml=map.getMapList();
-    for( std::list<MapEntry>::iterator it=ml.begin(); it!= ml.end() ; it++)
-    {
-      os<< (*it);
-    }
-    return os;
-  }
-
-} //namespace nlsr
diff --git a/src/route/nlsr_map.hpp b/src/route/nlsr_map.hpp
deleted file mode 100644
index bf50aac..0000000
--- a/src/route/nlsr_map.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef NLSR_MAP_HPP
-#define NLSR_MAP_HPP
-
-#include <iostream>
-#include <list>
-
-#include <ndn-cpp-dev/face.hpp>
-
-namespace nlsr
-{
-
-  class Nlsr;
-
-  using namespace std;
-
-  class MapEntry
-  {
-  public:
-    MapEntry()
-      : m_router()
-      , m_mappingNumber(-1)
-    {
-    }
-
-    ~MapEntry()
-    {
-    }
-
-    MapEntry(string rtr, int mn)
-    {
-      m_router=rtr;
-      m_mappingNumber=mn;
-    }
-
-    string getRouter()
-    {
-      return m_router;
-    }
-
-    int getMappingNumber()
-    {
-      return m_mappingNumber;
-    }
-  private:
-    string m_router;
-    int m_mappingNumber;
-  };
-
-  ostream&
-  operator<<(ostream& os, MapEntry& mpe);
-
-  class Map
-  {
-  public:
-    Map()
-      : m_mappingIndex(0)
-    {
-    }
-
-
-    void addElement(string& rtrName);
-    void createFromAdjLsdb(Nlsr& pnlsr);
-    string getRouterNameByMappingNo(int mn);
-    int getMappingNoByRouterName(string& rName);
-    void reset();
-    std::list< MapEntry >& getMapList()
-    {
-      return m_table;
-    }
-
-    int getMapSize()
-    {
-      return m_table.size();
-    }
-
-
-  private:
-    bool addElement(MapEntry& mpe);
-
-    int m_mappingIndex;
-    std::list< MapEntry > m_table;
-  };
-
-  ostream&
-  operator<<(ostream& os, Map& map);
-
-} // namespace nlsr
-#endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
deleted file mode 100644
index 08dfe62..0000000
--- a/src/route/nlsr_nexthop.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "nlsr_nexthop.hpp"
-#include "utility/nlsr_logger.hpp"
-#define THIS_FILE "nlsr_nexthop.cpp"
-
-namespace nlsr
-{
-
-  ostream&
-  operator<<(ostream& os, NextHop& nh)
-  {
-    os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
-    return os;
-  }
-
-}//namespace nlsr
diff --git a/src/route/nlsr_nexthop.hpp b/src/route/nlsr_nexthop.hpp
deleted file mode 100644
index 0105fb6..0000000
--- a/src/route/nlsr_nexthop.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef NLSR_NEXTHOP_HPP
-#define NLSR_NEXTHOP_HPP
-
-#include<iostream>
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class NextHop
-  {
-  public:
-    NextHop()
-      : m_connectingFace(0)
-      , m_routeCost(0)
-    {
-    }
-
-    NextHop(int cf, double rc)
-    {
-      m_connectingFace=cf;
-      m_routeCost=rc;
-    }
-
-    int getConnectingFace() const
-    {
-      return m_connectingFace;
-    }
-
-    void setConnectingFace(int cf)
-    {
-      m_connectingFace=cf;
-    }
-
-    double getRouteCost() const
-    {
-      return m_routeCost;
-    }
-
-    void setRouteCost(double rc)
-    {
-      m_routeCost=rc;
-    }
-  private:
-    int m_connectingFace;
-    double m_routeCost;
-  };
-
-
-  ostream&
-  operator<<(ostream& os, NextHop& nh);
-
-}//namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
deleted file mode 100644
index ed769c9..0000000
--- a/src/route/nlsr_nhl.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <iostream>
-#include "utility/nlsr_logger.hpp"
-#include "nlsr_nhl.hpp"
-#include "nlsr_nexthop.hpp"
-
-#define THIS_FILE "nlsr_nhl.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  static bool
-  nexthopCompare(NextHop& nh1, NextHop& nh2)
-  {
-    return nh1.getConnectingFace()==nh2.getConnectingFace();
-  }
-
-  static bool
-  nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
-  {
-    return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
-            nh1.getRouteCost() == nh2.getRouteCost()) ;
-  }
-
-  static bool
-  nextHopSortingComparator(const NextHop& nh1, const NextHop& nh2)
-  {
-    return nh1.getRouteCost() < nh2.getRouteCost();
-  }
-
-  /**
-  Add next hop to the Next Hop list
-  If next hop is new it is added
-  If next hop already exists in next
-  hop list then updates the route
-  cost with new next hop's route cost
-  */
-
-  void
-  Nhl::addNextHop(NextHop& nh)
-  {
-    std::list<NextHop >::iterator it = std::find_if( m_nexthopList.begin(),
-                                       m_nexthopList.end(),
-                                       bind(&nexthopCompare, _1, nh));
-    if ( it == m_nexthopList.end() )
-    {
-      m_nexthopList.push_back(nh);
-    }
-    if ( (*it).getRouteCost() > nh.getRouteCost() )
-    {
-      (*it).setRouteCost(nh.getRouteCost());
-    }
-  }
-
-  /**
-  Remove a next hop only if both next hop face and route cost are same
-
-  */
-
-  void
-  Nhl::removeNextHop(NextHop &nh)
-  {
-    std::list<NextHop >::iterator it = std::find_if( m_nexthopList.begin(),
-                                       m_nexthopList.end(),
-                                       bind(&nexthopRemoveCompare, _1, nh));
-    if ( it != m_nexthopList.end() )
-    {
-      m_nexthopList.erase(it);
-    }
-  }
-
-  void
-  Nhl::sort()
-  {
-    m_nexthopList.sort(nextHopSortingComparator);
-  }
-
-  ostream&
-  operator<<(ostream& os, Nhl& nhl)
-  {
-    std::list< NextHop > nexthopList = nhl.getNextHopList();
-    int i=1;
-    for( std::list<NextHop>::iterator it=nexthopList.begin();
-         it!= nexthopList.end() ; it++,i++)
-    {
-      os << "Nexthop "<<i<<": "<<(*it)<<endl;
-    }
-    return os;
-  }
-
-}//namespace nlsr
diff --git a/src/route/nlsr_nhl.hpp b/src/route/nlsr_nhl.hpp
deleted file mode 100644
index fd8b4ca..0000000
--- a/src/route/nlsr_nhl.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef NLSR_NHL_HPP
-#define NLSR_NHL_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include "nlsr_adjacent.hpp"
-#include <list>
-#include <iostream>
-
-#include "nlsr_nexthop.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class Nhl
-  {
-  public:
-    Nhl()
-      : m_nexthopList()
-    {
-    }
-
-    ~Nhl()
-    {
-    }
-    void addNextHop(NextHop &nh);
-    void removeNextHop(NextHop &nh);
-    void sort();
-    int getSize()
-    {
-      return m_nexthopList.size();
-    }
-    void reset()
-    {
-      if (m_nexthopList.size() > 0 )
-      {
-        m_nexthopList.clear();
-      }
-    }
-    std::list< NextHop >& getNextHopList()
-    {
-      return m_nexthopList;
-    }
-
-  private:
-    std::list< NextHop > m_nexthopList;
-  };
-
-  ostream&
-  operator<<(ostream& os, Nhl& nhl);
-
-}//namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
deleted file mode 100644
index 89eba30..0000000
--- a/src/route/nlsr_npt.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <list>
-#include <utility>
-#include <algorithm>
-#include "utility/nlsr_logger.hpp"
-#include "nlsr_npt.hpp"
-#include "nlsr_npte.hpp"
-#include "nlsr.hpp"
-
-#define THIS_FILE "nlsr_npt.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  static bool
-  npteCompare(Npte& npte, string& name)
-  {
-    return npte.getNamePrefix()==name;
-  }
-
-
-
-  void
-  Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
-  {
-    std::list<Npte >::iterator it = std::find_if( m_npteList.begin(),
-                                    m_npteList.end(), bind(&npteCompare, _1, name));
-    if ( it == m_npteList.end() )
-    {
-      Npte newEntry(name);
-      newEntry.addRoutingTableEntry(rte);
-      newEntry.generateNhlfromRteList();
-      newEntry.getNhl().sort();
-      m_npteList.push_back(newEntry);
-      if(rte.getNhl().getSize()> 0)
-      {
-        pnlsr.getFib().update(pnlsr, name,newEntry.getNhl());
-      }
-    }
-    else
-    {
-      if ( rte.getNhl().getSize()> 0 )
-      {
-        (*it).addRoutingTableEntry(rte);
-        (*it).generateNhlfromRteList();
-        (*it).getNhl().sort();
-        pnlsr.getFib().update(pnlsr, name,(*it).getNhl());
-      }
-      else
-      {
-        (*it).resetRteListNextHop();
-        (*it).getNhl().reset();
-        pnlsr.getFib().remove(pnlsr,name);
-      }
-    }
-  }
-
-  void
-  Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
-  {
-    std::list<Npte >::iterator it = std::find_if( m_npteList.begin(),
-                                    m_npteList.end(), bind(&npteCompare, _1, name));
-    if ( it != m_npteList.end() )
-    {
-      string destRouter=rte.getDestination();
-      (*it).removeRoutingTableEntry(rte);
-      if ( ((*it).getRteListSize() == 0 ) &&
-           (!pnlsr.getLsdb().doesLsaExist(destRouter+"/1",1) ) &&
-           (!pnlsr.getLsdb().doesLsaExist(destRouter+"/2",2) ) &&
-           (!pnlsr.getLsdb().doesLsaExist(destRouter+"/3",3) )   )
-      {
-        m_npteList.erase(it);
-        pnlsr.getFib().remove(pnlsr,name);
-      }
-      else
-      {
-        (*it).generateNhlfromRteList();
-        pnlsr.getFib().update(pnlsr, name,(*it).getNhl());
-      }
-    }
-  }
-
-
-  void
-  Npt::addNpteByDestName(string name, string destRouter, Nlsr& pnlsr)
-  {
-    std::pair<RoutingTableEntry& , bool> rteCheck=
-      pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
-    if(rteCheck.second)
-    {
-      addNpte(name,rteCheck.first,pnlsr);
-    }
-    else
-    {
-      RoutingTableEntry rte(destRouter);
-      addNpte(name, rte,pnlsr);
-    }
-  }
-
-  void
-  Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
-  {
-    std::pair<RoutingTableEntry& , bool> rteCheck=
-      pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
-    if(rteCheck.second)
-    {
-      removeNpte(name,rteCheck.first,pnlsr);
-    }
-    else
-    {
-      RoutingTableEntry rte(destRouter);
-      removeNpte(name, rte,pnlsr);
-    }
-  }
-
-  void
-  Npt::updateWithNewRoute(Nlsr& pnlsr)
-  {
-    for(std::list<Npte >::iterator it=m_npteList.begin(); it!=m_npteList.end(); ++it)
-    {
-      std::list<RoutingTableEntry> rteList=(*it).getRteList();
-      for(std::list<RoutingTableEntry >::iterator rteit=rteList.begin();
-          rteit !=rteList.end(); ++rteit)
-      {
-        std::pair<RoutingTableEntry& , bool> rteCheck=
-          pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
-        if(rteCheck.second)
-        {
-          addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
-        }
-        else
-        {
-          RoutingTableEntry rte((*rteit).getDestination());
-          addNpte((*it).getNamePrefix(), rte,pnlsr);
-        }
-      }
-    }
-  }
-
-  void
-  Npt::print()
-  {
-    cout<<"----------------NPT----------------------"<<endl;
-    for(std::list<Npte >::iterator it=m_npteList.begin(); it!=m_npteList.end(); ++it)
-    {
-      cout <<(*it)<<endl;
-    }
-  }
-
-}
diff --git a/src/route/nlsr_npt.hpp b/src/route/nlsr_npt.hpp
deleted file mode 100644
index 89af33d..0000000
--- a/src/route/nlsr_npt.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef NLSR_NPT_HPP
-#define NLSR_NPT_HPP
-
-#include <list>
-#include "nlsr_npte.hpp"
-#include "nlsr_rte.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class Nlsr;
-
-  class Npt
-  {
-  public:
-    Npt()
-    {
-    }
-    void addNpteByDestName(string name, string destRouter, Nlsr& pnlsr);
-    void removeNpte(string name, string destRouter, Nlsr& pnlsr);
-    void updateWithNewRoute(Nlsr& pnlsr);
-    void print();
-  private:
-    void addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
-    void removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
-  private:
-    std::list<Npte> m_npteList;
-  };
-
-}//namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
deleted file mode 100644
index d8e83c3..0000000
--- a/src/route/nlsr_npte.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <list>
-#include <utility>
-#include "nlsr_npte.hpp"
-#include "nlsr_rte.hpp"
-#include "nlsr_nexthop.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_npte.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  void
-  Npte::generateNhlfromRteList()
-  {
-    m_nhl.reset();
-    for( std::list<RoutingTableEntry>::iterator it=m_rteList.begin();
-         it != m_rteList.end(); ++it )
-    {
-      for(std::list< NextHop >::iterator nhit=(*it).getNhl().getNextHopList().begin();
-          nhit != (*it).getNhl().getNextHopList().end(); ++nhit)
-      {
-        m_nhl.addNextHop((*nhit));
-      }
-    }
-  }
-
-
-
-  static bool
-  rteCompare(RoutingTableEntry& rte, string& destRouter)
-  {
-    return rte.getDestination()==destRouter;
-  }
-
-  void
-  Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
-  {
-    std::list<RoutingTableEntry >::iterator it = std::find_if( m_rteList.begin(),
-        m_rteList.end(),
-        bind(&rteCompare, _1, rte.getDestination()));
-    if ( it != m_rteList.end() )
-    {
-      m_rteList.erase(it);
-    }
-  }
-
-  void
-  Npte::addRoutingTableEntry(RoutingTableEntry &rte)
-  {
-    std::list<RoutingTableEntry >::iterator it = std::find_if( m_rteList.begin(),
-        m_rteList.end(),
-        bind(&rteCompare, _1, rte.getDestination()));
-    if ( it == m_rteList.end() )
-    {
-      m_rteList.push_back(rte);
-    }
-    else
-    {
-      (*it).getNhl().reset(); // reseting existing routing table's next hop
-      for(std::list< NextHop >::iterator nhit=rte.getNhl().getNextHopList().begin();
-          nhit != rte.getNhl().getNextHopList().end(); ++nhit)
-      {
-        (*it).getNhl().addNextHop((*nhit));
-      }
-    }
-  }
-
-//debugging purpose
-  ostream&
-  operator<<(ostream& os, Npte& npte)
-  {
-    os<<"Name: "<<npte.getNamePrefix()<<endl;
-    std::list<RoutingTableEntry> rteList=npte.getRteList();
-    for(std::list<RoutingTableEntry >::iterator it=rteList.begin();
-        it !=rteList.end(); ++it)
-    {
-      cout<<(*it);
-    }
-    os<<npte.getNhl();
-    return os;
-  }
-
-}//namespace nlsr
diff --git a/src/route/nlsr_npte.hpp b/src/route/nlsr_npte.hpp
deleted file mode 100644
index bb4b1c8..0000000
--- a/src/route/nlsr_npte.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef NLSR_NPTE_HPP
-#define NLSR_NPTE_HPP
-
-#include <list>
-#include <utility>
-#include "nlsr_rte.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class Npte
-  {
-  public:
-    Npte()
-      : m_namePrefix()
-      , m_nhl()
-    {
-    }
-    Npte(string np)
-      : m_nhl()
-    {
-      m_namePrefix=np;
-    }
-
-    string getNamePrefix()
-    {
-      return m_namePrefix;
-    }
-
-    std::list<RoutingTableEntry>& getRteList()
-    {
-      return m_rteList;
-    }
-
-    void resetRteListNextHop()
-    {
-      if (m_rteList.size() > 0 )
-      {
-        for( std::list<RoutingTableEntry>::iterator it=m_rteList.begin();
-             it != m_rteList.end(); ++it )
-        {
-          (*it).getNhl().reset();
-        }
-      }
-    }
-
-    int getRteListSize()
-    {
-      return m_rteList.size();
-    }
-
-    Nhl& getNhl()
-    {
-      return m_nhl;
-    }
-    void generateNhlfromRteList();
-    void removeRoutingTableEntry(RoutingTableEntry& rte);
-    void addRoutingTableEntry(RoutingTableEntry &rte);
-
-  private:
-    string m_namePrefix;
-    std::list<RoutingTableEntry> m_rteList;
-    Nhl m_nhl;
-  };
-
-  ostream&
-  operator<<(ostream& os, Npte& npte);
-
-}//namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
deleted file mode 100644
index 8267930..0000000
--- a/src/route/nlsr_rt.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-#include<iostream>
-#include<string>
-#include<list>
-
-#include "nlsr_rt.hpp"
-#include "nlsr.hpp"
-#include "nlsr_map.hpp"
-#include "nlsr_rtc.hpp"
-#include "nlsr_rte.hpp"
-#include "nlsr_npt.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_rt.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  void
-  RoutingTable::calculate(Nlsr& pnlsr)
-  {
-    //debugging purpose
-    std::cout<<pnlsr.getConfParameter()<<std::endl;
-    pnlsr.getNpt().print();
-    pnlsr.getLsdb().printAdjLsdb();
-    pnlsr.getLsdb().printCorLsdb();
-    pnlsr.getLsdb().printNameLsdb();
-    if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
-    {
-      pnlsr.setIsRoutingTableCalculating(1); //setting routing table calculation
-      if ( pnlsr.getLsdb().doesLsaExist(
-             pnlsr.getConfParameter().getRouterPrefix()+"/"+"2",2) )
-      {
-        if(pnlsr.getIsBuildAdjLsaSheduled() != 1)
-        {
-          cout<<"CLearing old routing table ....."<<endl;
-          clearRoutingTable();
-          clearDryRoutingTable(); // for dry run options
-          // calculate Link State routing
-          if( (pnlsr.getConfParameter().getIsHyperbolicCalc() == 0 )
-              || (pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 ) )
-          {
-            calculateLsRoutingTable(pnlsr);
-          }
-          //calculate hyperbolic routing
-          if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 1 )
-          {
-            calculateHypRoutingTable(pnlsr);
-          }
-          //calculate dry hyperbolic routing
-          if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 )
-          {
-            calculateHypDryRoutingTable(pnlsr);
-          }
-          //need to update NPT here
-          pnlsr.getNpt().updateWithNewRoute(pnlsr);
-          //debugging purpose
-          printRoutingTable();
-          pnlsr.getNpt().print();
-          pnlsr.getFib().print();
-          //debugging purpose end
-        }
-        else
-        {
-          cout<<"Adjacency building is scheduled, so ";
-          cout<<"routing table can not be calculated :("<<endl;
-        }
-      }
-      else
-      {
-        cout<<"No Adj LSA of router itself,";
-        cout<<	" so Routing table can not be calculated :("<<endl;
-        clearRoutingTable();
-        clearDryRoutingTable(); // for dry run options
-        // need to update NPT here
-        std::cout<<"Calling Update NPT With new Route"<<std::endl;
-        pnlsr.getNpt().updateWithNewRoute(pnlsr);
-        //debugging purpose
-        printRoutingTable();
-        pnlsr.getNpt().print();
-        pnlsr.getFib().print();
-        //debugging purpose end
-      }
-      pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
-      pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
-    }
-    else
-    {
-      scheduleRoutingTableCalculation(pnlsr);
-    }
-  }
-
-
-  void
-  RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
-  {
-    cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
-    Map vMap;
-    vMap.createFromAdjLsdb(pnlsr);
-    int numOfRouter=vMap.getMapSize();
-    LinkStateRoutingTableCalculator lsrtc(numOfRouter);
-    lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
-  }
-
-  void
-  RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
-  {
-    Map vMap;
-    vMap.createFromAdjLsdb(pnlsr);
-    int numOfRouter=vMap.getMapSize();
-    HypRoutingTableCalculator hrtc(numOfRouter,0);
-    hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
-  }
-
-  void
-  RoutingTable::calculateHypDryRoutingTable(Nlsr& pnlsr)
-  {
-    Map vMap;
-    vMap.createFromAdjLsdb(pnlsr);
-    int numOfRouter=vMap.getMapSize();
-    HypRoutingTableCalculator hrtc(numOfRouter,1);
-    hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
-  }
-
-  void
-  RoutingTable::scheduleRoutingTableCalculation(Nlsr& pnlsr)
-  {
-    if ( pnlsr.getIsRouteCalculationScheduled() != 1 )
-    {
-      pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
-                                         ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
-      pnlsr.setIsRouteCalculationScheduled(1);
-    }
-  }
-
-  static bool
-  routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter)
-  {
-    return rte.getDestination()==destRouter;
-  }
-
-// function related to manipulation of routing table
-  void
-  RoutingTable::addNextHop(string destRouter, NextHop& nh)
-  {
-    std::pair<RoutingTableEntry&, bool> rte=findRoutingTableEntry(destRouter);
-    if( !rte.second )
-    {
-      RoutingTableEntry rte(destRouter);
-      rte.getNhl().addNextHop(nh);
-      m_rTable.push_back(rte);
-    }
-    else
-    {
-      (rte.first).getNhl().addNextHop(nh);
-    }
-  }
-
-  std::pair<RoutingTableEntry&, bool>
-  RoutingTable::findRoutingTableEntry(string destRouter)
-  {
-    std::list<RoutingTableEntry >::iterator it = std::find_if( m_rTable.begin(),
-        m_rTable.end(),
-        bind(&routingTableEntryCompare, _1, destRouter));
-    if ( it != m_rTable.end() )
-    {
-      return std::make_pair(boost::ref((*it)),true);
-    }
-    RoutingTableEntry rteEmpty;
-    return std::make_pair(boost::ref(rteEmpty),false);
-  }
-
-  void
-  RoutingTable::printRoutingTable()
-  {
-    cout<<"---------------Routing Table------------------"<<endl;
-    for(std::list<RoutingTableEntry>::iterator it=m_rTable.begin() ;
-        it != m_rTable.end(); ++it)
-    {
-      cout<<(*it)<<endl;
-    }
-  }
-
-
-//function related to manipulation of dry routing table
-  void
-  RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
-  {
-    std::list<RoutingTableEntry >::iterator it = std::find_if( m_dryTable.begin(),
-        m_dryTable.end(),
-        bind(&routingTableEntryCompare, _1, destRouter));
-    if ( it == m_dryTable.end() )
-    {
-      RoutingTableEntry rte(destRouter);
-      rte.getNhl().addNextHop(nh);
-      m_dryTable.push_back(rte);
-    }
-    else
-    {
-      (*it).getNhl().addNextHop(nh);
-    }
-  }
-
-  void
-  RoutingTable::printDryRoutingTable()
-  {
-    cout<<"--------Dry Run's Routing Table--------------"<<endl;
-    for(std::list<RoutingTableEntry>::iterator it=m_dryTable.begin() ;
-        it != m_dryTable.end(); ++it)
-    {
-      cout<<(*it)<<endl;
-    }
-  }
-
-
-  void
-  RoutingTable::clearRoutingTable()
-  {
-    if( m_rTable.size() > 0 )
-    {
-      m_rTable.clear();
-    }
-  }
-
-  void
-  RoutingTable::clearDryRoutingTable()
-  {
-    if (m_dryTable.size()>0 )
-    {
-      m_dryTable.clear();
-    }
-  }
-
-}//namespace nlsr
-
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
deleted file mode 100644
index e382b8b..0000000
--- a/src/route/nlsr_rt.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef NLSR_RT_HPP
-#define NLSR_RT_HPP
-
-#include<iostream>
-#include<utility>
-#include<string>
-
-#include "nlsr_rte.hpp"
-
-namespace nlsr
-{
-
-  class Nlsr;
-  class NextHop;
-
-  using namespace std;
-
-  class RoutingTable
-  {
-  public:
-    RoutingTable()
-      : NO_NEXT_HOP(-12345)
-    {
-    }
-    void calculate(Nlsr& pnlsr);
-    void addNextHop(string destRouter, NextHop& nh);
-    void printRoutingTable();
-
-    void addNextHopToDryTable(string destRouter, NextHop& nh);
-    void printDryRoutingTable();
-    std::pair<RoutingTableEntry&, bool> findRoutingTableEntry(string destRouter);
-    void scheduleRoutingTableCalculation(Nlsr& pnlsr);
-
-  private:
-    void calculateLsRoutingTable(Nlsr& pnlsr);
-    void calculateHypRoutingTable(Nlsr& pnlsr);
-    void calculateHypDryRoutingTable(Nlsr& pnlsr);
-
-    void clearRoutingTable();
-    void clearDryRoutingTable();
-
-    const int NO_NEXT_HOP;
-
-    std::list< RoutingTableEntry > m_rTable;
-    std::list< RoutingTableEntry > m_dryTable;
-  };
-
-}//namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
deleted file mode 100644
index c6499f7..0000000
--- a/src/route/nlsr_rtc.cpp
+++ /dev/null
@@ -1,511 +0,0 @@
-#include <iostream>
-#include <cmath>
-#include "nlsr_lsdb.hpp"
-#include "nlsr_rtc.hpp"
-#include "nlsr_map.hpp"
-#include "nlsr_lsa.hpp"
-#include "nlsr_nexthop.hpp"
-#include "nlsr.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_rtc.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  void
-  RoutingTableCalculator::allocateAdjMatrix()
-  {
-    adjMatrix = new double*[numOfRouter];
-    for(int i = 0; i < numOfRouter; ++i)
-    {
-      adjMatrix[i] = new double[numOfRouter];
-    }
-  }
-
-  void
-  RoutingTableCalculator::initMatrix()
-  {
-    for(int i=0; i<numOfRouter; i++)
-    {
-      for(int j=0; j<numOfRouter; j++)
-        adjMatrix[i][j]=0;
-    }
-  }
-
-  void
-  RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
-  {
-    std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
-    for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
-         it!= adjLsdb.end() ; it++)
-    {
-      string linkStartRouter=(*it).getOrigRouter();
-      int row=pMap.getMappingNoByRouterName(linkStartRouter);
-      std::list<Adjacent> adl=(*it).getAdl().getAdjList();
-      for( std::list<Adjacent>::iterator itAdl=adl.begin();
-           itAdl!= adl.end() ; itAdl++)
-      {
-        string linkEndRouter=(*itAdl).getName();
-        int col=pMap.getMappingNoByRouterName(linkEndRouter);
-        double cost=(*itAdl).getLinkCost();
-        if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
-        {
-          adjMatrix[row][col]=cost;
-        }
-      }
-    }
-  }
-
-  void
-  RoutingTableCalculator::printAdjMatrix()
-  {
-    for(int i=0; i<numOfRouter; i++)
-    {
-      for(int j=0; j<numOfRouter; j++)
-        printf("%f ",adjMatrix[i][j]);
-      printf("\n");
-    }
-  }
-
-  void
-  RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
-  {
-    for ( int i = 0; i < numOfRouter; i++ )
-    {
-      if ( i == link )
-      {
-        adjMatrix[source][i]=linkCost;
-      }
-      else
-      {
-        adjMatrix[source][i]=0;
-      }
-    }
-  }
-
-  int
-  RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
-  {
-    int noLink=0;
-    for(int i=0; i<numOfRouter; i++)
-    {
-      if ( adjMatrix[sRouter][i] > 0 )
-      {
-        noLink++;
-      }
-    }
-    return noLink;
-  }
-
-  void
-  RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
-      double *linkCosts, int source)
-  {
-    int j=0;
-    for (int i=0; i <numOfRouter; i++)
-    {
-      if ( adjMatrix[source][i] > 0 )
-      {
-        links[j]=i;
-        linkCosts[j]=adjMatrix[source][i];
-        j++;
-      }
-    }
-  }
-
-  void
-  RoutingTableCalculator::freeAdjMatrix()
-  {
-    for(int i = 0; i < numOfRouter; ++i)
-    {
-      delete [] adjMatrix[i];
-    }
-    delete [] adjMatrix;
-  }
-
-
-  void
-  RoutingTableCalculator::allocateLinks()
-  {
-    links=new int[vNoLink];
-  }
-
-  void RoutingTableCalculator::allocateLinkCosts()
-  {
-    linkCosts=new double[vNoLink];
-  }
-
-
-  void
-  RoutingTableCalculator::freeLinks()
-  {
-    delete [] links;
-  }
-  void
-  RoutingTableCalculator::freeLinksCosts()
-  {
-    delete [] linkCosts;
-  }
-
-  void
-  LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
-      RoutingTable& rt, Nlsr& pnlsr)
-  {
-    cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
-    allocateAdjMatrix();
-    initMatrix();
-    makeAdjMatrix(pnlsr,pMap);
-    cout<<pMap;
-    printAdjMatrix();
-    string routerName=pnlsr.getConfParameter().getRouterPrefix();
-    int sourceRouter=pMap.getMappingNoByRouterName(routerName);
-    int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
-    allocateParent();
-    allocateDistance();
-    if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
-    {
-      // Single Path
-      doDijkstraPathCalculation(sourceRouter);
-      // print all ls path -- debugging purpose
-      printAllLsPath(sourceRouter);
-      // update routing table
-      addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
-    }
-    else
-    {
-      // Multi Path
-      setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
-      allocateLinks();
-      allocateLinkCosts();
-      getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
-      for (int i=0 ; i < vNoLink; i++)
-      {
-        adjustAdMatrix(sourceRouter,links[i], linkCosts[i]);
-        printAdjMatrix();
-        doDijkstraPathCalculation(sourceRouter);
-        // print all ls path -- debugging purpose
-        printAllLsPath(sourceRouter);
-        //update routing table
-        addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
-      }
-      freeLinks();
-      freeLinksCosts();
-    }
-    freeParent();
-    freeDistance();
-    freeAdjMatrix();
-  }
-
-  void
-  LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
-  {
-    int i;
-    int v,u;
-    int *Q=new int[numOfRouter];
-    int head=0;
-    /* Initiate the Parent */
-    for (i = 0 ; i < numOfRouter; i++)
-    {
-      m_parent[i]=EMPTY_PARENT;
-      m_distance[i]=INF_DISTANCE;
-      Q[i]=i;
-    }
-    if ( sourceRouter != NO_MAPPING_NUM )
-    {
-      m_distance[sourceRouter]=0;
-      sortQueueByDistance(Q,m_distance,head,numOfRouter);
-      while (head < numOfRouter )
-      {
-        u=Q[head];
-        if(m_distance[u] == INF_DISTANCE)
-        {
-          break;
-        }
-        for(v=0 ; v <numOfRouter; v++)
-        {
-          if( adjMatrix[u][v] > 0 )
-          {
-            if ( isNotExplored(Q,v,head+1,numOfRouter) )
-            {
-              if( m_distance[u] + adjMatrix[u][v] <  m_distance[v])
-              {
-                m_distance[v]=m_distance[u] + adjMatrix[u][v] ;
-                m_parent[v]=u;
-              }
-            }
-          }
-        }
-        head++;
-        sortQueueByDistance(Q,m_distance,head,numOfRouter);
-      }
-    }
-    delete [] Q;
-  }
-
-  void
-  LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
-      RoutingTable& rt, Map& pMap, int sourceRouter)
-  {
-    cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
-    cout<<endl;
-    for(int i=0; i < numOfRouter ; i++)
-    {
-      if ( i!= sourceRouter )
-      {
-        int nextHopRouter=getLsNextHop(i,sourceRouter);
-        if ( nextHopRouter != NO_NEXT_HOP )
-        {
-          double routeCost=m_distance[i];
-          string nextHopRouterName=
-            pMap.getRouterNameByMappingNo(nextHopRouter);
-          int nxtHopFace=
-            pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
-          cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
-          cout<<"Next hop Router: "<<nextHopRouterName<<endl;
-          cout<<"Next hop Face: "<<nxtHopFace<<endl;
-          cout<<"Route Cost: "<<routeCost<<endl;
-          cout<<endl;
-          // Add next hop to routing table
-          NextHop nh(nxtHopFace,routeCost);
-          rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
-        }
-      }
-    }
-  }
-
-  int
-  LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
-  {
-    int nextHop;
-    while ( m_parent[dest] != EMPTY_PARENT )
-    {
-      nextHop=dest;
-      dest=m_parent[dest];
-    }
-    if ( dest != source )
-    {
-      nextHop=NO_NEXT_HOP;
-    }
-    return nextHop;
-  }
-
-  void
-  LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
-  {
-    cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
-    cout<<"Source Router: "<<sourceRouter<<endl;
-    for(int i=0; i < numOfRouter ; i++)
-    {
-      if ( i!= sourceRouter )
-      {
-        printLsPath(i);
-        cout<<endl;
-      }
-    }
-  }
-
-  void
-  LinkStateRoutingTableCalculator::printLsPath(int destRouter)
-  {
-    if (m_parent[destRouter] != EMPTY_PARENT )
-    {
-      printLsPath(m_parent[destRouter]);
-    }
-    cout<<" "<<destRouter;
-  }
-
-  void
-  LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
-      double *dist,int start,int element)
-  {
-    for ( int i=start ; i < element ; i ++)
-    {
-      for( int j=i+1; j<element; j ++)
-      {
-        if (dist[Q[j]] < dist[Q[i]])
-        {
-          int tempU=Q[j];
-          Q[j]=Q[i];
-          Q[i]=tempU;
-        }
-      }
-    }
-  }
-
-  int
-  LinkStateRoutingTableCalculator::isNotExplored(int *Q,
-      int u,int start, int element)
-  {
-    int ret=0;
-    for(int i=start; i< element; i++)
-    {
-      if ( Q[i] == u )
-      {
-        ret=1;
-        break;
-      }
-    }
-    return ret;
-  }
-
-  void
-  LinkStateRoutingTableCalculator::allocateParent()
-  {
-    m_parent=new int[numOfRouter];
-  }
-
-  void
-  LinkStateRoutingTableCalculator::allocateDistance()
-  {
-    m_distance= new double[numOfRouter];
-  }
-
-  void
-  LinkStateRoutingTableCalculator::freeParent()
-  {
-    delete [] m_parent;
-  }
-
-  void LinkStateRoutingTableCalculator::freeDistance()
-  {
-    delete [] m_distance;
-  }
-
-
-
-  void
-  HypRoutingTableCalculator::calculatePath(Map& pMap,
-      RoutingTable& rt, Nlsr& pnlsr)
-  {
-    makeAdjMatrix(pnlsr,pMap);
-    string routerName=pnlsr.getConfParameter().getRouterPrefix();
-    int sourceRouter=pMap.getMappingNoByRouterName(routerName);
-    int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
-    setNoLink(noLink);
-    allocateLinks();
-    allocateLinkCosts();
-    getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
-    for(int i=0 ; i < numOfRouter ; ++i)
-    {
-      int k=0;
-      if ( i != sourceRouter)
-      {
-        allocateLinkFaces();
-        allocateDistanceToNeighbor();
-        allocateDistFromNbrToDest();
-        for(int j=0; j<vNoLink; j++)
-        {
-          string nextHopRouterName=pMap.getRouterNameByMappingNo(links[j]);
-          int nextHopFace=
-            pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
-          double distToNbr=getHyperbolicDistance(pnlsr,pMap,
-                                                 sourceRouter,links[j]);
-          double distToDestFromNbr=getHyperbolicDistance(pnlsr,
-                                   pMap,links[j],i);
-          if ( distToDestFromNbr >= 0 )
-          {
-            m_linkFaces[k] = nextHopFace;
-            m_distanceToNeighbor[k] = distToNbr;
-            m_distFromNbrToDest[k] = distToDestFromNbr;
-            k++;
-          }
-        }
-        addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
-        freeLinkFaces();
-        freeDistanceToNeighbor();
-        freeDistFromNbrToDest();
-      }
-    }
-    freeLinks();
-    freeLinksCosts();
-    freeAdjMatrix();
-  }
-
-  void
-  HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
-      RoutingTable& rt, int noFaces, int dest)
-  {
-    for(int i=0 ; i < noFaces ; ++i)
-    {
-      string destRouter=pMap.getRouterNameByMappingNo(dest);
-      NextHop nh(m_linkFaces[i],m_distFromNbrToDest[i]);
-      rt.addNextHop(destRouter,nh);
-      if( m_isDryRun)
-      {
-        rt.addNextHopToDryTable(destRouter,nh);
-      }
-    }
-  }
-
-  double
-  HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
-      Map& pMap, int src, int dest)
-  {
-    double distance=0.0;
-    string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
-    string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
-    double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
-    double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
-    double destRadius=(pnlsr.getLsdb().getCorLsa(
-                         destRouterKey).first).getCorRadius();
-    double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
-    double diffTheta = fabs (srcTheta - destTheta);
-    if (diffTheta > MATH_PI)
-    {
-      diffTheta = 2 * MATH_PI - diffTheta;
-    }
-    if ( srcRadius != -1 && destRadius != -1 )
-    {
-      if (diffTheta == 0)
-        distance = fabs (srcRadius - destRadius);
-      else
-        distance = acosh((cosh(srcRadius)*cosh(destRadius))-
-                         (sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
-    }
-    else
-    {
-      distance = -1;
-    }
-    return distance;
-  }
-
-  void
-  HypRoutingTableCalculator::allocateLinkFaces()
-  {
-    m_linkFaces=new int[vNoLink];
-  }
-
-  void
-  HypRoutingTableCalculator::allocateDistanceToNeighbor()
-  {
-    m_distanceToNeighbor=new double[vNoLink];
-  }
-
-  void
-  HypRoutingTableCalculator::allocateDistFromNbrToDest()
-  {
-    m_distFromNbrToDest=new double[vNoLink];
-  }
-
-  void
-  HypRoutingTableCalculator::freeLinkFaces()
-  {
-    delete [] m_linkFaces;
-  }
-
-  void
-  HypRoutingTableCalculator::freeDistanceToNeighbor()
-  {
-    delete [] m_distanceToNeighbor;
-  }
-
-  void
-  HypRoutingTableCalculator::freeDistFromNbrToDest()
-  {
-    delete [] m_distFromNbrToDest;
-  }
-
-}//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
deleted file mode 100644
index dba45ca..0000000
--- a/src/route/nlsr_rtc.hpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef NLSR_RTC_HPP
-#define NLSR_RTC_HPP
-
-#include <list>
-#include <iostream>
-
-namespace nlsr
-{
-
-  class Map;
-  class RoutingTable;
-  class Nlsr;
-
-
-  using namespace std;
-
-  class RoutingTableCalculator
-  {
-  public:
-    RoutingTableCalculator()
-    {
-    }
-    RoutingTableCalculator(int rn)
-    {
-      numOfRouter=rn;
-    }
-  protected:
-    void allocateAdjMatrix();
-    void initMatrix();
-    void makeAdjMatrix(Nlsr& pnlsr,Map pMap);
-    void printAdjMatrix();
-    int getNumOfLinkfromAdjMatrix(int sRouter);
-    void freeAdjMatrix();
-    void adjustAdMatrix(int source, int link, double linkCost);
-    void getLinksFromAdjMatrix(int *links, double *linkCosts, int source);
-
-    void allocateLinks();
-    void allocateLinkCosts();
-    void freeLinks();
-    void freeLinksCosts();
-
-    void setNoLink(int nl)
-    {
-      vNoLink=nl;
-    }
-
-  protected:
-    double** adjMatrix;
-    int numOfRouter;
-
-    int vNoLink;
-    int* links;
-    double* linkCosts;
-  };
-
-  class LinkStateRoutingTableCalculator: public RoutingTableCalculator
-  {
-  public:
-    LinkStateRoutingTableCalculator(int rn)
-      : EMPTY_PARENT(-12345)
-      , INF_DISTANCE(2147483647)
-      , NO_MAPPING_NUM(-1)
-      , NO_NEXT_HOP(-12345)
-    {
-      numOfRouter=rn;
-    }
-
-
-    void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
-
-
-  private:
-    void doDijkstraPathCalculation(int sourceRouter);
-    void sortQueueByDistance(int* Q, double* dist,int start,int element);
-    int isNotExplored(int* Q, int u,int start, int element);
-    void printAllLsPath(int sourceRouter);
-    void printLsPath(int destRouter);
-    void addAllLsNextHopsToRoutingTable(Nlsr& pnlsr, RoutingTable& rt,
-                                        Map& pMap,int sourceRouter);
-    int getLsNextHop(int dest, int source);
-
-    void allocateParent();
-    void allocateDistance();
-    void freeParent();
-    void freeDistance();
-
-
-
-
-  private:
-    int* m_parent;
-    double* m_distance;
-
-
-    const int EMPTY_PARENT;
-    const double INF_DISTANCE;
-    const int NO_MAPPING_NUM;
-    const int NO_NEXT_HOP;
-
-  };
-
-  class HypRoutingTableCalculator: public RoutingTableCalculator
-  {
-  public:
-    HypRoutingTableCalculator(int rn)
-      :  MATH_PI(3.141592654)
-    {
-      numOfRouter=rn;
-      m_isDryRun=0;
-    }
-    HypRoutingTableCalculator(int rn, int idr)
-      :  MATH_PI(3.141592654)
-    {
-      numOfRouter=rn;
-      m_isDryRun=idr;
-    }
-
-    void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
-
-  private:
-    void allocateLinkFaces();
-    void allocateDistanceToNeighbor();
-    void allocateDistFromNbrToDest();
-    void freeLinkFaces();
-    void freeDistanceToNeighbor();
-    void freeDistFromNbrToDest();
-
-    double getHyperbolicDistance(Nlsr& pnlsr,Map& pMap, int src, int dest);
-    void addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
-                                      RoutingTable& rt, int noFaces,int dest);
-
-  private:
-    bool m_isDryRun;
-
-    int* m_linkFaces;
-    double* m_distanceToNeighbor;
-    double* m_distFromNbrToDest;
-
-    const double MATH_PI;
-
-  };
-
-}//namespace nlsr
-
-#endif
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
deleted file mode 100644
index 7c06b03..0000000
--- a/src/route/nlsr_rte.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <iostream>
-#include <string>
-
-#include "nlsr_rte.hpp"
-#include "utility/nlsr_logger.hpp"
-
-#define THIS_FILE "nlsr_rte.cpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  ostream&
-  operator<<(ostream& os, RoutingTableEntry& rte)
-  {
-    os<<"Destination: "<<rte.getDestination()<<endl;
-    os<<"Nexthops: "<<endl;
-    int i=1;
-    std::list< NextHop > nhl = rte.getNhl().getNextHopList();
-    for( std::list<NextHop>::iterator it=nhl.begin();
-         it!= nhl.end() ; it++,i++)
-    {
-      os <<"  Nexthop "<<i<<": "<<(*it)<<endl;
-    }
-    return os;
-  }
-
-}//namespace nlsr
diff --git a/src/route/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
deleted file mode 100644
index 484edab..0000000
--- a/src/route/nlsr_rte.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef NLSR_RTE_HPP
-#define NLSR_RTE_HPP
-
-#include<iostream>
-
-#include "nlsr_nhl.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-
-  class RoutingTableEntry
-  {
-  public:
-    RoutingTableEntry()
-      : m_destination()
-      , m_nhl()
-    {
-    }
-
-    ~RoutingTableEntry()
-    {
-    }
-
-    RoutingTableEntry(string dest)
-      : m_nhl()
-    {
-      m_destination=dest;
-    }
-
-    string getDestination()
-    {
-      return m_destination;
-    }
-
-    Nhl& getNhl()
-    {
-      return m_nhl;
-    }
-
-  private:
-    string m_destination;
-    Nhl m_nhl;
-  };
-
-  ostream&
-  operator<<(ostream& os, RoutingTableEntry& rte);
-
-}
-
-#endif
diff --git a/src/route/npt.cpp b/src/route/npt.cpp
new file mode 100644
index 0000000..665dbb2
--- /dev/null
+++ b/src/route/npt.cpp
@@ -0,0 +1,151 @@
+#include <list>
+#include <utility>
+#include <algorithm>
+
+#include "npt.hpp"
+#include "npte.hpp"
+#include "nlsr.hpp"
+
+
+namespace nlsr {
+
+using namespace std;
+
+static bool
+npteCompare(Npte& npte, string& name)
+{
+  return npte.getNamePrefix() == name;
+}
+
+
+
+void
+Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+{
+  std::list<Npte>::iterator it = std::find_if(m_npteList.begin(),
+                                              m_npteList.end(), bind(&npteCompare, _1, name));
+  if (it == m_npteList.end())
+  {
+    Npte newEntry(name);
+    newEntry.addRoutingTableEntry(rte);
+    newEntry.generateNhlfromRteList();
+    newEntry.getNhl().sort();
+    m_npteList.push_back(newEntry);
+    if (rte.getNhl().getSize() > 0)
+    {
+      pnlsr.getFib().update(pnlsr, name, newEntry.getNhl());
+    }
+  }
+  else
+  {
+    if (rte.getNhl().getSize() > 0)
+    {
+      (*it).addRoutingTableEntry(rte);
+      (*it).generateNhlfromRteList();
+      (*it).getNhl().sort();
+      pnlsr.getFib().update(pnlsr, name, (*it).getNhl());
+    }
+    else
+    {
+      (*it).resetRteListNextHop();
+      (*it).getNhl().reset();
+      pnlsr.getFib().remove(pnlsr, name);
+    }
+  }
+}
+
+void
+Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+{
+  std::list<Npte>::iterator it = std::find_if(m_npteList.begin(),
+                                              m_npteList.end(), bind(&npteCompare, _1, name));
+  if (it != m_npteList.end())
+  {
+    string destRouter = rte.getDestination();
+    (*it).removeRoutingTableEntry(rte);
+    if (((*it).getRteListSize() == 0) &&
+        (!pnlsr.getLsdb().doesLsaExist(destRouter + "/1", 1)) &&
+        (!pnlsr.getLsdb().doesLsaExist(destRouter + "/2", 2)) &&
+        (!pnlsr.getLsdb().doesLsaExist(destRouter + "/3", 3)))
+    {
+      m_npteList.erase(it);
+      pnlsr.getFib().remove(pnlsr, name);
+    }
+    else
+    {
+      (*it).generateNhlfromRteList();
+      pnlsr.getFib().update(pnlsr, name, (*it).getNhl());
+    }
+  }
+}
+
+
+void
+Npt::addNpteByDestName(string name, string destRouter, Nlsr& pnlsr)
+{
+  std::pair<RoutingTableEntry&, bool> rteCheck =
+    pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+  if (rteCheck.second)
+  {
+    addNpte(name, rteCheck.first, pnlsr);
+  }
+  else
+  {
+    RoutingTableEntry rte(destRouter);
+    addNpte(name, rte, pnlsr);
+  }
+}
+
+void
+Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
+{
+  std::pair<RoutingTableEntry&, bool> rteCheck =
+    pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+  if (rteCheck.second)
+  {
+    removeNpte(name, rteCheck.first, pnlsr);
+  }
+  else
+  {
+    RoutingTableEntry rte(destRouter);
+    removeNpte(name, rte, pnlsr);
+  }
+}
+
+void
+Npt::updateWithNewRoute(Nlsr& pnlsr)
+{
+  for (std::list<Npte>::iterator it = m_npteList.begin(); it != m_npteList.end();
+       ++it)
+  {
+    std::list<RoutingTableEntry> rteList = (*it).getRteList();
+    for (std::list<RoutingTableEntry>::iterator rteit = rteList.begin();
+         rteit != rteList.end(); ++rteit)
+    {
+      std::pair<RoutingTableEntry&, bool> rteCheck =
+        pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
+      if (rteCheck.second)
+      {
+        addNpte((*it).getNamePrefix(), rteCheck.first, pnlsr);
+      }
+      else
+      {
+        RoutingTableEntry rte((*rteit).getDestination());
+        addNpte((*it).getNamePrefix(), rte, pnlsr);
+      }
+    }
+  }
+}
+
+void
+Npt::print()
+{
+  std::cout << "----------------NPT----------------------" << std::endl;
+  for (std::list<Npte>::iterator it = m_npteList.begin(); it != m_npteList.end();
+       ++it)
+  {
+    cout << (*it) << endl;
+  }
+}
+
+} //namespace nlsr
diff --git a/src/route/npt.hpp b/src/route/npt.hpp
new file mode 100644
index 0000000..8e6cd0a
--- /dev/null
+++ b/src/route/npt.hpp
@@ -0,0 +1,42 @@
+#ifndef NLSR_NPT_HPP
+#define NLSR_NPT_HPP
+
+#include <list>
+#include "npte.hpp"
+#include "routing-table-entry.hpp"
+
+namespace nlsr {
+class Nlsr;
+
+class Npt
+{
+public:
+  Npt()
+  {
+  }
+  void
+  addNpteByDestName(std::string name, std::string destRouter, Nlsr& pnlsr);
+
+  void
+  removeNpte(std::string name, std::string destRouter, Nlsr& pnlsr);
+
+  void
+  updateWithNewRoute(Nlsr& pnlsr);
+
+  void
+  print();
+
+private:
+  void
+  addNpte(std::string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+
+  void
+  removeNpte(std::string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+
+private:
+  std::list<Npte> m_npteList;
+};
+
+}//namespace nlsr
+
+#endif //NLSR_NPT_HPP
diff --git a/src/route/npte.cpp b/src/route/npte.cpp
new file mode 100644
index 0000000..3194635
--- /dev/null
+++ b/src/route/npte.cpp
@@ -0,0 +1,83 @@
+#include <list>
+#include <utility>
+#include "npte.hpp"
+#include "routing-table-entry.hpp"
+#include "nexthop.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+void
+Npte::generateNhlfromRteList()
+{
+  m_nhl.reset();
+  for (std::list<RoutingTableEntry>::iterator it = m_rteList.begin();
+       it != m_rteList.end(); ++it)
+  {
+    for (std::list<NextHop>::iterator nhit =
+           (*it).getNhl().getNextHopList().begin();
+         nhit != (*it).getNhl().getNextHopList().end(); ++nhit)
+    {
+      m_nhl.addNextHop((*nhit));
+    }
+  }
+}
+
+
+
+static bool
+rteCompare(RoutingTableEntry& rte, string& destRouter)
+{
+  return rte.getDestination() == destRouter;
+}
+
+void
+Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
+{
+  std::list<RoutingTableEntry>::iterator it = std::find_if(m_rteList.begin(),
+                                                           m_rteList.end(),
+                                                           bind(&rteCompare, _1, rte.getDestination()));
+  if (it != m_rteList.end())
+  {
+    m_rteList.erase(it);
+  }
+}
+
+void
+Npte::addRoutingTableEntry(RoutingTableEntry& rte)
+{
+  std::list<RoutingTableEntry>::iterator it = std::find_if(m_rteList.begin(),
+                                                           m_rteList.end(),
+                                                           bind(&rteCompare, _1, rte.getDestination()));
+  if (it == m_rteList.end())
+  {
+    m_rteList.push_back(rte);
+  }
+  else
+  {
+    (*it).getNhl().reset(); // reseting existing routing table's next hop
+    for (std::list<NextHop>::iterator nhit = rte.getNhl().getNextHopList().begin();
+         nhit != rte.getNhl().getNextHopList().end(); ++nhit)
+    {
+      (*it).getNhl().addNextHop((*nhit));
+    }
+  }
+}
+
+//debugging purpose
+ostream&
+operator<<(ostream& os, Npte& npte)
+{
+  os << "Name: " << npte.getNamePrefix() << endl;
+  std::list<RoutingTableEntry> rteList = npte.getRteList();
+  for (std::list<RoutingTableEntry>::iterator it = rteList.begin();
+       it != rteList.end(); ++it)
+  {
+    cout << (*it);
+  }
+  os << npte.getNhl();
+  return os;
+}
+
+}//namespace nlsr
diff --git a/src/route/npte.hpp b/src/route/npte.hpp
new file mode 100644
index 0000000..57fdfec
--- /dev/null
+++ b/src/route/npte.hpp
@@ -0,0 +1,84 @@
+#ifndef NLSR_NPTE_HPP
+#define NLSR_NPTE_HPP
+
+#include <list>
+#include <utility>
+#include "routing-table-entry.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+class Npte
+{
+public:
+  Npte()
+    : m_namePrefix()
+    , m_nhl()
+  {
+  }
+
+  Npte(string np)
+    : m_nhl()
+  {
+    m_namePrefix = np;
+  }
+
+  std::string
+  getNamePrefix()
+  {
+    return m_namePrefix;
+  }
+
+  std::list<RoutingTableEntry>&
+  getRteList()
+  {
+    return m_rteList;
+  }
+
+  void
+  resetRteListNextHop()
+  {
+    if (m_rteList.size() > 0)
+    {
+      for (std::list<RoutingTableEntry>::iterator it = m_rteList.begin();
+           it != m_rteList.end(); ++it)
+      {
+        (*it).getNhl().reset();
+      }
+    }
+  }
+
+  int
+  getRteListSize()
+  {
+    return m_rteList.size();
+  }
+
+  Nhl&
+  getNhl()
+  {
+    return m_nhl;
+  }
+
+  void
+  generateNhlfromRteList();
+
+  void
+  removeRoutingTableEntry(RoutingTableEntry& rte);
+
+  void
+  addRoutingTableEntry(RoutingTableEntry& rte);
+
+private:
+  std::string m_namePrefix;
+  std::list<RoutingTableEntry> m_rteList;
+  Nhl m_nhl;
+};
+
+std::ostream&
+operator<<(std::ostream& os, Npte& npte);
+
+}//namespace nlsr
+
+#endif //NLSR_NPTE_HPP
diff --git a/src/route/routing-table-calculator.cpp b/src/route/routing-table-calculator.cpp
new file mode 100644
index 0000000..6c6dad3
--- /dev/null
+++ b/src/route/routing-table-calculator.cpp
@@ -0,0 +1,514 @@
+#include <iostream>
+#include <cmath>
+#include "lsdb.hpp"
+#include "routing-table-calculator.hpp"
+#include "map.hpp"
+#include "lsa.hpp"
+#include "nexthop.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+void
+RoutingTableCalculator::allocateAdjMatrix()
+{
+  adjMatrix = new double*[numOfRouter];
+  for (int i = 0; i < numOfRouter; ++i)
+  {
+    adjMatrix[i] = new double[numOfRouter];
+  }
+}
+
+void
+RoutingTableCalculator::initMatrix()
+{
+  for (int i = 0; i < numOfRouter; i++)
+  {
+    for (int j = 0; j < numOfRouter; j++)
+      adjMatrix[i][j] = 0;
+  }
+}
+
+void
+RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
+{
+  std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
+  for (std::list<AdjLsa>::iterator it = adjLsdb.begin();
+       it != adjLsdb.end() ; it++)
+  {
+    string linkStartRouter = (*it).getOrigRouter();
+    int row = pMap.getMappingNoByRouterName(linkStartRouter);
+    std::list<Adjacent> adl = (*it).getAdl().getAdjList();
+    for (std::list<Adjacent>::iterator itAdl = adl.begin();
+         itAdl != adl.end() ; itAdl++)
+    {
+      string linkEndRouter = (*itAdl).getName();
+      int col = pMap.getMappingNoByRouterName(linkEndRouter);
+      double cost = (*itAdl).getLinkCost();
+      if ((row >= 0 && row < numOfRouter) && (col >= 0 && col < numOfRouter))
+      {
+        adjMatrix[row][col] = cost;
+      }
+    }
+  }
+}
+
+void
+RoutingTableCalculator::printAdjMatrix()
+{
+  for (int i = 0; i < numOfRouter; i++)
+  {
+    for (int j = 0; j < numOfRouter; j++)
+      printf("%f ", adjMatrix[i][j]);
+    printf("\n");
+  }
+}
+
+void
+RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+{
+  for (int i = 0; i < numOfRouter; i++)
+  {
+    if (i == link)
+    {
+      adjMatrix[source][i] = linkCost;
+    }
+    else
+    {
+      adjMatrix[source][i] = 0;
+    }
+  }
+}
+
+int
+RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+{
+  int noLink = 0;
+  for (int i = 0; i < numOfRouter; i++)
+  {
+    if (adjMatrix[sRouter][i] > 0)
+    {
+      noLink++;
+    }
+  }
+  return noLink;
+}
+
+void
+RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
+                                              double* linkCosts, int source)
+{
+  int j = 0;
+  for (int i = 0; i < numOfRouter; i++)
+  {
+    if (adjMatrix[source][i] > 0)
+    {
+      links[j] = i;
+      linkCosts[j] = adjMatrix[source][i];
+      j++;
+    }
+  }
+}
+
+void
+RoutingTableCalculator::freeAdjMatrix()
+{
+  for (int i = 0; i < numOfRouter; ++i)
+  {
+    delete [] adjMatrix[i];
+  }
+  delete [] adjMatrix;
+}
+
+
+void
+RoutingTableCalculator::allocateLinks()
+{
+  links = new int[vNoLink];
+}
+
+void
+RoutingTableCalculator::allocateLinkCosts()
+{
+  linkCosts = new double[vNoLink];
+}
+
+
+void
+RoutingTableCalculator::freeLinks()
+{
+  delete [] links;
+}
+void
+RoutingTableCalculator::freeLinksCosts()
+{
+  delete [] linkCosts;
+}
+
+void
+LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
+                                               RoutingTable& rt, Nlsr& pnlsr)
+{
+  std::cout << "LinkStateRoutingTableCalculator::calculatePath Called" <<
+            std::endl;
+  allocateAdjMatrix();
+  initMatrix();
+  makeAdjMatrix(pnlsr, pMap);
+  std::cout << pMap;
+  printAdjMatrix();
+  string routerName = pnlsr.getConfParameter().getRouterPrefix();
+  int sourceRouter = pMap.getMappingNoByRouterName(routerName);
+  //int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
+  allocateParent();
+  allocateDistance();
+  if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1)
+  {
+    // Single Path
+    doDijkstraPathCalculation(sourceRouter);
+    // print all ls path -- debugging purpose
+    printAllLsPath(sourceRouter);
+    // update routing table
+    addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
+  }
+  else
+  {
+    // Multi Path
+    setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
+    allocateLinks();
+    allocateLinkCosts();
+    getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+    for (int i = 0 ; i < vNoLink; i++)
+    {
+      adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
+      printAdjMatrix();
+      doDijkstraPathCalculation(sourceRouter);
+      // print all ls path -- debugging purpose
+      printAllLsPath(sourceRouter);
+      //update routing table
+      addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
+    }
+    freeLinks();
+    freeLinksCosts();
+  }
+  freeParent();
+  freeDistance();
+  freeAdjMatrix();
+}
+
+void
+LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
+{
+  int i;
+  int v, u;
+  int* Q = new int[numOfRouter];
+  int head = 0;
+  /* Initiate the Parent */
+  for (i = 0 ; i < numOfRouter; i++)
+  {
+    m_parent[i] = EMPTY_PARENT;
+    m_distance[i] = INF_DISTANCE;
+    Q[i] = i;
+  }
+  if (sourceRouter != NO_MAPPING_NUM)
+  {
+    m_distance[sourceRouter] = 0;
+    sortQueueByDistance(Q, m_distance, head, numOfRouter);
+    while (head < numOfRouter)
+    {
+      u = Q[head];
+      if (m_distance[u] == INF_DISTANCE)
+      {
+        break;
+      }
+      for (v = 0 ; v < numOfRouter; v++)
+      {
+        if (adjMatrix[u][v] > 0)
+        {
+          if (isNotExplored(Q, v, head + 1, numOfRouter))
+          {
+            if (m_distance[u] + adjMatrix[u][v] <  m_distance[v])
+            {
+              m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
+              m_parent[v] = u;
+            }
+          }
+        }
+      }
+      head++;
+      sortQueueByDistance(Q, m_distance, head, numOfRouter);
+    }
+  }
+  delete [] Q;
+}
+
+void
+LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
+                                                                RoutingTable& rt, Map& pMap, int sourceRouter)
+{
+  std::cout <<
+            "LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
+  std::cout << std::endl;
+  int nextHopRouter = 0;
+  for (int i = 0; i < numOfRouter ; i++)
+  {
+    if (i != sourceRouter)
+    {
+      nextHopRouter = getLsNextHop(i, sourceRouter);
+      if (nextHopRouter != NO_NEXT_HOP)
+      {
+        double routeCost = m_distance[i];
+        string nextHopRouterName =
+          pMap.getRouterNameByMappingNo(nextHopRouter);
+        int nxtHopFace =
+          pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+        std::cout << "Dest Router: " << pMap.getRouterNameByMappingNo(i) << std::endl;
+        std::cout << "Next hop Router: " << nextHopRouterName << std::endl;
+        std::cout << "Next hop Face: " << nxtHopFace << std::endl;
+        std::cout << "Route Cost: " << routeCost << std::endl;
+        std::cout << std::endl;
+        // Add next hop to routing table
+        NextHop nh(nxtHopFace, routeCost);
+        rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
+      }
+    }
+  }
+}
+
+int
+LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+{
+  int nextHop = NO_NEXT_HOP;
+  while (m_parent[dest] != EMPTY_PARENT)
+  {
+    nextHop = dest;
+    dest = m_parent[dest];
+  }
+  if (dest != source)
+  {
+    nextHop = NO_NEXT_HOP;
+  }
+  return nextHop;
+}
+
+void
+LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
+{
+  std::cout << "LinkStateRoutingTableCalculator::printAllLsPath Called" <<
+            std::endl;
+  std::cout << "Source Router: " << sourceRouter << std::endl;
+  for (int i = 0; i < numOfRouter ; i++)
+  {
+    if (i != sourceRouter)
+    {
+      printLsPath(i);
+      std::cout << std::endl;
+    }
+  }
+}
+
+void
+LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+{
+  if (m_parent[destRouter] != EMPTY_PARENT)
+  {
+    printLsPath(m_parent[destRouter]);
+  }
+  std:: cout << " " << destRouter;
+}
+
+void
+LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
+                                                     double* dist, int start, int element)
+{
+  for (int i = start ; i < element ; i++)
+  {
+    for (int j = i + 1; j < element; j++)
+    {
+      if (dist[Q[j]] < dist[Q[i]])
+      {
+        int tempU = Q[j];
+        Q[j] = Q[i];
+        Q[i] = tempU;
+      }
+    }
+  }
+}
+
+int
+LinkStateRoutingTableCalculator::isNotExplored(int* Q,
+                                               int u, int start, int element)
+{
+  int ret = 0;
+  for (int i = start; i < element; i++)
+  {
+    if (Q[i] == u)
+    {
+      ret = 1;
+      break;
+    }
+  }
+  return ret;
+}
+
+void
+LinkStateRoutingTableCalculator::allocateParent()
+{
+  m_parent = new int[numOfRouter];
+}
+
+void
+LinkStateRoutingTableCalculator::allocateDistance()
+{
+  m_distance = new double[numOfRouter];
+}
+
+void
+LinkStateRoutingTableCalculator::freeParent()
+{
+  delete [] m_parent;
+}
+
+void LinkStateRoutingTableCalculator::freeDistance()
+{
+  delete [] m_distance;
+}
+
+
+
+void
+HypRoutingTableCalculator::calculatePath(Map& pMap,
+                                         RoutingTable& rt, Nlsr& pnlsr)
+{
+  makeAdjMatrix(pnlsr, pMap);
+  string routerName = pnlsr.getConfParameter().getRouterPrefix();
+  int sourceRouter = pMap.getMappingNoByRouterName(routerName);
+  int noLink = getNumOfLinkfromAdjMatrix(sourceRouter);
+  setNoLink(noLink);
+  allocateLinks();
+  allocateLinkCosts();
+  getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+  for (int i = 0 ; i < numOfRouter ; ++i)
+  {
+    int k = 0;
+    if (i != sourceRouter)
+    {
+      allocateLinkFaces();
+      allocateDistanceToNeighbor();
+      allocateDistFromNbrToDest();
+      for (int j = 0; j < vNoLink; j++)
+      {
+        string nextHopRouterName = pMap.getRouterNameByMappingNo(links[j]);
+        int nextHopFace =
+          pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+        double distToNbr = getHyperbolicDistance(pnlsr, pMap,
+                                                 sourceRouter, links[j]);
+        double distToDestFromNbr = getHyperbolicDistance(pnlsr,
+                                                         pMap, links[j], i);
+        if (distToDestFromNbr >= 0)
+        {
+          m_linkFaces[k] = nextHopFace;
+          m_distanceToNeighbor[k] = distToNbr;
+          m_distFromNbrToDest[k] = distToDestFromNbr;
+          k++;
+        }
+      }
+      addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
+      freeLinkFaces();
+      freeDistanceToNeighbor();
+      freeDistFromNbrToDest();
+    }
+  }
+  freeLinks();
+  freeLinksCosts();
+  freeAdjMatrix();
+}
+
+void
+HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
+                                                        RoutingTable& rt, int noFaces, int dest)
+{
+  for (int i = 0 ; i < noFaces ; ++i)
+  {
+    string destRouter = pMap.getRouterNameByMappingNo(dest);
+    NextHop nh(m_linkFaces[i], m_distFromNbrToDest[i]);
+    rt.addNextHop(destRouter, nh);
+    if (m_isDryRun)
+    {
+      rt.addNextHopToDryTable(destRouter, nh);
+    }
+  }
+}
+
+double
+HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
+                                                 Map& pMap, int src, int dest)
+{
+  double distance = 0.0;
+  string srcRouterKey = pMap.getRouterNameByMappingNo(src) + "/3";
+  string destRouterKey = pMap.getRouterNameByMappingNo(dest) + "/3";
+  double srcRadius = (pnlsr.getLsdb().getCorLsa(
+                        srcRouterKey).first).getCorRadius();
+  double srcTheta = (pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
+  double destRadius = (pnlsr.getLsdb().getCorLsa(
+                         destRouterKey).first).getCorRadius();
+  double destTheta = (pnlsr.getLsdb().getCorLsa(
+                        destRouterKey).first).getCorTheta();
+  double diffTheta = fabs(srcTheta - destTheta);
+  if (diffTheta > MATH_PI)
+  {
+    diffTheta = 2 * MATH_PI - diffTheta;
+  }
+  if (srcRadius != -1 && destRadius != -1)
+  {
+    if (diffTheta == 0)
+      distance = fabs(srcRadius - destRadius);
+    else
+      distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
+                       (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
+  }
+  else
+  {
+    distance = -1;
+  }
+  return distance;
+}
+
+void
+HypRoutingTableCalculator::allocateLinkFaces()
+{
+  m_linkFaces = new int[vNoLink];
+}
+
+void
+HypRoutingTableCalculator::allocateDistanceToNeighbor()
+{
+  m_distanceToNeighbor = new double[vNoLink];
+}
+
+void
+HypRoutingTableCalculator::allocateDistFromNbrToDest()
+{
+  m_distFromNbrToDest = new double[vNoLink];
+}
+
+void
+HypRoutingTableCalculator::freeLinkFaces()
+{
+  delete [] m_linkFaces;
+}
+
+void
+HypRoutingTableCalculator::freeDistanceToNeighbor()
+{
+  delete [] m_distanceToNeighbor;
+}
+
+void
+HypRoutingTableCalculator::freeDistFromNbrToDest()
+{
+  delete [] m_distFromNbrToDest;
+}
+
+}//namespace nlsr
diff --git a/src/route/routing-table-calculator.hpp b/src/route/routing-table-calculator.hpp
new file mode 100644
index 0000000..b248b15
--- /dev/null
+++ b/src/route/routing-table-calculator.hpp
@@ -0,0 +1,201 @@
+#ifndef NLSR_RTC_HPP
+#define NLSR_RTC_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr {
+
+class Map;
+class RoutingTable;
+class Nlsr;
+
+class RoutingTableCalculator
+{
+public:
+  RoutingTableCalculator()
+  {
+  }
+  RoutingTableCalculator(int rn)
+  {
+    numOfRouter = rn;
+  }
+protected:
+  void
+  allocateAdjMatrix();
+
+  void
+  initMatrix();
+
+  void
+  makeAdjMatrix(Nlsr& pnlsr, Map pMap);
+
+  void
+  printAdjMatrix();
+
+  int
+  getNumOfLinkfromAdjMatrix(int sRouter);
+
+  void
+  freeAdjMatrix();
+
+  void
+  adjustAdMatrix(int source, int link, double linkCost);
+
+  void
+  getLinksFromAdjMatrix(int* links, double* linkCosts, int source);
+
+  void
+  allocateLinks();
+
+  void
+  allocateLinkCosts();
+
+  void
+  freeLinks();
+
+  void
+  freeLinksCosts();
+
+  void
+  setNoLink(int nl)
+  {
+    vNoLink = nl;
+  }
+
+protected:
+  double** adjMatrix;
+  int numOfRouter;
+
+  int vNoLink;
+  int* links;
+  double* linkCosts;
+};
+
+class LinkStateRoutingTableCalculator: public RoutingTableCalculator
+{
+public:
+  LinkStateRoutingTableCalculator(int rn)
+    : EMPTY_PARENT(-12345)
+    , INF_DISTANCE(2147483647)
+    , NO_MAPPING_NUM(-1)
+    , NO_NEXT_HOP(-12345)
+  {
+    numOfRouter = rn;
+  }
+
+
+  void
+  calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+
+private:
+  void
+  doDijkstraPathCalculation(int sourceRouter);
+
+  void
+  sortQueueByDistance(int* Q, double* dist, int start, int element);
+
+  int
+  isNotExplored(int* Q, int u, int start, int element);
+
+  void
+  printAllLsPath(int sourceRouter);
+
+  void
+  printLsPath(int destRouter);
+
+  void
+  addAllLsNextHopsToRoutingTable(Nlsr& pnlsr, RoutingTable& rt,
+                                 Map& pMap, int sourceRouter);
+
+  int
+  getLsNextHop(int dest, int source);
+
+  void
+  allocateParent();
+
+  void
+  allocateDistance();
+
+  void
+  freeParent();
+
+  void
+  freeDistance();
+
+
+
+
+private:
+  int* m_parent;
+  double* m_distance;
+
+
+  const int EMPTY_PARENT;
+  const double INF_DISTANCE;
+  const int NO_MAPPING_NUM;
+  const int NO_NEXT_HOP;
+
+};
+
+class HypRoutingTableCalculator: public RoutingTableCalculator
+{
+public:
+  HypRoutingTableCalculator(int rn)
+    :  MATH_PI(3.141592654)
+  {
+    numOfRouter = rn;
+    m_isDryRun = 0;
+  }
+
+  HypRoutingTableCalculator(int rn, int idr)
+    :  MATH_PI(3.141592654)
+  {
+    numOfRouter = rn;
+    m_isDryRun = idr;
+  }
+
+  void
+  calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+private:
+  void
+  allocateLinkFaces();
+
+  void
+  allocateDistanceToNeighbor();
+
+  void
+  allocateDistFromNbrToDest();
+
+  void
+  freeLinkFaces();
+
+  void
+  freeDistanceToNeighbor();
+
+  void
+  freeDistFromNbrToDest();
+
+  double
+  getHyperbolicDistance(Nlsr& pnlsr, Map& pMap, int src, int dest);
+
+  void
+  addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
+                               RoutingTable& rt, int noFaces, int dest);
+
+private:
+  bool m_isDryRun;
+
+  int* m_linkFaces;
+  double* m_distanceToNeighbor;
+  double* m_distFromNbrToDest;
+
+  const double MATH_PI;
+
+};
+
+}//namespace nlsr
+
+#endif //NLSR_RTC_HPP
diff --git a/src/route/routing-table-entry.cpp b/src/route/routing-table-entry.cpp
new file mode 100644
index 0000000..5222cb9
--- /dev/null
+++ b/src/route/routing-table-entry.cpp
@@ -0,0 +1,25 @@
+#include <iostream>
+#include <string>
+
+#include "routing-table-entry.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+ostream&
+operator<<(ostream& os, RoutingTableEntry& rte)
+{
+  os << "Destination: " << rte.getDestination() << endl;
+  os << "Nexthops: " << endl;
+  int i = 1;
+  std::list<NextHop> nhl = rte.getNhl().getNextHopList();
+  for (std::list<NextHop>::iterator it = nhl.begin();
+       it != nhl.end() ; it++, i++)
+  {
+    os << "  Nexthop " << i << ": " << (*it) << endl;
+  }
+  return os;
+}
+
+}//namespace nlsr
diff --git a/src/route/routing-table-entry.hpp b/src/route/routing-table-entry.hpp
new file mode 100644
index 0000000..f185e61
--- /dev/null
+++ b/src/route/routing-table-entry.hpp
@@ -0,0 +1,51 @@
+#ifndef NLSR_RTE_HPP
+#define NLSR_RTE_HPP
+
+#include <iostream>
+
+#include "nhl.hpp"
+
+namespace nlsr {
+
+class RoutingTableEntry
+{
+public:
+  RoutingTableEntry()
+    : m_destination()
+    , m_nhl()
+  {
+  }
+
+  ~RoutingTableEntry()
+  {
+  }
+
+  RoutingTableEntry(std::string dest)
+    : m_nhl()
+  {
+    m_destination = dest;
+  }
+
+  std::string
+  getDestination()
+  {
+    return m_destination;
+  }
+
+  Nhl&
+  getNhl()
+  {
+    return m_nhl;
+  }
+
+private:
+  std::string m_destination;
+  Nhl m_nhl;
+};
+
+std::ostream&
+operator<<(std::ostream& os, RoutingTableEntry& rte);
+
+} //namespace nlsr
+
+#endif //NLSR_RTE_HPP
diff --git a/src/route/routing-table.cpp b/src/route/routing-table.cpp
new file mode 100644
index 0000000..9e2c19c
--- /dev/null
+++ b/src/route/routing-table.cpp
@@ -0,0 +1,232 @@
+#include <iostream>
+#include <string>
+#include <list>
+
+#include "routing-table.hpp"
+#include "nlsr.hpp"
+#include "map.hpp"
+#include "routing-table-calculator.hpp"
+#include "routing-table-entry.hpp"
+#include "npt.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+void
+RoutingTable::calculate(Nlsr& pnlsr)
+{
+  //debugging purpose
+  std::cout << pnlsr.getConfParameter() << std::endl;
+  pnlsr.getNpt().print();
+  pnlsr.getLsdb().printAdjLsdb();
+  pnlsr.getLsdb().printCorLsdb();
+  pnlsr.getLsdb().printNameLsdb();
+  if (pnlsr.getIsRoutingTableCalculating() == 0)
+  {
+    pnlsr.setIsRoutingTableCalculating(1); //setting routing table calculation
+    if (pnlsr.getLsdb().doesLsaExist(
+          pnlsr.getConfParameter().getRouterPrefix() + "/" + "2", 2))
+    {
+      if (pnlsr.getIsBuildAdjLsaSheduled() != 1)
+      {
+        std::cout << "CLearing old routing table ....." << std::endl;
+        clearRoutingTable();
+        clearDryRoutingTable(); // for dry run options
+        // calculate Link State routing
+        if ((pnlsr.getConfParameter().getIsHyperbolicCalc() == 0)
+            || (pnlsr.getConfParameter().getIsHyperbolicCalc() == 2))
+        {
+          calculateLsRoutingTable(pnlsr);
+        }
+        //calculate hyperbolic routing
+        if (pnlsr.getConfParameter().getIsHyperbolicCalc() == 1)
+        {
+          calculateHypRoutingTable(pnlsr);
+        }
+        //calculate dry hyperbolic routing
+        if (pnlsr.getConfParameter().getIsHyperbolicCalc() == 2)
+        {
+          calculateHypDryRoutingTable(pnlsr);
+        }
+        //need to update NPT here
+        pnlsr.getNpt().updateWithNewRoute(pnlsr);
+        //debugging purpose
+        printRoutingTable();
+        pnlsr.getNpt().print();
+        pnlsr.getFib().print();
+        //debugging purpose end
+      }
+      else
+      {
+        std::cout << "Adjacency building is scheduled, so ";
+        std::cout << "routing table can not be calculated :(" << std::endl;
+      }
+    }
+    else
+    {
+      std::cout << "No Adj LSA of router itself,";
+      std::cout <<	" so Routing table can not be calculated :(" << std::endl;
+      clearRoutingTable();
+      clearDryRoutingTable(); // for dry run options
+      // need to update NPT here
+      std::cout << "Calling Update NPT With new Route" << std::endl;
+      pnlsr.getNpt().updateWithNewRoute(pnlsr);
+      //debugging purpose
+      printRoutingTable();
+      pnlsr.getNpt().print();
+      pnlsr.getFib().print();
+      //debugging purpose end
+    }
+    pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
+    pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
+  }
+  else
+  {
+    scheduleRoutingTableCalculation(pnlsr);
+  }
+}
+
+
+void
+RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
+{
+  std::cout << "RoutingTable::calculateLsRoutingTable Called" << std::endl;
+  Map vMap;
+  vMap.createFromAdjLsdb(pnlsr);
+  int numOfRouter = vMap.getMapSize();
+  LinkStateRoutingTableCalculator lsrtc(numOfRouter);
+  lsrtc.calculatePath(vMap, boost::ref(*this), pnlsr);
+}
+
+void
+RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
+{
+  Map vMap;
+  vMap.createFromAdjLsdb(pnlsr);
+  int numOfRouter = vMap.getMapSize();
+  HypRoutingTableCalculator hrtc(numOfRouter, 0);
+  hrtc.calculatePath(vMap, boost::ref(*this), pnlsr);
+}
+
+void
+RoutingTable::calculateHypDryRoutingTable(Nlsr& pnlsr)
+{
+  Map vMap;
+  vMap.createFromAdjLsdb(pnlsr);
+  int numOfRouter = vMap.getMapSize();
+  HypRoutingTableCalculator hrtc(numOfRouter, 1);
+  hrtc.calculatePath(vMap, boost::ref(*this), pnlsr);
+}
+
+void
+RoutingTable::scheduleRoutingTableCalculation(Nlsr& pnlsr)
+{
+  if (pnlsr.getIsRouteCalculationScheduled() != 1)
+  {
+    pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
+                                       ndn::bind(&RoutingTable::calculate, this, boost::ref(pnlsr)));
+    pnlsr.setIsRouteCalculationScheduled(1);
+  }
+}
+
+static bool
+routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter)
+{
+  return rte.getDestination() == destRouter;
+}
+
+// function related to manipulation of routing table
+void
+RoutingTable::addNextHop(string destRouter, NextHop& nh)
+{
+  std::pair<RoutingTableEntry&, bool> rte = findRoutingTableEntry(destRouter);
+  if (!rte.second)
+  {
+    RoutingTableEntry rte(destRouter);
+    rte.getNhl().addNextHop(nh);
+    m_rTable.push_back(rte);
+  }
+  else
+  {
+    (rte.first).getNhl().addNextHop(nh);
+  }
+}
+
+std::pair<RoutingTableEntry&, bool>
+RoutingTable::findRoutingTableEntry(string destRouter)
+{
+  std::list<RoutingTableEntry>::iterator it = std::find_if(m_rTable.begin(),
+                                                           m_rTable.end(),
+                                                           bind(&routingTableEntryCompare, _1, destRouter));
+  if (it != m_rTable.end())
+  {
+    return std::make_pair(boost::ref((*it)), true);
+  }
+  RoutingTableEntry rteEmpty;
+  return std::make_pair(boost::ref(rteEmpty), false);
+}
+
+void
+RoutingTable::printRoutingTable()
+{
+  std::cout << "---------------Routing Table------------------" << std::endl;
+  for (std::list<RoutingTableEntry>::iterator it = m_rTable.begin() ;
+       it != m_rTable.end(); ++it)
+  {
+    std::cout << (*it) << std::endl;
+  }
+}
+
+
+//function related to manipulation of dry routing table
+void
+RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
+{
+  std::list<RoutingTableEntry>::iterator it = std::find_if(m_dryTable.begin(),
+                                                           m_dryTable.end(),
+                                                           bind(&routingTableEntryCompare, _1, destRouter));
+  if (it == m_dryTable.end())
+  {
+    RoutingTableEntry rte(destRouter);
+    rte.getNhl().addNextHop(nh);
+    m_dryTable.push_back(rte);
+  }
+  else
+  {
+    (*it).getNhl().addNextHop(nh);
+  }
+}
+
+void
+RoutingTable::printDryRoutingTable()
+{
+  std::cout << "--------Dry Run's Routing Table--------------" << std::endl;
+  for (std::list<RoutingTableEntry>::iterator it = m_dryTable.begin() ;
+       it != m_dryTable.end(); ++it)
+  {
+    cout << (*it) << endl;
+  }
+}
+
+
+void
+RoutingTable::clearRoutingTable()
+{
+  if (m_rTable.size() > 0)
+  {
+    m_rTable.clear();
+  }
+}
+
+void
+RoutingTable::clearDryRoutingTable()
+{
+  if (m_dryTable.size() > 0)
+  {
+    m_dryTable.clear();
+  }
+}
+
+}//namespace nlsr
+
diff --git a/src/route/routing-table.hpp b/src/route/routing-table.hpp
new file mode 100644
index 0000000..cc04915
--- /dev/null
+++ b/src/route/routing-table.hpp
@@ -0,0 +1,73 @@
+#ifndef NLSR_RT_HPP
+#define NLSR_RT_HPP
+
+#include <iostream>
+#include <utility>
+#include <string>
+
+#include "routing-table-entry.hpp"
+
+namespace nlsr {
+
+class Nlsr;
+class NextHop;
+
+class RoutingTable
+{
+public:
+  RoutingTable()
+    : m_NO_NEXT_HOP(-12345)
+  {
+  }
+  void
+  calculate(Nlsr& pnlsr);
+
+  void
+  addNextHop(std::string destRouter, NextHop& nh);
+
+  void
+  printRoutingTable();
+
+  void
+  addNextHopToDryTable(std::string destRouter, NextHop& nh);
+
+  void
+  printDryRoutingTable();
+
+  std::pair<RoutingTableEntry&, bool>
+  findRoutingTableEntry(std::string destRouter);
+
+  void
+  scheduleRoutingTableCalculation(Nlsr& pnlsr);
+
+  int
+  getNoNextHop()
+  {
+    return m_NO_NEXT_HOP;
+  }
+
+private:
+  void
+  calculateLsRoutingTable(Nlsr& pnlsr);
+
+  void
+  calculateHypRoutingTable(Nlsr& pnlsr);
+
+  void
+  calculateHypDryRoutingTable(Nlsr& pnlsr);
+
+  void
+  clearRoutingTable();
+
+  void
+  clearDryRoutingTable();
+
+  const int m_NO_NEXT_HOP;
+
+  std::list<RoutingTableEntry> m_rTable;
+  std::list<RoutingTableEntry> m_dryTable;
+};
+
+}//namespace nlsr
+
+#endif //NLSR_RT_HPP
diff --git a/src/security/certificate-store-entry.cpp b/src/security/certificate-store-entry.cpp
new file mode 100644
index 0000000..5cb7933
--- /dev/null
+++ b/src/security/certificate-store-entry.cpp
@@ -0,0 +1,17 @@
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+#include "certificate-store-entry.hpp"
+
+namespace nlsr {
+std::ostream&
+operator<<(std::ostream& os, const CertificateStoreEntry& ncse)
+{
+  os << "------Certificate Entry---------------" << std::endl;
+  os << *(ncse.getCert()) << std::endl;
+  ndn::SignatureSha256WithRsa sig(ncse.getCert()->getSignature());
+  ndn::Name keyName = sig.getKeyLocator().getName();
+  os << "Signee : " << keyName.toUri() << std::endl;
+  os << "Cert Seq Num: " << ncse.getCertSeqNum() << std::endl;
+  os << "Is Signer Verified: " << ncse.getIsSignerVerified() << std::endl;
+  return os;
+}
+}//namespace nlsr
diff --git a/src/security/certificate-store-entry.hpp b/src/security/certificate-store-entry.hpp
new file mode 100644
index 0000000..1257129
--- /dev/null
+++ b/src/security/certificate-store-entry.hpp
@@ -0,0 +1,72 @@
+#ifndef NLSR_CERT_STORE_ENTRY_HPP
+#define NLSR_CERT_STORE_ENTRY_HPP
+
+#include <iostream>
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+
+namespace nlsr {
+class CertificateStoreEntry
+{
+public:
+  CertificateStoreEntry()
+    : m_cert(ndn::make_shared<ndn::IdentityCertificate>())
+    , m_certSeqNum(0)
+    , m_isSignerVerified(false)
+  {}
+
+  CertificateStoreEntry(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                        , uint32_t csn, bool isv)
+    : m_cert(pcert)
+    , m_certSeqNum(csn)
+    , m_isSignerVerified(isv)
+  {}
+
+  ndn::shared_ptr<ndn::IdentityCertificate>
+  getCert() const
+  {
+    return m_cert;
+  }
+
+  void
+  setCert(ndn::shared_ptr<ndn::IdentityCertificate> pcert)
+  {
+    m_cert = pcert;
+  }
+
+  uint32_t
+  getCertSeqNum() const
+  {
+    return m_certSeqNum;
+  }
+
+  void
+  setCertSeqNum(uint32_t csn)
+  {
+    m_certSeqNum = csn;
+  }
+
+  bool
+  getIsSignerVerified() const
+  {
+    return m_isSignerVerified;
+  }
+
+  void
+  setIsSignerVerified(bool isv)
+  {
+    m_isSignerVerified = isv;
+  }
+
+private:
+  ndn::shared_ptr<ndn::IdentityCertificate> m_cert;
+  uint32_t m_certSeqNum;
+  bool m_isSignerVerified;
+};
+/* Debugging Purpose */
+std::ostream&
+operator <<(std::ostream& os, const CertificateStoreEntry& ncse);
+
+}//namespace NLSR
+
+#endif //NLSR_CERT_STORE_ENTRY_HPP
diff --git a/src/security/certificate-store.cpp b/src/security/certificate-store.cpp
new file mode 100644
index 0000000..3ac5361
--- /dev/null
+++ b/src/security/certificate-store.cpp
@@ -0,0 +1,233 @@
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include "certificate-store.hpp"
+#include "waiting-list-entry.hpp"
+#include "key-manager.hpp"
+
+
+namespace nlsr {
+static bool
+nlsrCertificateStoreEntryCompare(CertificateStoreEntry& ncse1,
+                                 CertificateStoreEntry& ncse2)
+
+{
+  int sizeDiff = ncse1.getCert()->getName().size() -
+                 ncse2.getCert()->getName().size();
+  return (ncse2.getCert()->getName().isPrefixOf(ncse1.getCert()->getName()) &&
+          (sizeDiff <= 1 && sizeDiff >= 0));
+}
+
+static bool
+nlsrCertificateStoreEntryCompareByName(CertificateStoreEntry& ncse1,
+                                       std::string compCertName)
+
+{
+  ndn::Name ccn(compCertName);
+  int sizeDiff = ncse1.getCert()->getName().size() - ccn.size();
+  return (ccn.isPrefixOf(ncse1.getCert()->getName()) &&
+          (sizeDiff <= 1 && sizeDiff >= 0));
+}
+
+void
+CertificateStore::updateWaitingList(std::string respCertName)
+{
+  ndn::Name tmpName(respCertName);
+  respCertName = tmpName.getPrefix(-1).toUri();
+  std::pair<WaitingListEntry, bool> chkWle =
+    m_waitingList.getWaitingListEntry(respCertName);
+  if (chkWle.second)
+  {
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> sc =
+      getCertificateFromStore(respCertName);
+    std::list<std::string> waitees = (chkWle.first).getWaitingCerts();
+    for (std::list<std::string>::iterator it = waitees.begin();
+         it != waitees.end(); ++it)
+    {
+      KeyManager km;
+      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> wc =
+        getCertificateFromStore(*(it));
+      if (wc.second && sc.second)
+      {
+        if (km.verifySignature(*(wc.first), sc.first->getPublicKeyInfo()))
+        {
+          //1. Update Certificate Store
+          setCertificateIsVerified(*(it), true);
+          //2. Call updateWaitingList for waitee ( *(it) )
+          updateWaitingList(*(it));
+        }
+      }
+    }
+  }
+
+  //remove that entry from waiting list
+  m_waitingList.remove(respCertName);
+}
+
+void
+CertificateStore::updateWaitingList(CertificateStoreEntry& ncse)
+{
+  if (ncse.getIsSignerVerified())
+  {
+    updateWaitingList(ncse.getCert()->getName().toUri());
+  }
+  else
+  {
+    ndn::SignatureSha256WithRsa signature(ncse.getCert()->getSignature());
+    m_waitingList.add(signature.getKeyLocator().getName().toUri(),
+                      ncse.getCert()->getName().toUri());
+  }
+}
+
+bool
+CertificateStore::addCertificate(CertificateStoreEntry& ncse)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompare, _1, ncse));
+  if (it == m_certTable.end())
+  {
+    m_certTable.push_back(ncse);
+    updateWaitingList(ncse);
+    return true;
+  }
+  else if (it !=  m_certTable.end())
+  {
+    if ((*it).getCertSeqNum() < ncse.getCertSeqNum())
+    {
+      m_certTable.erase(it);
+      m_certTable.push_back(ncse);
+      updateWaitingList(ncse);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool
+CertificateStore::addCertificate(
+  ndn::shared_ptr<ndn::IdentityCertificate> pcert, uint32_t csn, bool isv)
+{
+  CertificateStoreEntry ncse(pcert, csn, isv);
+  return addCertificate(ncse);
+}
+
+std::pair<uint32_t, bool>
+CertificateStore::getCertificateSeqNum(std::string certName)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it == m_certTable.end())
+  {
+    return std::make_pair(0, false);
+  }
+  return std::make_pair((*it).getCertSeqNum(), true);
+}
+
+
+
+void
+CertificateStore::setCertificateIsVerified(std::string certName,
+                                           bool isVerified)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it != m_certTable.end())
+  {
+    it->setIsSignerVerified(true);
+  }
+}
+
+bool
+CertificateStore::getCertificateIsVerified(std::string certName)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it != m_certTable.end())
+  {
+    return it->getIsSignerVerified();
+  }
+
+  return false;
+}
+
+std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+CertificateStore::getCertificateFromStore(const std::string certName)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it == m_certTable.end())
+  {
+    ndn::shared_ptr<ndn::IdentityCertificate> cert =
+      ndn::make_shared<ndn::IdentityCertificate>();
+    return std::make_pair(cert, false);
+  }
+  return std::make_pair((*it).getCert(), true);
+}
+
+std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+CertificateStore::getCertificateFromStore(
+  const std::string certName, uint64_t checkSeqNum)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it == m_certTable.end())
+  {
+    ndn::shared_ptr<ndn::IdentityCertificate> cert =
+      ndn::make_shared<ndn::IdentityCertificate>();
+    return std::make_pair(cert, false);
+  }
+  else
+  {
+    if ((*it).getCertSeqNum() == checkSeqNum)
+    {
+      return std::make_pair((*it).getCert(), true);
+    }
+  }
+  return std::make_pair((*it).getCert(), false);
+}
+
+bool
+CertificateStore::isCertificateNewInStore(const std::string certName,
+                                          int checkSeqNo)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it != m_certTable.end())
+  {
+    return (*it).getCertSeqNum() < checkSeqNo ;
+  }
+  return true;
+}
+
+bool
+CertificateStore::removeCertificateFromStroe(const std::string certName)
+{
+  std::list<CertificateStoreEntry>::iterator it =
+    std::find_if(m_certTable.begin(), m_certTable.end(),
+                 bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+  if (it != m_certTable.end())
+  {
+    m_certTable.erase(it);
+    return true;
+  }
+  return false;
+}
+
+void
+CertificateStore::print()
+{
+  std::list<CertificateStoreEntry>::iterator it;
+  for (it = m_certTable.begin(); it != m_certTable.end(); ++it)
+  {
+    std::cout << (*it) << std::endl;
+  }
+  std::cout << m_waitingList << std::endl;
+}
+
+} //namespace nlsr
diff --git a/src/security/certificate-store.hpp b/src/security/certificate-store.hpp
new file mode 100644
index 0000000..01495d9
--- /dev/null
+++ b/src/security/certificate-store.hpp
@@ -0,0 +1,63 @@
+#ifndef NLSR_CERT_STORE_HPP
+#define NLSR_CERT_STORE_HPP
+
+#include <list>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include "certificate-store-entry.hpp"
+#include "waiting-list.hpp"
+
+namespace nlsr {
+class CertificateStore
+{
+public:
+  CertificateStore()
+    : m_certTable()
+    , m_waitingList()
+  {}
+
+  bool
+  addCertificate(CertificateStoreEntry& ncse);
+
+  bool
+  addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                 , uint32_t csn, bool isv);
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  getCertificateFromStore(const std::string certName);
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  getCertificateFromStore(const std::string certName, uint64_t checkSeqNum);
+
+  bool
+  removeCertificateFromStroe(const std::string certName);
+
+  bool
+  isCertificateNewInStore(const std::string certName, int checkSeqNo);
+
+  std::pair<uint32_t, bool>
+  getCertificateSeqNum(std::string certName);
+
+  void
+  print();
+
+  void
+  setCertificateIsVerified(std::string certName, bool isVerified);
+
+  bool
+  getCertificateIsVerified(std::string certName);
+
+private:
+  void
+  updateWaitingList(CertificateStoreEntry& ncse);
+
+  void
+  updateWaitingList(std::string respCertName);
+
+private:
+  std::list<CertificateStoreEntry> m_certTable;
+  WaitingList m_waitingList;
+};
+
+} //namespace nlsr
+
+#endif // NLSR_CERT_STORE_HPP
diff --git a/src/security/key-manager.cpp b/src/security/key-manager.cpp
new file mode 100644
index 0000000..5ab63a8
--- /dev/null
+++ b/src/security/key-manager.cpp
@@ -0,0 +1,406 @@
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/encoding/block.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+#include <stdexcept>
+
+#include "sequencing-manager.hpp"
+#include "key-manager.hpp"
+#include "nlsr.hpp"
+
+
+namespace nlsr {
+bool
+KeyManager::initialize(ConfParameter& cp)
+{
+  initCertSeqFromFile(cp.getSeqFileDir());
+  if (!loadAllCertificates(cp.getCertDir()))
+  {
+    return false;
+  }
+  m_nlsrRootKeyPrefix = cp.getRootKeyPrefix();
+  string processIdentityName(cp.getRootKeyPrefix());
+  processIdentityName += "/";
+  processIdentityName += cp.getSiteName();
+  processIdentityName += "/";
+  processIdentityName += "R.Start";
+  processIdentityName += "/";
+  processIdentityName += cp.getRouterName();
+  ndn::Name ri(processIdentityName);
+  std::cout << "Router Identity: " << ri.toUri() << std::endl;
+  m_routerIdentity = ri;
+  processIdentityName += "/";
+  processIdentityName += "nlsr";
+  cout << "Proces Identity Name: " << processIdentityName << endl;
+  ndn::Name identityName(processIdentityName);
+  m_processIdentity = identityName;
+  ndn::KeyChain::deleteIdentity(m_processIdentity);
+  m_processCertName = ndn::KeyChain::createIdentity(m_processIdentity);
+  cout << "Certificate Name: " << m_processCertName.toUri() << endl;
+  m_processKeyName = m_processCertName.getPrefix(-2);
+  cout << "Key Name: " << m_processKeyName.toUri() << endl;
+  ndn::shared_ptr<ndn::IdentityCertificate> cert =
+    getCertificate(m_processCertName);
+  signByIdentity(*(cert), m_routerIdentity);
+  m_certStore.addCertificate(cert, m_certSeqNo, true);
+  m_certStore.print();
+  return true;
+}
+
+bool
+KeyManager::loadAllCertificates(std::string certDirPath)
+{
+  std::string filePath = certDirPath;
+  if (filePath.empty())
+  {
+    SequencingManager sm;
+    filePath = sm.getUserHomeDirectory();
+    filePath += "/nlsrCertDir";
+  }
+  return loadCertificate(filePath + "/root.cert", KEY_TYPE_ROOT)
+         && loadCertificate(filePath + "/site.cert", KEY_TYPE_SITE)
+         && loadCertificate(filePath + "/operator.cert", KEY_TYPE_OPERATOR)
+         && loadCertificate(filePath + "/router.cert", KEY_TYPE_ROUTER) ;
+}
+
+bool
+KeyManager::loadCertificate(std::string inputFile, nlsrKeyType keyType)
+{
+  try
+  {
+    ndn::shared_ptr<ndn::IdentityCertificate> cert =
+      ndn::io::load<ndn::IdentityCertificate>(inputFile, ndn::io::BASE_64);
+    ndn::Name certName = cert->getName();
+    switch (keyType)
+      {
+      case KEY_TYPE_ROOT:
+        m_certStore.addCertificate(cert, 10, true);
+        m_rootCertName = certName;
+        std::cout << "Root Cert: " << m_rootCertName << std::endl;
+        break;
+      case KEY_TYPE_SITE:
+        m_certStore.addCertificate(cert, 10, true);
+        m_siteCertName = certName;
+        std::cout << "Site Cert: " << m_siteCertName << std::endl;
+        break;
+      case KEY_TYPE_OPERATOR:
+        m_certStore.addCertificate(cert, 10, true);
+        m_opCertName = certName;
+        std::cout << "Operator Cert: " << m_opCertName << std::endl;
+        break;
+      case KEY_TYPE_ROUTER:
+        m_certStore.addCertificate(cert, m_certSeqNo, true);
+        m_routerCertName = certName;
+        std::cout << "Router Cert: " << m_routerCertName << std::endl;
+        break;
+      case KEY_TYPE_PROCESS:
+        m_certStore.addCertificate(cert, m_certSeqNo, true);
+        m_processCertName = certName;
+        std::cout << "Process Cert: " << m_processCertName << std::endl;
+        break;
+      default:
+        break;
+      }
+    return true;
+  }
+  catch (std::exception& e)
+  {
+    return false;
+  }
+  return false;
+}
+
+ndn::Name
+KeyManager::getProcessCertName()
+{
+  return m_processCertName;
+}
+
+ndn::Name
+KeyManager::getRouterCertName()
+{
+  return m_routerCertName;
+}
+
+ndn::Name
+KeyManager::getOperatorCertName()
+{
+  return m_opCertName;
+}
+
+ndn::Name
+KeyManager::getSiteCertName()
+{
+  return m_siteCertName;
+}
+
+ndn::Name
+KeyManager::getRootCertName()
+{
+  return m_rootCertName;
+}
+
+uint32_t
+KeyManager::getCertSeqNo()
+{
+  return m_certSeqNo;
+}
+
+void
+KeyManager::setCerSeqNo(uint32_t csn)
+{
+  m_certSeqNo = csn;
+}
+
+void
+KeyManager::initCertSeqFromFile(string certSeqFileDir)
+{
+  m_certSeqFileNameWithPath = certSeqFileDir;
+  if (m_certSeqFileNameWithPath.empty())
+  {
+    SequencingManager sm;
+    m_certSeqFileNameWithPath = sm.getUserHomeDirectory();
+  }
+  m_certSeqFileNameWithPath += "/nlsrCertSeqNo.txt";
+  cout << "Key Seq File Name: " << m_certSeqFileNameWithPath << endl;
+  std::ifstream inputFile(m_certSeqFileNameWithPath.c_str(), ios::binary);
+  if (inputFile.good())
+  {
+    inputFile >> m_certSeqNo;
+    m_certSeqNo++;
+  }
+  else
+  {
+    m_certSeqNo = 1;
+  }
+  writeCertSeqToFile();
+}
+
+void
+KeyManager::writeCertSeqToFile()
+{
+  std::ofstream outputFile(m_certSeqFileNameWithPath.c_str(), ios::binary);
+  outputFile << m_certSeqNo;
+  outputFile.close();
+}
+
+bool
+KeyManager::isNewCertificate(std::string certName, int checkSeqNum)
+{
+  return m_certStore.isCertificateNewInStore(certName, checkSeqNum);
+}
+
+std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+KeyManager::getCertificateFromStore(const std::string certName, int checkSeqNum)
+{
+  return m_certStore.getCertificateFromStore(certName, checkSeqNum);
+}
+
+std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+KeyManager::getCertificateFromStore(const std::string certName)
+{
+  return m_certStore.getCertificateFromStore(certName);
+}
+
+bool
+KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                           , uint32_t csn, bool isv)
+{
+  return m_certStore.addCertificate(pcert, csn, isv);
+}
+
+std::pair<uint32_t, bool>
+KeyManager::getCertificateSeqNum(std::string certName)
+{
+  return m_certStore.getCertificateSeqNum(certName);
+}
+
+nlsrKeyType
+KeyManager::getKeyTypeFromName(const std::string keyName)
+{
+  Tokenizer nt(keyName, "/");
+  std::string KEY("KEY");
+  std::string opHandle("O.Start");
+  std::string routerHandle("R.Start");
+  std::string processHandle("nlsr");
+  if (nt.getTokenString(0, nt.getTokenPosition(KEY) - 1) == m_nlsrRootKeyPrefix)
+  {
+    return KEY_TYPE_ROOT;
+  }
+  else if (nt.doesTokenExist(opHandle))
+  {
+    return KEY_TYPE_OPERATOR;
+  }
+  else if (nt.doesTokenExist(routerHandle) &&
+           nt.doesTokenExist(processHandle))
+  {
+    return KEY_TYPE_PROCESS;
+  }
+  else if (nt.doesTokenExist(routerHandle) &&
+           !nt.doesTokenExist(processHandle))
+  {
+    return KEY_TYPE_ROUTER;
+  }
+  else
+  {
+    return KEY_TYPE_SITE;
+  }
+}
+
+std::string
+KeyManager::getRouterName(const std::string name)
+{
+  std::string routerName;
+  std::string rkp(m_nlsrRootKeyPrefix);
+  Tokenizer ntRkp(rkp, "/");
+  Tokenizer nt(name, "/");
+  std::string KEY("KEY");
+  std::string opHandle("O.Start");
+  std::string routerHandle("R.Start");
+  std::string processHandle("nlsr");
+  std::string infoHandle("info");
+  std::string lsaHandle("LSA");
+  if (nt.doesTokenExist(processHandle) && nt.doesTokenExist(routerHandle))
+  {
+    routerName = "/ndn" +
+                 nt.getTokenString(ntRkp.getTokenNumber(),
+                                   nt.getTokenPosition(routerHandle) - 1) +
+                 nt.getTokenString(nt.getTokenPosition(routerHandle) + 1,
+                                   nt.getTokenPosition(processHandle) - 1);
+  }
+  else if (nt.doesTokenExist(routerHandle) && !nt.doesTokenExist(infoHandle)
+           && !nt.doesTokenExist(lsaHandle))
+  {
+    routerName = "/ndn" +
+                 nt.getTokenString(ntRkp.getTokenNumber(),
+                                   nt.getTokenPosition(routerHandle) - 1) +
+                 nt.getTokenString(nt.getTokenPosition(routerHandle) + 1,
+                                   nt.getTokenPosition(KEY) - 1);
+  }
+  else
+  {
+    if (nt.doesTokenExist(infoHandle))
+    {
+      routerName = nt.getTokenString(0, nt.getTokenPosition(infoHandle) - 1);
+    }
+    else
+    {
+      routerName = nt.getTokenString(nt.getTokenPosition(lsaHandle) + 1,
+                                     nt.getTokenNumber() - 4);
+    }
+  }
+  return routerName;
+}
+
+std::string
+KeyManager::getSiteName(const std::string name)
+{
+  std::string siteName;
+  std::string routerName;
+  std::string rkp(m_nlsrRootKeyPrefix);
+  Tokenizer ntRkp(rkp, "/");
+  Tokenizer nt(name, "/");
+  std::string KEY("KEY");
+  std::string opHandle("O.Start");
+  std::string routerHandle("R.Start");
+  if (nt.doesTokenExist(routerHandle))
+  {
+    siteName = "/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
+                                          nt.getTokenPosition(routerHandle) - 1);
+  }
+  else if (nt.doesTokenExist(opHandle))
+  {
+    siteName = "/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
+                                          nt.getTokenPosition(opHandle) - 1);
+  }
+  else
+  {
+    siteName = "/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
+                                          nt.getTokenPosition(KEY) - 1);
+  }
+  return siteName;
+}
+
+std::string
+KeyManager::getRootName(const std::string name)
+{
+  std::string rName;
+  Tokenizer nt(name, "/");
+  std::string rkp(m_nlsrRootKeyPrefix);
+  Tokenizer ntRkp(rkp, "/");
+  rName = nt.getTokenString(0, ntRkp.getTokenNumber() - 1);
+  return rName;
+}
+
+
+bool
+KeyManager::verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
+{
+  std::cout << "KeyManager::verifyCertPacket Called" << std::endl;
+  ndn::SignatureSha256WithRsa signature(packet.getSignature());
+  std::string signingCertName = signature.getKeyLocator().getName().toUri();
+  std::string packetName = packet.getName().toUri();
+
+  std::cout << "Packet Name: " << packetName << std::endl;
+  std::cout << "Signee Name: " << signingCertName << std::endl;
+
+  int paketCertType = getKeyTypeFromName(packetName);
+  int signingCertType = getKeyTypeFromName(signingCertName);
+
+  if (signingCertType > paketCertType)  //lower level Cert can not sign
+  {
+    //upper level Cert
+    return false;
+  }
+
+  if ((signingCertType == paketCertType) && (paketCertType != KEY_TYPE_ROOT))
+  {
+    return false;
+  }
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee =
+    m_certStore.getCertificateFromStore(signingCertName);
+
+  if (signee.second)
+  {
+    switch (paketCertType)
+      {
+      case KEY_TYPE_ROOT:
+        return ((getRootName(packetName) == m_nlsrRootKeyPrefix) &&
+                verifySignature(packet, signee.first->getPublicKeyInfo()));
+        break;
+      case KEY_TYPE_SITE:
+        return ((getRootName(packetName) == getRootName(signingCertName)) &&
+                verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+                m_certStore.getCertificateIsVerified(signingCertName));
+        break;
+      case KEY_TYPE_OPERATOR:
+        return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
+                verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+                m_certStore.getCertificateIsVerified(signingCertName));
+        break;
+      case KEY_TYPE_ROUTER:
+        return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
+                verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+                m_certStore.getCertificateIsVerified(signingCertName));
+        break;
+      case KEY_TYPE_PROCESS:
+        return ((getRouterName(packetName) == getRouterName(signingCertName)) &&
+                verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+                m_certStore.getCertificateIsVerified(signingCertName));
+        break;
+      }
+  }
+  else
+  {
+    std::cout << "Certificate Not Found in store. Sending Interest" << std::endl;
+    pnlsr.getIm().expressInterest(pnlsr, signingCertName, 3,
+                                  pnlsr.getConfParameter().getInterestResendTime());
+    return false;
+  }
+  return false;
+}
+
+}//namespace nlsr
+
+
+
diff --git a/src/security/key-manager.hpp b/src/security/key-manager.hpp
new file mode 100644
index 0000000..9becfe2
--- /dev/null
+++ b/src/security/key-manager.hpp
@@ -0,0 +1,275 @@
+#ifndef NLSR_KM_HPP
+#define NLSR_KM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/data.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/security/validator.hpp>
+#include <ndn-cpp-dev/util/random.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <list>
+#include "conf-parameter.hpp"
+#include "certificate-store.hpp"
+#include "utility/tokenizer.hpp"
+
+namespace nlsr {
+class Nlsr;
+enum nlsrKeyType
+{
+  KEY_TYPE_ROOT,
+  KEY_TYPE_SITE,
+  KEY_TYPE_OPERATOR,
+  KEY_TYPE_ROUTER,
+  KEY_TYPE_PROCESS,
+  KEY_TYPE_UNKNOWN
+};
+
+enum nlsrContentType
+{
+  CONTENT_TYPE_DATA,
+  CONTENT_TYPE_CERT
+};
+
+class KeyManager: public ndn::KeyChain, public ndn::Validator
+{
+  typedef SecPublicInfo::Error InfoError;
+  typedef SecTpm::Error TpmError;
+public:
+  using ndn::KeyChain::addCertificate;
+  KeyManager()
+    : m_certSeqNo(1)
+    , m_nlsrRootKeyPrefix()
+    , m_certStore()
+  {
+  }
+
+  bool
+  initialize(ConfParameter& cp);
+
+
+
+  void
+  checkPolicy(const ndn::Data& data,
+              int stepCount,
+              const ndn::OnDataValidated& onValidated,
+              const ndn::OnDataValidationFailed& onValidationFailed,
+              std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps)
+  {}
+
+  void
+  checkPolicy(const ndn::Interest& interest,
+              int stepCount,
+              const ndn::OnInterestValidated& onValidated,
+              const ndn::OnInterestValidationFailed& onValidationFailed,
+              std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps)
+  {}
+
+  void
+  signData(ndn::Data& data)
+  {
+    ndn::KeyChain::signByIdentity(data, m_processIdentity);
+  }
+
+  template<typename T> void
+  signByIdentity(T& packet, ndn::Name signeeIdentity)
+  {
+    ndn::KeyChain::signByIdentity(packet, signeeIdentity);
+  }
+
+  ndn::Name
+  createIdentity(const ndn::Name identityName)
+  {
+    return ndn::KeyChain::createIdentity(identityName);
+  }
+
+  ndn::Name
+  createIdentity(const ndn::Name identityName, const ndn::Name signee)
+  {
+    ndn::KeyChain::addIdentity(identityName);
+    ndn::Name keyName;
+    try
+    {
+      keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
+    }
+    catch (InfoError& e)
+    {
+      keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
+    }
+    ndn::shared_ptr<ndn::PublicKey> pubKey;
+    try
+    {
+      pubKey = ndn::KeyChain::getPublicKey(keyName);
+    }
+    catch (InfoError& e)
+    {
+      return identityName;
+    }
+    ndn::Name certName;
+    try
+    {
+      certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
+    }
+    catch (InfoError& e)
+    {
+      ndn::shared_ptr<ndn::IdentityCertificate> certificate =
+        ndn::make_shared<ndn::IdentityCertificate>();
+      ndn::Name certificateName = keyName.getPrefix(-1);
+      certificateName.append("KEY").append(
+        keyName.get(-1)).append("ID-CERT").appendVersion();
+      certificate->setName(certificateName);
+      certificate->setNotBefore(ndn::time::system_clock::now());
+      certificate->setNotAfter(ndn::time::system_clock::now() + ndn::time::days(
+                                 7300) /* 1 year*/);
+      certificate->setPublicKeyInfo(*pubKey);
+      certificate->addSubjectDescription(
+        ndn::CertificateSubjectDescription("2.5.4.41",
+                                           keyName.toUri()));
+      certificate->encode();
+      try
+      {
+        ndn::KeyChain::signByIdentity(*certificate, signee);
+      }
+      catch (InfoError& e)
+      {
+        try
+        {
+          ndn::KeyChain::deleteIdentity(identityName);
+        }
+        catch (InfoError& e)
+        {
+        }
+        return identityName;
+      }
+      certName = certificate->getName();
+    }
+    return certName;
+  }
+
+  void
+  printCertStore()
+  {
+    m_certStore.print();
+  }
+
+private:
+  bool
+  verifyDataPacket(ndn::Data packet)
+  {
+    std::cout << "KeyManager::verifyDataPacket Called" << std::endl;
+    ndn::SignatureSha256WithRsa signature(packet.getSignature());
+    std::string signingCertName = signature.getKeyLocator().getName().toUri();
+    std::string packetName = packet.getName().toUri();
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee =
+      m_certStore.getCertificateFromStore(signingCertName);
+    if (signee.second)
+    {
+      std::string routerNameFromPacketName = getRouterName(packetName);
+      std::string routerNameFromCertName = getRouterName(signingCertName);
+      return ((routerNameFromPacketName == routerNameFromCertName) &&
+              verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+              m_certStore.getCertificateIsVerified(signingCertName));
+    }
+    return false;
+  }
+
+  bool
+  verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet);
+
+public:
+  template<typename T> bool
+  verify(T& packet)
+  {
+    std::cout << "KeyManager::verify Called" << std::endl;
+
+    return verifyDataPacket(packet);
+
+    return false;
+  }
+
+  bool
+  verify(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
+  {
+    return verifyCertPacket(pnlsr, packet);
+  }
+
+  ndn::Name
+  getProcessCertName();
+
+  ndn::Name
+  getRouterCertName();
+
+  ndn::Name
+  getOperatorCertName();
+
+  ndn::Name
+  getSiteCertName();
+
+  ndn::Name
+  getRootCertName();
+
+  uint32_t
+  getCertSeqNo();
+
+  std::pair<uint32_t, bool>
+  getCertificateSeqNum(std::string certName);
+
+  void
+  setCerSeqNo(uint32_t csn);
+
+  void
+  initCertSeqFromFile(std::string certSeqFileDir);
+
+  void
+  writeCertSeqToFile();
+
+  bool
+  isNewCertificate(std::string certName, int checkSeqNum);
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  getCertificateFromStore(const std::string certName, int checkSeqNum);
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  getCertificateFromStore(const std::string certName);
+
+  bool
+  addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert,
+                 uint32_t csn, bool isv);
+
+
+private:
+  bool
+  loadAllCertificates(std::string certDirPath);
+
+  bool
+  loadCertificate(std::string inputFile, nlsrKeyType keyType);
+
+  nlsrKeyType
+  getKeyTypeFromName(const std::string keyName);
+
+  std::string
+  getRouterName(const std::string name);
+
+  std::string
+  getSiteName(const std::string name);
+
+  std::string
+  getRootName(const std::string name);
+
+private:
+  ndn::Name m_processIdentity;
+  ndn::Name m_routerIdentity;
+  ndn::Name m_processCertName;
+  ndn::Name m_routerCertName;
+  ndn::Name m_opCertName;
+  ndn::Name m_siteCertName;
+  ndn::Name m_rootCertName;
+  ndn::Name m_processKeyName;
+  uint32_t m_certSeqNo;
+  std::string m_certSeqFileNameWithPath;
+  std::string m_nlsrRootKeyPrefix;
+  CertificateStore m_certStore;
+
+};
+}//namespace nlsr
+
+#endif //NLSR_KM_HPP
diff --git a/src/security/nlsr_cert_store.cpp b/src/security/nlsr_cert_store.cpp
deleted file mode 100644
index fa84ad9..0000000
--- a/src/security/nlsr_cert_store.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp> 
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include "nlsr_cert_store.hpp"
-#include "nlsr_wle.hpp"
-#include "nlsr_km.hpp"
-
-#define THIS_FILE "nlsr_cert_store.cpp"
-
-namespace nlsr
-{
-  static bool
-  nlsrCertificateStoreEntryCompare(NlsrCertificateStoreEntry& ncse1,
-                                   NlsrCertificateStoreEntry& ncse2)
-
-  {    
-    int sizeDiff=ncse1.getCert()->getName().size()-
-                                              ncse2.getCert()->getName().size();
-    return (ncse2.getCert()->getName().isPrefixOf(ncse1.getCert()->getName()) &&
-                                               (sizeDiff <= 1 && sizeDiff>= 0));
-  
-    
-  }
-
-  static bool
-  nlsrCertificateStoreEntryCompareByName(NlsrCertificateStoreEntry& ncse1,
-                                         std::string compCertName)
-
-  {
-    ndn::Name ccn(compCertName);
-    int sizeDiff= ncse1.getCert()->getName().size() -ccn.size();
-    return ( ccn.isPrefixOf(ncse1.getCert()->getName()) &&
-                                               (sizeDiff <= 1 && sizeDiff>= 0));
-  }
-  
-  void 
-  NlsrCertificateStore::updateWaitingList(std::string respCertName)
-  {
-    ndn::Name tmpName(respCertName);
-    respCertName=tmpName.getPrefix(-1).toUri();
-    std::pair<WaitingListEntry, bool> chkWle=
-                              m_waitingList.getWaitingListEntry(respCertName);
-    if( chkWle.second )
-    {
-      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> sc=
-                                          getCertificateFromStore(respCertName);
-      std::list<std::string> waitees=(chkWle.first).getWaitingCerts();
-      for(std::list<std::string>::iterator it = waitees.begin();
-                                                       it != waitees.end();++it)
-      {
-        KeyManager km;
-        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> wc=
-                                                 getCertificateFromStore(*(it));
-        if( wc.second && sc.second )
-        {
-          if(km.verifySignature(*(wc.first),sc.first->getPublicKeyInfo()))
-          {
-            //1. Update Certificate Store
-            setCertificateIsVerified(*(it),true);
-            //2. Call updateWaitingList for waitee ( *(it) )
-            updateWaitingList(*(it));
-          }
-        }
-      }
-    }
-    
-    //remove that entry from waiting list
-    m_waitingList.remove(respCertName);
-  }
-  
-  void
-  NlsrCertificateStore::updateWaitingList(NlsrCertificateStoreEntry& ncse)
-  {
-    if( ncse.getIsSignerVerified())
-    {
-      updateWaitingList(ncse.getCert()->getName().toUri());
-    }
-    else
-    {
-      ndn::SignatureSha256WithRsa signature(ncse.getCert()->getSignature());
-      m_waitingList.add(signature.getKeyLocator().getName().toUri(), 
-                                             ncse.getCert()->getName().toUri());
-    }
-  }
-
-  bool
-  NlsrCertificateStore::addCertificate(NlsrCertificateStoreEntry & ncse)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompare, _1, ncse));
-    if(it == m_certTable.end())
-    {
-      m_certTable.push_back(ncse);
-      updateWaitingList(ncse);
-      return true;
-    }
-    else if( it !=  m_certTable.end() )
-    {
-      if ( (*it).getCertSeqNum() < ncse.getCertSeqNum() )
-      {
-        m_certTable.erase(it);
-        m_certTable.push_back(ncse);
-        updateWaitingList(ncse);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool
-  NlsrCertificateStore::addCertificate(
-    ndn::shared_ptr<ndn::IdentityCertificate> pcert, uint32_t csn, bool isv)
-  {
-    NlsrCertificateStoreEntry ncse(pcert, csn, isv);
-    return addCertificate(ncse);
-  }
-
-  std::pair<uint32_t, bool>
-  NlsrCertificateStore::getCertificateSeqNum(std::string certName)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it == m_certTable.end())
-    {
-      return std::make_pair(0,false);
-    }
-    return std::make_pair((*it).getCertSeqNum(),true);
-  }
-  
- 
-  
-  void 
-  NlsrCertificateStore::setCertificateIsVerified(std::string certName, 
-                                                                bool isVerified)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it != m_certTable.end())
-    {
-      it->setIsSignerVerified(true);
-    }
-  }
-  
-  bool
-  NlsrCertificateStore::getCertificateIsVerified( std::string certName )
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it != m_certTable.end())
-    {
-      return it->getIsSignerVerified();
-    }
-    
-    return false;
-  }
-
-  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-  NlsrCertificateStore::getCertificateFromStore(const std::string certName)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it == m_certTable.end())
-    {
-      ndn::shared_ptr<ndn::IdentityCertificate> cert=
-                                    ndn::make_shared<ndn::IdentityCertificate>();
-      return std::make_pair(cert,false);
-    }
-    return std::make_pair((*it).getCert(),true);
-  }
-
-  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-  NlsrCertificateStore::getCertificateFromStore(
-    const std::string certName, int checkSeqNum)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it == m_certTable.end())
-    {
-      ndn::shared_ptr<ndn::IdentityCertificate> cert=
-        ndn::make_shared<ndn::IdentityCertificate>();
-      return std::make_pair(cert,false);
-    }
-    else
-    {
-      if( (*it).getCertSeqNum() == checkSeqNum )
-      {
-        return std::make_pair((*it).getCert(),true);
-      }
-    }
-    return std::make_pair((*it).getCert(),false);
-  }
-
-  bool
-  NlsrCertificateStore::isCertificateNewInStore(const std::string certName,
-      int checkSeqNo)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it != m_certTable.end())
-    {
-      return (*it).getCertSeqNum() < checkSeqNo ;
-    }
-    return true;
-  }
-
-  bool
-  NlsrCertificateStore::removeCertificateFromStroe(const std::string certName)
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it =
-      std::find_if( m_certTable.begin(), m_certTable.end(),
-                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-    if(it != m_certTable.end())
-    {
-      m_certTable.erase(it);
-      return true;
-    }
-    return false;
-  }
-
-  void
-  NlsrCertificateStore::print()
-  {
-    std::list<NlsrCertificateStoreEntry>::iterator it;
-    for(it=m_certTable.begin(); it!=m_certTable.end(); ++it)
-    {
-      std::cout<<(*it)<<std::endl;
-    }
-    std::cout<<m_waitingList<<std::endl;
-  }
-}
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
deleted file mode 100644
index 2ef4513..0000000
--- a/src/security/nlsr_cert_store.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef NLSR_CERT_STORE_HPP
-#define NLSR_CERT_STORE_HPP
-
-#include<list>
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include "nlsr_cse.hpp"
-#include "nlsr_wl.hpp"
-
-namespace nlsr
-{
-  class NlsrCertificateStore
-  {
-  public:
-    NlsrCertificateStore()
-        : m_certTable()
-        , m_waitingList()
-    {}
-
-    bool addCertificate(NlsrCertificateStoreEntry& ncse);
-    bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                        , uint32_t csn, bool isv);
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-                            getCertificateFromStore(const std::string certName);
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-           getCertificateFromStore(const std::string certName, int checkSeqNum);
-    bool removeCertificateFromStroe(const std::string certName);
-    bool isCertificateNewInStore(const std::string certName, int checkSeqNo);
-    std::pair<uint32_t, bool> getCertificateSeqNum(std::string certName);
-    void print();
-    void setCertificateIsVerified(std::string certName, bool isVerified);
-    bool getCertificateIsVerified(std::string certName);
-  private:
-    void updateWaitingList(NlsrCertificateStoreEntry& ncse);
-    void updateWaitingList(std::string respCertName);
-    
-  private:
-    std::list<NlsrCertificateStoreEntry> m_certTable;
-    WaitingList m_waitingList;
-  };
-}
-
-#endif
diff --git a/src/security/nlsr_cse.cpp b/src/security/nlsr_cse.cpp
deleted file mode 100644
index 91c0150..0000000
--- a/src/security/nlsr_cse.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-#include "nlsr_cse.hpp"
-
-#define THIS_FILE "nlsr_cse.cpp"
-
-namespace nlsr
-{
-  std::ostream&
-  operator <<(std::ostream& os, const NlsrCertificateStoreEntry& ncse)
-  {
-    os<<"------Certificate Entry---------------"<<std::endl;
-    os<<*(ncse.getCert())<<std::endl;
-    ndn::SignatureSha256WithRsa sig(ncse.getCert()->getSignature());
-    ndn::Name keyName=sig.getKeyLocator().getName();
-    os<<"Signee : "<<keyName.toUri()<<std::endl;
-    os<<"Cert Seq Num: "<<ncse.getCertSeqNum()<<std::endl;
-    os<<"Is Signer Verified: "<<ncse.getIsSignerVerified()<<std::endl;
-    return os;
-  }
-}
diff --git a/src/security/nlsr_cse.hpp b/src/security/nlsr_cse.hpp
deleted file mode 100644
index 238d511..0000000
--- a/src/security/nlsr_cse.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef NLSR_CERT_STORE_ENTRY_HPP
-#define NLSR_CERT_STORE_ENTRY_HPP
-
-#include <iostream>
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-
-namespace nlsr
-{
-  class NlsrCertificateStoreEntry
-  {
-  public:
-    NlsrCertificateStoreEntry()
-      : m_cert(ndn::make_shared<ndn::IdentityCertificate>())
-      , m_certSeqNum(0)
-      , m_isSignerVerified(false)
-    {}
-
-    NlsrCertificateStoreEntry(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                              , uint32_t csn, bool isv)
-      : m_cert(pcert)
-      , m_certSeqNum(csn)
-      , m_isSignerVerified(isv)
-    {}
-
-    ndn::shared_ptr<ndn::IdentityCertificate> getCert() const
-    {
-      return m_cert;
-    }
-
-    void setCert(ndn::shared_ptr<ndn::IdentityCertificate> pcert)
-    {
-      m_cert=pcert;
-    }
-
-    uint32_t getCertSeqNum() const
-    {
-      return m_certSeqNum;
-    }
-
-    void setCertSeqNum(uint32_t csn)
-    {
-      m_certSeqNum=csn;
-    }
-
-    bool getIsSignerVerified() const
-    {
-      return m_isSignerVerified;
-    }
-
-    void setIsSignerVerified(bool isv)
-    {
-      m_isSignerVerified=isv;
-    }
-
-  private:
-    ndn::shared_ptr<ndn::IdentityCertificate> m_cert;
-    uint32_t m_certSeqNum;
-    bool m_isSignerVerified;
-  };
-  /* Debugging Purpose */
-  std::ostream&
-  operator <<(std::ostream& os, const NlsrCertificateStoreEntry& ncse);
-}
-
-#endif
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
deleted file mode 100644
index d357795..0000000
--- a/src/security/nlsr_km.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <ndn-cpp-dev/encoding/block.hpp>
-#include <ndn-cpp-dev/util/io.hpp>
-#include <stdexcept>
-#include "nlsr_sm.hpp"
-#include "nlsr_km.hpp"
-#include "nlsr.hpp"
-
-#define THIS_FILE "nlsr_km.cpp"
-
-namespace nlsr
-{
-  bool
-  KeyManager::initialize(ConfParameter &cp)
-  {
-    initCertSeqFromFile(cp.getSeqFileDir());
-    if( !loadAllCertificates(cp.getCertDir()) )
-    {
-      return false;
-    }
-    m_nlsrRootKeyPrefix=cp.getRootKeyPrefix();
-    string processIdentityName(cp.getRootKeyPrefix());
-    processIdentityName += "/";
-    processIdentityName += cp.getSiteName();
-    processIdentityName += "/";
-    processIdentityName += "R.Start";
-    processIdentityName += "/";
-    processIdentityName += cp.getRouterName();
-    ndn::Name ri(processIdentityName);
-    std::cout<<"Router Identity: "<<ri.toUri()<<std::endl;
-    m_routerIdentity=ri;
-    processIdentityName += "/";
-    processIdentityName += "nlsr";
-    cout<<"Proces Identity Name: "<<processIdentityName<<endl;
-    ndn::Name identityName(processIdentityName);
-    m_processIdentity=identityName;
-    ndn::KeyChain::deleteIdentity(m_processIdentity);
-    m_processCertName = ndn::KeyChain::createIdentity(m_processIdentity);
-    cout<<"Certificate Name: "<<m_processCertName.toUri()<<endl;
-    m_processKeyName=m_processCertName.getPrefix(-2);
-    cout<<"Key Name: "<<m_processKeyName.toUri()<<endl;
-    ndn::shared_ptr<ndn::IdentityCertificate> cert = 
-                                                getCertificate(m_processCertName);
-    signByIdentity(*(cert),m_routerIdentity);
-    m_certStore.addCertificate(cert, m_certSeqNo, true);
-    m_certStore.print();
-    return true;
-  }
-
-  bool
-  KeyManager::loadAllCertificates(std::string certDirPath)
-  {
-    std::string filePath=certDirPath;
-    if(filePath.empty())
-    {
-      SequencingManager sm;
-      filePath=sm.getUserHomeDirectory();
-      filePath+="/nlsrCertDir";
-    }
-    return loadCertificate(filePath+"/root.cert", KEY_TYPE_ROOT)
-           && loadCertificate(filePath+"/site.cert", KEY_TYPE_SITE)
-           && loadCertificate(filePath+"/operator.cert", KEY_TYPE_OPERATOR)
-           && loadCertificate(filePath+"/router.cert", KEY_TYPE_ROUTER) ;
-  }
-
-  bool
-  KeyManager::loadCertificate(std::string inputFile, nlsrKeyType keyType)
-  {
-    try
-    {
-      ndn::shared_ptr<ndn::IdentityCertificate> cert =
-        ndn::io::load<ndn::IdentityCertificate>(inputFile, ndn::io::BASE_64);
-      ndn::Name certName=cert->getName();
-      switch(keyType)
-        {
-        case KEY_TYPE_ROOT:
-          m_certStore.addCertificate(cert, 10, true);
-          m_rootCertName=certName;
-          std::cout<<"Root Cert: "<<m_rootCertName<<std::endl;
-          break;
-        case KEY_TYPE_SITE:
-          m_certStore.addCertificate(cert, 10, true);
-          m_siteCertName=certName;
-          std::cout<<"Site Cert: "<<m_siteCertName<<std::endl;
-          break;
-        case KEY_TYPE_OPERATOR:
-          m_certStore.addCertificate(cert, 10, true);
-          m_opCertName=certName;
-          std::cout<<"Operator Cert: "<<m_opCertName<<std::endl;
-          break;
-        case KEY_TYPE_ROUTER:
-          m_certStore.addCertificate(cert, m_certSeqNo, true);
-          m_routerCertName=certName;
-          std::cout<<"Router Cert: "<<m_routerCertName<<std::endl;
-          break;
-        case KEY_TYPE_PROCESS:
-          m_certStore.addCertificate(cert, m_certSeqNo, true);
-          m_processCertName=certName;
-          std::cout<<"Process Cert: "<<m_processCertName<<std::endl;
-          break;
-        default:
-          break;
-        }
-      return true;
-    }
-    catch(std::exception& e)
-    {
-      return false;
-    }
-    return false;
-  }
-
-  ndn::Name
-  KeyManager::getProcessCertName()
-  {
-    return m_processCertName;
-  }
-
-  ndn::Name
-  KeyManager::getRouterCertName()
-  {
-    return m_routerCertName;
-  }
-
-  ndn::Name
-  KeyManager::getOperatorCertName()
-  {
-    return m_opCertName;
-  }
-
-  ndn::Name
-  KeyManager::getSiteCertName()
-  {
-    return m_siteCertName;
-  }
-
-  ndn::Name
-  KeyManager::getRootCertName()
-  {
-    return m_rootCertName;
-  }
-
-  uint32_t
-  KeyManager::getCertSeqNo()
-  {
-    return m_certSeqNo;
-  }
-
-  void
-  KeyManager::setCerSeqNo(uint32_t csn)
-  {
-    m_certSeqNo=csn;
-  }
-
-  void
-  KeyManager::initCertSeqFromFile(string certSeqFileDir)
-  {
-    m_certSeqFileNameWithPath=certSeqFileDir;
-    if( m_certSeqFileNameWithPath.empty() )
-    {
-      SequencingManager sm;
-      m_certSeqFileNameWithPath=sm.getUserHomeDirectory();
-    }
-    m_certSeqFileNameWithPath += "/nlsrCertSeqNo.txt";
-    cout<<"Key Seq File Name: "<< m_certSeqFileNameWithPath<<endl;
-    std::ifstream inputFile(m_certSeqFileNameWithPath.c_str(),ios::binary);
-    if ( inputFile.good() )
-    {
-      inputFile>>m_certSeqNo;
-      m_certSeqNo++;
-    }
-    else
-    {
-      m_certSeqNo=1;
-    }
-    writeCertSeqToFile();
-  }
-
-  void
-  KeyManager::writeCertSeqToFile()
-  {
-    std::ofstream outputFile(m_certSeqFileNameWithPath.c_str(),ios::binary);
-    outputFile<<m_certSeqNo;
-    outputFile.close();
-  }
-
-  bool
-  KeyManager::isNewCertificate(std::string certName, int checkSeqNum)
-  {
-    return m_certStore.isCertificateNewInStore(certName,checkSeqNum);
-  }
-
-  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-  KeyManager::getCertificateFromStore(const std::string certName, int checkSeqNum)
-  {
-    return m_certStore.getCertificateFromStore(certName, checkSeqNum);
-  }
-
-  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-  KeyManager::getCertificateFromStore(const std::string certName)
-  {
-    return m_certStore.getCertificateFromStore(certName);
-  }
-
-  bool
-  KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                             , uint32_t csn, bool isv)
-  {
-    return m_certStore.addCertificate(pcert, csn, isv);
-  }
-  
-  std::pair<uint32_t, bool> 
-  KeyManager::getCertificateSeqNum(std::string certName)
-  {
-    return m_certStore.getCertificateSeqNum(certName);
-  }
-
-  nlsrKeyType
-  KeyManager::getKeyTypeFromName(const std::string keyName)
-  {
-    nlsrTokenizer nt(keyName,"/");
-    std::string KEY("KEY");
-    std::string opHandle("O.Start");
-    std::string routerHandle("R.Start");
-    std::string processHandle("nlsr");
-    if ( nt.getTokenString(0,nt.getTokenPosition(KEY)-1) == m_nlsrRootKeyPrefix)
-    {
-      return KEY_TYPE_ROOT;
-    }
-    else if ( nt.doesTokenExist(opHandle) )
-    {
-      return KEY_TYPE_OPERATOR;
-    }
-    else if ( nt.doesTokenExist(routerHandle) &&
-              nt.doesTokenExist(processHandle))
-    {
-      return KEY_TYPE_PROCESS;
-    }
-    else if ( nt.doesTokenExist(routerHandle) &&
-              !nt.doesTokenExist(processHandle))
-    {
-      return KEY_TYPE_ROUTER;
-    }
-    else
-    {
-      return KEY_TYPE_SITE;
-    }
-  }
-
-  std::string
-  KeyManager::getRouterName(const std::string name)
-  {
-    std::string routerName;
-    std::string rkp(m_nlsrRootKeyPrefix);
-    nlsrTokenizer ntRkp(rkp,"/");
-    nlsrTokenizer nt(name,"/");
-    std::string KEY("KEY");
-    std::string opHandle("O.Start");
-    std::string routerHandle("R.Start");
-    std::string processHandle("nlsr");
-    std::string infoHandle("info");
-    std::string lsaHandle("LSA");
-    if ( nt.doesTokenExist(processHandle) && nt.doesTokenExist(routerHandle))
-    {
-      routerName="/ndn" +
-                 nt.getTokenString(ntRkp.getTokenNumber(),
-                                   nt.getTokenPosition(routerHandle)-1) +
-                 nt.getTokenString(nt.getTokenPosition(routerHandle)+1,
-                                   nt.getTokenPosition(processHandle)-1);
-    }
-    else if(nt.doesTokenExist(routerHandle) && !nt.doesTokenExist(infoHandle)
-            && !nt.doesTokenExist(lsaHandle))
-    {
-      routerName="/ndn" +
-                 nt.getTokenString(ntRkp.getTokenNumber(),
-                                   nt.getTokenPosition(routerHandle)-1) +
-                 nt.getTokenString(nt.getTokenPosition(routerHandle)+1,
-                                   nt.getTokenPosition(KEY)-1);
-    }
-    else
-    {
-      if (nt.doesTokenExist(infoHandle) )
-      {
-        routerName=nt.getTokenString(0,nt.getTokenPosition(infoHandle)-1);
-      }
-      else
-      {
-        routerName=nt.getTokenString(nt.getTokenPosition(lsaHandle)+1,
-                                     nt.getTokenNumber()-4);
-      }
-    }
-    return routerName;
-  }
-
-  std::string
-  KeyManager::getSiteName(const std::string name)
-  {
-    std::string siteName;
-    std::string routerName;
-    std::string rkp(m_nlsrRootKeyPrefix);
-    nlsrTokenizer ntRkp(rkp,"/");
-    nlsrTokenizer nt(name,"/");
-    std::string KEY("KEY");
-    std::string opHandle("O.Start");
-    std::string routerHandle("R.Start");
-    if ( nt.doesTokenExist(routerHandle) )
-    {
-      siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
-                                          nt.getTokenPosition(routerHandle) -1);
-    }
-    else if ( nt.doesTokenExist(opHandle) )
-    {
-      siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
-                                          nt.getTokenPosition(opHandle) -1);
-    }
-    else
-    {
-      siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
-                                          nt.getTokenPosition(KEY) -1);
-    }
-    return siteName;
-  }
-  
-  std::string 
-  KeyManager::getRootName(const std::string name)
-  {
-    std::string rName;
-    nlsrTokenizer nt(name,"/");
-    std::string rkp(m_nlsrRootKeyPrefix);
-    nlsrTokenizer ntRkp(rkp,"/");
-    rName=nt.getTokenString(0,ntRkp.getTokenNumber()-1);
-    return rName;
-  }
-  
-  
-  bool
-  KeyManager::verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
-    {
-      std::cout<<"KeyManager::verifyCertPacket Called"<<std::endl;
-      ndn::SignatureSha256WithRsa signature(packet.getSignature());
-      std::string signingCertName=signature.getKeyLocator().getName().toUri();
-      std::string packetName=packet.getName().toUri();
-      
-      std::cout<<"Packet Name: "<<packetName<<std::endl;
-      std::cout<<"Signee Name: "<<signingCertName<<std::endl;
-      
-      int paketCertType=getKeyTypeFromName(packetName);
-      int signingCertType=getKeyTypeFromName(signingCertName);
-      
-      if( signingCertType > paketCertType ) //lower level Cert can not sign
-      {                                     //upper level Cert
-        return false;
-      }
-      
-      if((signingCertType == paketCertType) && (paketCertType != KEY_TYPE_ROOT))
-      {
-        return false;
-      }
-      
-      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
-                             m_certStore.getCertificateFromStore(signingCertName);
-      
-      if( signee.second )
-      {
-        switch(paketCertType)
-          {
-          case KEY_TYPE_ROOT:
-            return ((getRootName(packetName) == m_nlsrRootKeyPrefix) &&
-                     verifySignature(packet,signee.first->getPublicKeyInfo()));
-            break;
-          case KEY_TYPE_SITE:
-            return ((getRootName(packetName) == getRootName(signingCertName)) &&
-                      verifySignature(packet,signee.first->getPublicKeyInfo()) &&
-                      m_certStore.getCertificateIsVerified(signingCertName));                   
-            break;
-          case KEY_TYPE_OPERATOR:
-            return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
-                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
-                     m_certStore.getCertificateIsVerified(signingCertName)); 
-            break;
-          case KEY_TYPE_ROUTER:
-            return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
-                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
-                     m_certStore.getCertificateIsVerified(signingCertName));
-            break;
-          case KEY_TYPE_PROCESS:
-            return ((getRouterName(packetName) == getRouterName(signingCertName)) &&
-                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
-                     m_certStore.getCertificateIsVerified(signingCertName));
-            break;
-          }
-      }
-      else
-      {
-        std::cout<<"Certificate Not Found in store. Sending Interest"<<std::endl;
-        pnlsr.getIm().expressInterest(pnlsr, signingCertName, 3,
-                              pnlsr.getConfParameter().getInterestResendTime());
-        return false;
-      }
-      return false;
-    }
-}
-
-
-
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
deleted file mode 100644
index 291d55c..0000000
--- a/src/security/nlsr_km.hpp
+++ /dev/null
@@ -1,249 +0,0 @@
-#ifndef NLSR_KM_HPP
-#define NLSR_KM_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/data.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/security/validator.hpp>
-#include <ndn-cpp-dev/util/random.hpp>
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <list>
-#include "nlsr_conf_param.hpp"
-#include "nlsr_cert_store.hpp"
-#include "utility/nlsr_tokenizer.hpp"
-
-namespace nlsr
-{
-  class Nlsr;
-  enum nlsrKeyType
-  {
-    KEY_TYPE_ROOT,
-    KEY_TYPE_SITE,
-    KEY_TYPE_OPERATOR,
-    KEY_TYPE_ROUTER,
-    KEY_TYPE_PROCESS,
-    KEY_TYPE_UNKNOWN
-  };
-
-  enum nlsrContentType
-  {
-    CONTENT_TYPE_DATA,
-    CONTENT_TYPE_CERT
-  };
-
-  class KeyManager: public ndn::KeyChain, public ndn::Validator
-  {
-    typedef SecPublicInfo::Error InfoError;
-    typedef SecTpm::Error TpmError;
-  public:
-    KeyManager()
-      : m_certSeqNo(1)
-      , m_certStore()
-      , m_nlsrRootKeyPrefix()
-    {
-    }
-
-    bool initialize(ConfParameter &cp);
-
-
-
-    void
-    checkPolicy (const ndn::Data& data,
-                 int stepCount,
-                 const ndn::OnDataValidated& onValidated,
-                 const ndn::OnDataValidationFailed& onValidationFailed,
-                 std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps)
-    {}
-
-    void
-    checkPolicy (const ndn::Interest& interest,
-                 int stepCount,
-                 const ndn::OnInterestValidated& onValidated,
-                 const ndn::OnInterestValidationFailed& onValidationFailed,
-                 std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps)
-    {}
-
-    void signData(ndn::Data& data)
-    {
-      ndn::KeyChain::signByIdentity(data,m_processIdentity);
-    }
-
-    template<typename T>
-    void signByIdentity(T& packet, ndn::Name signeeIdentity)
-    {
-      ndn::KeyChain::signByIdentity(packet,signeeIdentity);
-    }
-
-    ndn::shared_ptr<ndn::IdentityCertificate>
-    getCertificate(ndn::Name certificateName)
-    {
-      return ndn::KeyChain::getCertificate(certificateName);
-    }
-
-    ndn::shared_ptr<ndn::IdentityCertificate>
-    getCertificate()
-    {
-      return getCertificate(m_processCertName);
-    }
-
-    ndn::Name
-    createIdentity(const ndn::Name identityName)
-    {
-      return ndn::KeyChain::createIdentity(identityName);
-    }
-
-    ndn::Name
-    createIdentity(const ndn::Name identityName, const ndn::Name signee)
-    {
-      ndn::KeyChain::addIdentity(identityName);
-      ndn::Name keyName;
-      try
-      {
-        keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
-      }
-      catch(InfoError& e)
-      {
-        keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
-      }
-      ndn::shared_ptr<ndn::PublicKey> pubKey;
-      try
-      {
-        pubKey = ndn::KeyChain::getPublicKey(keyName);
-      }
-      catch(InfoError& e)
-      {
-        return identityName;
-      }
-      ndn::Name certName;
-      try
-      {
-        certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
-      }
-      catch(InfoError& e)
-      {
-        ndn::shared_ptr<ndn::IdentityCertificate> certificate =
-          ndn::make_shared<ndn::IdentityCertificate>();
-        ndn::Name certificateName = keyName.getPrefix(-1);
-        certificateName.append("KEY").append(
-          keyName.get(-1)).append("ID-CERT").appendVersion();
-        certificate->setName(certificateName);
-        certificate->setNotBefore(ndn::time::system_clock::now());
-        certificate->setNotAfter(ndn::time::system_clock::now() + ndn::time::days(7300) /* 1 year*/);
-        certificate->setPublicKeyInfo(*pubKey);
-        certificate->addSubjectDescription(
-          ndn::CertificateSubjectDescription("2.5.4.41",
-                                             keyName.toUri()));
-        certificate->encode();
-        try
-        {
-          ndn::KeyChain::signByIdentity(*certificate,signee);
-        }
-        catch(InfoError& e)
-        {
-          try
-          {
-            ndn::KeyChain::deleteIdentity(identityName);
-          }
-          catch(InfoError& e)
-          {
-          }
-          return identityName;
-        }
-        certName=certificate->getName();
-      }
-      return certName;
-    }
-
-    void printCertStore()
-    {
-      m_certStore.print();
-    }
-
-  private:
-    bool
-    verifyDataPacket(ndn::Data packet)
-    {
-      std::cout<<"KeyManager::verifyDataPacket Called"<<std::endl;
-      ndn::SignatureSha256WithRsa signature(packet.getSignature());
-      std::string signingCertName=signature.getKeyLocator().getName().toUri();
-      std::string packetName=packet.getName().toUri();
-      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
-        m_certStore.getCertificateFromStore(signingCertName);
-      if( signee.second )
-      {
-        std::string routerNameFromPacketName=getRouterName(packetName);
-        std::string routerNameFromCertName=getRouterName(signingCertName);
-        return ( (routerNameFromPacketName== routerNameFromCertName) &&
-                 verifySignature(packet, signee.first->getPublicKeyInfo()) &&
-                 m_certStore.getCertificateIsVerified(signingCertName));
-      }
-      return false;
-    }
-
-    bool
-    verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet);
-
-  public:
-    template<typename T>
-    bool
-    verify(T& packet )
-    {
-      std::cout<<"KeyManager::verify Called"<<std::endl;
-      
-      return verifyDataPacket(packet);
-      
-      return false;
-    }
-    
-    bool
-    verify(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
-    {
-      return verifyCertPacket(pnlsr, packet);
-    }
-
-    ndn::Name getProcessCertName();
-    ndn::Name getRouterCertName();
-    ndn::Name getOperatorCertName();
-    ndn::Name getSiteCertName();
-    ndn::Name getRootCertName();
-
-    uint32_t getCertSeqNo();
-    std::pair<uint32_t, bool> getCertificateSeqNum(std::string certName);
-    void setCerSeqNo(uint32_t csn);
-    void initCertSeqFromFile(string certSeqFileDir);
-    void writeCertSeqToFile();
-    bool isNewCertificate(std::string certName, int checkSeqNum);
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    getCertificateFromStore(const std::string certName, int checkSeqNum);
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    getCertificateFromStore(const std::string certName);
-    bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                        , uint32_t csn, bool isv);
-
-
-  private:
-    bool loadAllCertificates(std::string certDirPath);
-    bool loadCertificate(std::string inputFile, nlsrKeyType keyType);
-    nlsrKeyType getKeyTypeFromName(const std::string keyName);
-    std::string getRouterName(const std::string name);
-    std::string getSiteName(const std::string name);
-    std::string getRootName(const std::string name);
-
-  private:
-    ndn::Name m_processIdentity;
-    ndn::Name m_routerIdentity;
-    ndn::Name m_processCertName;
-    ndn::Name m_routerCertName;
-    ndn::Name m_opCertName;
-    ndn::Name m_siteCertName;
-    ndn::Name m_rootCertName;
-    ndn::Name m_processKeyName;
-    uint32_t m_certSeqNo;
-    string m_certSeqFileNameWithPath;
-    string m_nlsrRootKeyPrefix;
-    NlsrCertificateStore m_certStore;
-
-  };
-}
-
-#endif
diff --git a/src/security/nlsr_wl.cpp b/src/security/nlsr_wl.cpp
deleted file mode 100644
index 442afe3..0000000
--- a/src/security/nlsr_wl.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <ndn-cpp-dev/face.hpp>
-#include "nlsr_wl.hpp"
-
-#define THIS_FILE "nlsr_wl.cpp"
-
-namespace nlsr
-{
-  static bool
-  waitingListCompare(const WaitingListEntry& w1, const std::string& respCert)
-  {
-    return w1.getResponsibleCert() == respCert;
-  }
-  
-  std::pair<WaitingListEntry, bool> 
-  WaitingList::getWaitingListEntry(std::string respCert)
-  {
-    std::list<WaitingListEntry>::iterator it = std::find_if( m_waitingTable.begin(),
-                m_waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
-    if( it != m_waitingTable.end() )
-    {
-      return std::make_pair(*(it),true);
-    }
-    
-    WaitingListEntry wle;
-    return std::make_pair(wle,false);
-    
-  }
-  
-  bool 
-  WaitingList::add(std::string respCert, std::string waitee)
-  {
-    std::list<WaitingListEntry>::iterator it = std::find_if( m_waitingTable.begin(),
-                m_waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
-    if( it == m_waitingTable.end() )
-    {
-      WaitingListEntry newWle(respCert);
-      newWle.addWaitee(waitee);
-      m_waitingTable.push_back(newWle);
-      return true;
-    }
-    else
-    {
-      return it->addWaitee(waitee);
-    }
-    return false;
-  }
-  
-  bool 
-  WaitingList::remove(std::string respCert)
-  {
-    std::list<WaitingListEntry>::iterator it = std::find_if( m_waitingTable.begin(),
-                m_waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
-    if( it == m_waitingTable.end() )
-    {
-      return false;
-    }
-    else
-    {
-      m_waitingTable.erase(it);
-      return true;
-    }
-    return false;
-  }
-  
-  std::ostream& 
-  operator<<(std::ostream& os, WaitingList wl)
-  {
-    os<<"-------Waiting List--------"<<std::endl;
-    std::list<WaitingListEntry> wles=wl.getWaitingTable();
-    for( std::list<WaitingListEntry> ::iterator it=wles.begin(); 
-                                                        it != wles.end(); ++it)
-    {
-      os<<*(it)<<std::endl;
-    }
-    return os;
-  }
-}
diff --git a/src/security/nlsr_wl.hpp b/src/security/nlsr_wl.hpp
deleted file mode 100644
index 1a752ca..0000000
--- a/src/security/nlsr_wl.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef NLSR_WL_HPP
-#define NLSR_WL_HPP
-
-#include "nlsr_wle.hpp"
-
-namespace nlsr
-{
-  class WaitingList
-  {
-    public:
-      WaitingList()
-        : m_waitingTable()
-      {}
-      
-      std::list<WaitingListEntry>& getWaitingTable()
-      {
-        return m_waitingTable;
-      }
-      
-      bool add(std::string respCert, std::string waitee);
-      std::pair<WaitingListEntry, bool> getWaitingListEntry(std::string respCert);
-      bool remove(std::string respCert);
-      
-    private:
-      std::list<WaitingListEntry> m_waitingTable;
-  };
-  
-  std::ostream& operator<<(std::ostream& os, WaitingList wl);
-}
-
-#endif
diff --git a/src/security/nlsr_wle.cpp b/src/security/nlsr_wle.cpp
deleted file mode 100644
index 37caf6d..0000000
--- a/src/security/nlsr_wle.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <iostream>
-#include <list>
-#include <ndn-cpp-dev/face.hpp>
-#include "nlsr_wle.hpp"
-
-#define THIS_FILE "nlsr_wle.cpp"
-
-namespace nlsr
-{
-  static bool
-  waiteeCompare(std::string& w1, std::string& w2)
-  {
-    return w1 == w2 ;
-  }
-  
-  bool
-  WaitingListEntry::addWaitee(std::string waiteeName)
-  {
-    std::list<std::string>::iterator it = std::find_if( m_waitingCerts.begin(),
-                m_waitingCerts.end(),ndn::bind(&waiteeCompare, _1, waiteeName));
-    if( it == m_waitingCerts.end() )
-    {
-      m_waitingCerts.push_back(waiteeName);
-      return true;
-    }
-    
-    return false;
-  }
-
-  std::ostream& 
-  operator<<(std::ostream& os, const WaitingListEntry& we)
-  {
-    os<<"-------------Wiating List Entry-------------"<<std::endl;
-    os<<"Responsible Certificate: "<<we.getResponsibleCert()<<std::endl;
-    std::list<std::string> waitee=we.getWaitingCerts();
-    int i=1;
-    for(std::list<std::string>::iterator it=waitee.begin(); 
-                                             it!=waitee.end(); ++i, ++it)
-    {
-      os<<"Waite "<<i<<": "<<*(it)<<std::endl;
-    }
-    return os;
-  }
-}
diff --git a/src/security/nlsr_wle.hpp b/src/security/nlsr_wle.hpp
deleted file mode 100644
index 0647382..0000000
--- a/src/security/nlsr_wle.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef NLSR_WLE_HPP
-#define NLSR_WLE_HPP
-
-#include <list>
-#include <iostream>
-
-namespace nlsr
-{
-  class WaitingListEntry
-  {
-    public:
-      WaitingListEntry()
-        : m_responsibleCert()
-        , m_waitingCerts()
-      {}
-      
-      WaitingListEntry(std::string resCert)
-        : m_responsibleCert(resCert)
-        , m_waitingCerts()
-      {}
-      
-      std::string getResponsibleCert() const
-      {
-        return m_responsibleCert;
-      }
-      
-      void setResponsibleCert(std::string resCert)
-      {
-        m_responsibleCert=resCert;
-      }
-      
-      std::list<std::string> getWaitingCerts() const
-      {
-        return m_waitingCerts;
-      }
-      
-      bool addWaitee(std::string waiteeName);
-      
-    private:
-      std::string m_responsibleCert;
-      std::list<std::string> m_waitingCerts;
-  };
-  
-  std::ostream& operator<<(std::ostream& os, const WaitingListEntry& we);
-} //end name space
-
-#endif
diff --git a/src/security/waiting-list-entry.cpp b/src/security/waiting-list-entry.cpp
new file mode 100644
index 0000000..1172698
--- /dev/null
+++ b/src/security/waiting-list-entry.cpp
@@ -0,0 +1,41 @@
+#include <iostream>
+#include <list>
+#include <ndn-cpp-dev/face.hpp>
+#include "waiting-list-entry.hpp"
+
+namespace nlsr {
+static bool
+waiteeCompare(std::string& w1, std::string& w2)
+{
+  return w1 == w2 ;
+}
+
+bool
+WaitingListEntry::addWaitee(std::string waiteeName)
+{
+  std::list<std::string>::iterator it = std::find_if(m_waitingCerts.begin(),
+                                                     m_waitingCerts.end(), ndn::bind(&waiteeCompare, _1, waiteeName));
+  if (it == m_waitingCerts.end())
+  {
+    m_waitingCerts.push_back(waiteeName);
+    return true;
+  }
+
+  return false;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const WaitingListEntry& we)
+{
+  os << "-------------Wiating List Entry-------------" << std::endl;
+  os << "Responsible Certificate: " << we.getResponsibleCert() << std::endl;
+  std::list<std::string> waitee = we.getWaitingCerts();
+  int i = 1;
+  for (std::list<std::string>::iterator it = waitee.begin();
+       it != waitee.end(); ++i, ++it)
+  {
+    os << "Waite " << i << ": " << *(it) << std::endl;
+  }
+  return os;
+}
+}//namespace nlsr
diff --git a/src/security/waiting-list-entry.hpp b/src/security/waiting-list-entry.hpp
new file mode 100644
index 0000000..66b0a95
--- /dev/null
+++ b/src/security/waiting-list-entry.hpp
@@ -0,0 +1,51 @@
+#ifndef NLSR_WLE_HPP
+#define NLSR_WLE_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr {
+class WaitingListEntry
+{
+public:
+  WaitingListEntry()
+    : m_responsibleCert()
+    , m_waitingCerts()
+  {}
+
+  WaitingListEntry(std::string resCert)
+    : m_responsibleCert(resCert)
+    , m_waitingCerts()
+  {}
+
+  std::string
+  getResponsibleCert() const
+  {
+    return m_responsibleCert;
+  }
+
+  void
+  setResponsibleCert(std::string resCert)
+  {
+    m_responsibleCert = resCert;
+  }
+
+  std::list<std::string>
+  getWaitingCerts() const
+  {
+    return m_waitingCerts;
+  }
+
+  bool
+  addWaitee(std::string waiteeName);
+
+private:
+  std::string m_responsibleCert;
+  std::list<std::string> m_waitingCerts;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const WaitingListEntry& we);
+} //end name space
+
+#endif //NLSR_WLE_HPP
diff --git a/src/security/waiting-list.cpp b/src/security/waiting-list.cpp
new file mode 100644
index 0000000..dbf9b68
--- /dev/null
+++ b/src/security/waiting-list.cpp
@@ -0,0 +1,74 @@
+#include <ndn-cpp-dev/face.hpp>
+#include "waiting-list.hpp"
+
+namespace nlsr {
+static bool
+waitingListCompare(const WaitingListEntry& w1, const std::string& respCert)
+{
+  return w1.getResponsibleCert() == respCert;
+}
+
+std::pair<WaitingListEntry, bool>
+WaitingList::getWaitingListEntry(std::string respCert)
+{
+  std::list<WaitingListEntry>::iterator it = std::find_if(m_waitingTable.begin(),
+                                                          m_waitingTable.end(), ndn::bind(&waitingListCompare, _1, respCert));
+  if (it != m_waitingTable.end())
+  {
+    return std::make_pair(*(it), true);
+  }
+
+  WaitingListEntry wle;
+  return std::make_pair(wle, false);
+
+}
+
+bool
+WaitingList::add(std::string respCert, std::string waitee)
+{
+  std::list<WaitingListEntry>::iterator it = std::find_if(m_waitingTable.begin(),
+                                                          m_waitingTable.end(), ndn::bind(&waitingListCompare, _1, respCert));
+  if (it == m_waitingTable.end())
+  {
+    WaitingListEntry newWle(respCert);
+    newWle.addWaitee(waitee);
+    m_waitingTable.push_back(newWle);
+    return true;
+  }
+  else
+  {
+    return it->addWaitee(waitee);
+  }
+  return false;
+}
+
+bool
+WaitingList::remove(std::string respCert)
+{
+  std::list<WaitingListEntry>::iterator it = std::find_if(m_waitingTable.begin(),
+                                                          m_waitingTable.end(), ndn::bind(&waitingListCompare, _1, respCert));
+  if (it == m_waitingTable.end())
+  {
+    return false;
+  }
+  else
+  {
+    m_waitingTable.erase(it);
+    return true;
+  }
+  return false;
+}
+
+std::ostream&
+operator<<(std::ostream& os, WaitingList wl)
+{
+  os << "-------Waiting List--------" << std::endl;
+  std::list<WaitingListEntry> wles = wl.getWaitingTable();
+  for (std::list<WaitingListEntry> ::iterator it = wles.begin();
+       it != wles.end(); ++it)
+  {
+    os << *(it) << std::endl;
+  }
+  return os;
+}
+}//namespace nlsr
diff --git a/src/security/waiting-list.hpp b/src/security/waiting-list.hpp
new file mode 100644
index 0000000..d7e89ce
--- /dev/null
+++ b/src/security/waiting-list.hpp
@@ -0,0 +1,38 @@
+#ifndef NLSR_WL_HPP
+#define NLSR_WL_HPP
+
+#include "waiting-list-entry.hpp"
+
+namespace nlsr {
+class WaitingList
+{
+public:
+  WaitingList()
+    : m_waitingTable()
+  {}
+
+  std::list<WaitingListEntry>&
+  getWaitingTable()
+  {
+    return m_waitingTable;
+  }
+
+  bool
+  add(std::string respCert, std::string waitee);
+
+  std::pair<WaitingListEntry, bool>
+  getWaitingListEntry(std::string respCert);
+
+  bool
+  remove(std::string respCert);
+
+private:
+  std::list<WaitingListEntry> m_waitingTable;
+};
+
+std::ostream&
+operator<<(std::ostream& os, WaitingList wl);
+
+}//namespace nlsr
+
+#endif //NLSR_WL_HPP
diff --git a/src/sequencing-manager.cpp b/src/sequencing-manager.cpp
new file mode 100644
index 0000000..9a5ec89
--- /dev/null
+++ b/src/sequencing-manager.cpp
@@ -0,0 +1,96 @@
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <pwd.h>
+#include <cstdlib>
+#include <unistd.h>
+
+#include "sequencing-manager.hpp"
+
+namespace nlsr {
+
+using namespace std;
+
+void
+SequencingManager::splittSequenceNo(uint64_t seqNo)
+{
+  m_combinedSeqNo = seqNo;
+  m_adjLsaSeq = (m_combinedSeqNo & 0xFFFFF);
+  m_corLsaSeq = ((m_combinedSeqNo >> 20) & 0xFFFFF);
+  m_nameLsaSeq = ((m_combinedSeqNo >> 40) & 0xFFFFF);
+}
+
+void
+SequencingManager::combineSequenceNo()
+{
+  m_combinedSeqNo = 0;
+  m_combinedSeqNo = m_combinedSeqNo | m_adjLsaSeq;
+  m_combinedSeqNo = m_combinedSeqNo | (m_corLsaSeq << 20);
+  m_combinedSeqNo = m_combinedSeqNo | (m_nameLsaSeq << 40);
+}
+
+void
+SequencingManager::writeSeqNoToFile()
+{
+  std::ofstream outputFile(m_seqFileNameWithPath.c_str(), ios::binary);
+  outputFile << m_combinedSeqNo;
+  outputFile.close();
+}
+
+void
+SequencingManager::initiateSeqNoFromFile()
+{
+  cout << "Seq File Name: " << m_seqFileNameWithPath << endl;
+  std::ifstream inputFile(m_seqFileNameWithPath.c_str(), ios::binary);
+  if (inputFile.good())
+  {
+    inputFile >> m_combinedSeqNo;
+    splittSequenceNo(m_combinedSeqNo);
+    m_adjLsaSeq += 10;
+    m_corLsaSeq += 10;
+    m_nameLsaSeq += 10;
+    combineSequenceNo();
+    inputFile.close();
+  }
+  else
+  {
+    splittSequenceNo(0);
+  }
+}
+
+void
+SequencingManager::setSeqFileName(string filePath)
+{
+  m_seqFileNameWithPath = filePath;
+  if (m_seqFileNameWithPath.empty())
+  {
+    m_seqFileNameWithPath = getUserHomeDirectory();
+  }
+  m_seqFileNameWithPath = m_seqFileNameWithPath + "/nlsrSeqNo.txt";
+}
+
+string
+SequencingManager::getUserHomeDirectory()
+{
+  string homeDirPath(getpwuid(getuid())->pw_dir);
+  if (homeDirPath.empty())
+  {
+    homeDirPath = getenv("HOME");
+  }
+  return homeDirPath;
+}
+
+ostream&
+operator<<(ostream& os, const SequencingManager& sm)
+{
+  std::cout << "----SequencingManager----" << std::endl;
+  std::cout << "Adj LSA seq no: " << sm.getAdjLsaSeq() << endl;
+  std::cout << "Cor LSA Seq no: " << sm.getCorLsaSeq() << endl;
+  std::cout << "Name LSA Seq no: " << sm.getNameLsaSeq() << endl;
+  std::cout << "Combined LSDB Seq no: " << sm.getCombinedSeqNo() << endl;
+  return os;
+}
+
+}//namespace nlsr
+
+
diff --git a/src/sequencing-manager.hpp b/src/sequencing-manager.hpp
new file mode 100644
index 0000000..32863a3
--- /dev/null
+++ b/src/sequencing-manager.hpp
@@ -0,0 +1,112 @@
+#ifndef NLSR_SM_HPP
+#define NLSR_SM_HPP
+
+#include <list>
+#include <string>
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr {
+class SequencingManager
+{
+public:
+  SequencingManager()
+    : m_nameLsaSeq(0)
+    , m_adjLsaSeq(0)
+    , m_corLsaSeq(0)
+    , m_combinedSeqNo(0)
+    , m_seqFileNameWithPath()
+  {
+  }
+
+  SequencingManager(uint64_t seqNo)
+  {
+    splittSequenceNo(seqNo);
+  }
+
+  SequencingManager(uint64_t nlsn, uint64_t alsn, uint64_t clsn)
+  {
+    m_nameLsaSeq = nlsn;
+    m_adjLsaSeq  = alsn;
+    m_corLsaSeq  = clsn;
+    combineSequenceNo();
+  }
+
+  uint64_t
+  getNameLsaSeq() const
+  {
+    return m_nameLsaSeq;
+  }
+
+  void
+  setNameLsaSeq(uint64_t nlsn)
+  {
+    m_nameLsaSeq = nlsn;
+    combineSequenceNo();
+  }
+
+  uint64_t
+  getAdjLsaSeq() const
+  {
+    return m_adjLsaSeq;
+  }
+
+  void
+  setAdjLsaSeq(uint64_t alsn)
+  {
+    m_adjLsaSeq = alsn;
+    combineSequenceNo();
+  }
+
+  uint64_t
+  getCorLsaSeq() const
+  {
+    return m_corLsaSeq;
+  }
+
+  void
+  setCorLsaSeq(uint64_t clsn)
+  {
+    m_corLsaSeq = clsn;
+    combineSequenceNo();
+  }
+
+  uint64_t
+  getCombinedSeqNo() const
+  {
+    return m_combinedSeqNo;
+  }
+
+  void
+  writeSeqNoToFile();
+
+  void
+  initiateSeqNoFromFile();
+
+  void
+  setSeqFileName(std::string filePath);
+
+  std::string
+  getUserHomeDirectory();
+
+private:
+  void
+  splittSequenceNo(uint64_t seqNo);
+
+  void
+  combineSequenceNo();
+
+
+private:
+  uint64_t m_nameLsaSeq;
+  uint64_t m_adjLsaSeq;
+  uint64_t m_corLsaSeq;
+  uint64_t m_combinedSeqNo;
+  std::string m_seqFileNameWithPath;
+};
+
+
+std::ostream&
+operator<<(std::ostream& os, const SequencingManager& sm);
+
+}//namespace nlsr
+#endif //NLSR_SM_HPP
diff --git a/src/utility/logger.cpp b/src/utility/logger.cpp
new file mode 100644
index 0000000..3d9a804
--- /dev/null
+++ b/src/utility/logger.cpp
@@ -0,0 +1,59 @@
+#include "logger.hpp"
+
+namespace nlsr {
+
+string
+Logger::getEpochTime()
+{
+  std::stringstream ss;
+  boost::posix_time::ptime time_t_epoch(boost::gregorian::date(1970, 1, 1));
+  boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
+  boost::posix_time::time_duration diff = now - time_t_epoch;
+  ss << diff.total_seconds() << "." << boost::format("%06i") %
+     (diff.total_microseconds()
+      % 1000000);
+  return ss.str();
+}
+
+string
+Logger::getUserHomeDirectory()
+{
+  string homeDirPath(getpwuid(getuid())->pw_dir);
+  if (homeDirPath.empty())
+  {
+    homeDirPath = getenv("HOME");
+  }
+  return homeDirPath;
+}
+
+void
+Logger::initialize(std::string dirPath)
+{
+  string logDirPath(dirPath);
+  if (dirPath.empty())
+  {
+    logDirPath = getUserHomeDirectory() + "/nlsrLog";
+  }
+  cout << "Log Dir Path: " << logDirPath << endl;
+  typedef sinks::synchronous_sink<sinks::text_file_backend> file_sink;
+  shared_ptr<file_sink> sink(new file_sink(
+                               keywords::file_name = logDirPath
+                                                     + "/NLSR%Y%m%d%H%M%S_%3N.log",
+                               keywords::rotation_size = 16 * 1024 * 1024,
+                               keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0),
+                               keywords::auto_flush = true
+                             ));
+  sink->locked_backend()->set_file_collector(sinks::file::make_collector(
+                                               keywords::target = logDirPath,
+                                               //keywords::max_size =  512 * 1024 * 1024,
+                                               keywords::min_free_space = 64 * 1024 * 1024
+                                             ));
+  sink->set_formatter(
+    expr::format("%1% %2%")
+    % getEpochTime()
+    % expr::smessage
+  );
+  logging::core::get()->add_sink(sink);
+}
+
+}//namespace nlsr
diff --git a/src/utility/logger.hpp b/src/utility/logger.hpp
new file mode 100644
index 0000000..97b8df4
--- /dev/null
+++ b/src/utility/logger.hpp
@@ -0,0 +1,64 @@
+#ifndef NLSR_LOGGER_HPP
+#define NLSR_LOGGER_HPP
+
+#define BOOST_LOG_DYN_LINK 1
+#include "boost-log.hpp"
+
+#include <stdexcept>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <pwd.h>
+#include <cstdlib>
+#include <string>
+#include <unistd.h>
+#include <boost/format.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/local_time/local_time.hpp>
+
+
+
+
+namespace nlsr {
+
+namespace logging = boost::log;
+namespace attrs = boost::log::attributes;
+namespace src = boost::log::sources;
+namespace sinks = boost::log::sinks;
+namespace expr = boost::log::expressions;
+namespace keywords = boost::log::keywords;
+
+using boost::shared_ptr;
+using namespace std;
+
+
+class Logger
+{
+public:
+  Logger()
+  {
+  }
+
+  void
+  initialize(std::string dirPath);
+
+  src::logger&
+  getLogger()
+  {
+    return m_Logger;
+  }
+
+private:
+  string
+  getEpochTime();
+
+  string
+  getUserHomeDirectory();
+
+private:
+  src::logger m_Logger;
+};
+
+}//namespace nlsr
+#endif //NLSR_LOGGER_HPP
diff --git a/src/utility/nlsr_logger.cpp b/src/utility/nlsr_logger.cpp
deleted file mode 100644
index f214c6a..0000000
--- a/src/utility/nlsr_logger.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "nlsr_logger.hpp"
-
-namespace nlsr
-{
-
-  string
-  NlsrLogger::getEpochTime()
-  {
-    std::stringstream ss;
-    boost::posix_time::ptime time_t_epoch(boost::gregorian::date(1970,1,1));
-    boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
-    boost::posix_time::time_duration diff = now - time_t_epoch;
-    ss<<diff.total_seconds()<<"."<<boost::format("%06i")%(diff.total_microseconds()
-        %1000000);
-    return ss.str();
-  }
-
-  string
-  NlsrLogger::getUserHomeDirectory()
-  {
-    string homeDirPath(getpwuid(getuid())->pw_dir);
-    if( homeDirPath.empty() )
-    {
-      homeDirPath = getenv("HOME");
-    }
-    return homeDirPath;
-  }
-
-  void
-  NlsrLogger::initNlsrLogger(std::string dirPath)
-  {
-    string logDirPath(dirPath);
-    if( dirPath.empty() )
-    {
-      logDirPath=getUserHomeDirectory()+"/nlsrLog";
-    }
-    cout<<"Log Dir Path: "<< logDirPath<<endl;
-    typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
-    shared_ptr< file_sink > sink(new file_sink(
-                                   keywords::file_name = logDirPath
-                                       +"/NLSR%Y%m%d%H%M%S_%3N.log",
-                                   keywords::rotation_size = 16 * 1024 * 1024,
-                                   keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0),
-                                   keywords::auto_flush = true
-                                 ));
-    sink->locked_backend()->set_file_collector(sinks::file::make_collector(
-          keywords::target = logDirPath,
-          //keywords::max_size =  512 * 1024 * 1024,
-          keywords::min_free_space = 64 * 1024 * 1024
-        ));
-    sink->set_formatter(
-      expr::format("%1% %2%")
-      % getEpochTime()
-      % expr::smessage
-    );
-    logging::core::get()->add_sink(sink);
-  }
-
-}//namespace nlsr
diff --git a/src/utility/nlsr_logger.hpp b/src/utility/nlsr_logger.hpp
deleted file mode 100644
index ca6be3e..0000000
--- a/src/utility/nlsr_logger.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef NLSR_LOGGER_HPP
-#define NLSR_LOGGER_HPP
-
-#define BOOST_LOG_DYN_LINK 1
-#include "boost-log.hpp"
-
-#include <stdexcept>
-#include <string>
-#include <iostream>
-#include <sstream>
-#include <pwd.h>
-#include <cstdlib>
-#include <string>
-#include <unistd.h>
-#include <boost/format.hpp>
-#include <boost/smart_ptr/shared_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/local_time/local_time.hpp>
-
-
-
-
-namespace nlsr
-{
-
-  namespace logging = boost::log;
-  namespace attrs = boost::log::attributes;
-  namespace src = boost::log::sources;
-  namespace sinks = boost::log::sinks;
-  namespace expr = boost::log::expressions;
-  namespace keywords = boost::log::keywords;
-
-  using boost::shared_ptr;
-  using namespace std;
-
-
-  class NlsrLogger
-  {
-  public:
-    NlsrLogger()
-    {
-    }
-
-    void initNlsrLogger(std::string dirPath);
-
-    src::logger& getLogger()
-    {
-      return mLogger;
-    }
-
-  private:
-    string getEpochTime();
-    string getUserHomeDirectory();
-
-  private:
-    src::logger mLogger;
-  };
-
-}//namespace nlsr
-#endif
diff --git a/src/utility/nlsr_tokenizer.cpp b/src/utility/nlsr_tokenizer.cpp
deleted file mode 100644
index a1ed2bd..0000000
--- a/src/utility/nlsr_tokenizer.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include <iostream>
-#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <string>
-#include <algorithm>
-
-#include "nlsr_tokenizer.hpp"
-
-namespace nlsr
-{
-
-  using namespace std;
-  using namespace boost;
-
-  void
-  nlsrTokenizer::makeToken()
-  {
-    char_separator<char> sep(m_seps.c_str());
-    tokenizer< char_separator<char> >tokens(m_originalString, sep);
-    tokenizer< char_separator<char> >::iterator tok_iter = tokens.begin();
-    for ( ; tok_iter != tokens.end(); ++tok_iter)
-    {
-      string oneToken(*tok_iter);
-      trim(oneToken);
-      if(!oneToken.empty())
-      {
-        insertToken(oneToken);
-      }
-    }
-    m_firstToken=m_vTokenList[0];
-    makeRestOfTheLine();
-  }
-
-  void
-  nlsrTokenizer::insertToken(const string& token)
-  {
-    m_tokenList.push_back(token);
-    m_vTokenList.push_back(token);
-  }
-
-  int
-  nlsrTokenizer::getTokenPosition(string& token)
-  {
-    int pos=-1;
-    int i=0;
-    for(std::list<string>::iterator it=m_tokenList.begin();
-        it!=m_tokenList.end(); it++)
-    {
-      if( (*it) == token )
-      {
-        break;
-      }
-      i++;
-    }
-    if( i < m_tokenList.size() )
-    {
-      pos=i;
-    }
-    return pos;
-  }
-
-  string
-  nlsrTokenizer::getTokenString(int from , int to)
-  {
-    string returnString="";
-    if((from>=0 && to<m_tokenList.size()) &&
-        (to>=from && to <m_tokenList.size()))
-    {
-      for(int i=from; i<=to; i++)
-      {
-        returnString+=m_seps;
-        returnString+=m_vTokenList[i];
-      }
-    }
-    trim(returnString);
-    return returnString;
-  }
-
-  string
-  nlsrTokenizer::getTokenString(int from)
-  {
-    return getTokenString(from,m_tokenList.size()-1);
-  }
-
-  static bool
-  tokenCompare(string& s1, string& s2)
-  {
-    return s1==s2;
-  }
-
-  void
-  nlsrTokenizer::makeRestOfTheLine()
-  {
-    m_restOfTheLine=getTokenString(1);
-  }
-
-  bool
-  nlsrTokenizer::doesTokenExist(string token)
-  {
-    std::list<string >::iterator it = std::find_if( m_tokenList.begin(),
-                                      m_tokenList.end(),
-                                      bind(&tokenCompare, _1 , token));
-    if( it != m_tokenList.end() )
-    {
-      return true;
-    }
-    return false;
-  }
-
-}//namespace nlsr
diff --git a/src/utility/nlsr_tokenizer.hpp b/src/utility/nlsr_tokenizer.hpp
deleted file mode 100644
index 02d6eea..0000000
--- a/src/utility/nlsr_tokenizer.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef NLSR_TOKENIZER_HPP
-#define NLSR_TOKENIZER_HPP
-
-#include <iostream>
-#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <string>
-#include <list>
-#include <vector>
-#include <ndn-cpp-dev/face.hpp>
-
-namespace nlsr
-{
-
-  using namespace std;
-  using namespace boost;
-
-  class nlsrTokenizer
-  {
-  public:
-    nlsrTokenizer(const string& inputString)
-      : m_firstToken()
-      , m_restOfTheLine()
-      , m_currentPosition(0)
-    {
-      m_seps = " ";
-      m_originalString = inputString;
-      makeToken();
-    }
-
-    nlsrTokenizer(const string& inputString, const string& separator)
-      : m_firstToken()
-      , m_restOfTheLine()
-      , m_currentPosition(0)
-    {
-      m_seps = separator;
-      m_originalString = inputString;
-      makeToken();
-    }
-
-    string getFirstToken()
-    {
-      return m_firstToken;
-    }
-
-    string getRestOfLine()
-    {
-      return m_restOfTheLine;
-    }
-
-    void resetCurrentPosition(uint32_t cp=0)
-    {
-      if( cp >=0 && cp <= m_vTokenList.size() )
-      {
-        m_currentPosition=cp;
-      }
-    }
-
-    string getNextToken()
-    {
-      if(m_currentPosition >= 0 && m_currentPosition <= (m_vTokenList.size()-1))
-      {
-        return m_vTokenList[m_currentPosition++];
-      }
-      return "";
-    }
-
-    uint32_t getTokenNumber()
-    {
-      return m_tokenList.size();
-    }
-
-    string getToken(int position)
-    {
-      if( position >=0 && position <m_vTokenList.size() )
-      {
-        return m_vTokenList[position];
-      }
-      return "";
-    }
-
-    int getTokenPosition(string& token);
-    string getTokenString(int from , int to);
-    string getTokenString(int from);
-    bool doesTokenExist(string token);
-
-
-  private:
-
-    void makeToken();
-    void insertToken(const string& token);
-    void makeRestOfTheLine();
-
-    string m_seps;
-    string m_originalString;
-    string m_firstToken;
-    string m_restOfTheLine;
-    std::list<string> m_tokenList;
-    std::vector<string> m_vTokenList;
-    uint32_t m_currentPosition;
-  };
-
-}//namespace nlsr
-#endif
diff --git a/src/utility/tokenizer.cpp b/src/utility/tokenizer.cpp
new file mode 100644
index 0000000..e326c2a
--- /dev/null
+++ b/src/utility/tokenizer.cpp
@@ -0,0 +1,109 @@
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <algorithm>
+
+#include "tokenizer.hpp"
+
+namespace nlsr {
+
+using namespace std;
+using namespace boost;
+
+void
+Tokenizer::makeToken()
+{
+  char_separator<char> sep(m_seps.c_str());
+  tokenizer<char_separator<char> >tokens(m_originalString, sep);
+  tokenizer<char_separator<char> >::iterator tok_iter = tokens.begin();
+  for (; tok_iter != tokens.end(); ++tok_iter)
+  {
+    string oneToken(*tok_iter);
+    trim(oneToken);
+    if (!oneToken.empty())
+    {
+      insertToken(oneToken);
+    }
+  }
+  m_firstToken = m_vTokenList[0];
+  makeRestOfTheLine();
+}
+
+void
+Tokenizer::insertToken(const string& token)
+{
+  m_tokenList.push_back(token);
+  m_vTokenList.push_back(token);
+}
+
+uint32_t
+Tokenizer::getTokenPosition(string& token)
+{
+  int pos = -1;
+  int i = 0;
+  for (std::list<string>::iterator it = m_tokenList.begin();
+       it != m_tokenList.end(); it++)
+  {
+    if ((*it) == token)
+    {
+      break;
+    }
+    i++;
+  }
+  if (i < m_tokenList.size())
+  {
+    pos = i;
+  }
+  return pos;
+}
+
+string
+Tokenizer::getTokenString(uint32_t from , uint32_t to)
+{
+  string returnString = "";
+  if ((to < m_tokenList.size()) &&
+      (to >= from && to < m_tokenList.size()))
+  {
+    for (int i = from; i <= to; i++)
+    {
+      returnString += m_seps;
+      returnString += m_vTokenList[i];
+    }
+  }
+  trim(returnString);
+  return returnString;
+}
+
+string
+Tokenizer::getTokenString(uint32_t from)
+{
+  return getTokenString(from, m_tokenList.size() - 1);
+}
+
+static bool
+tokenCompare(string& s1, string& s2)
+{
+  return s1 == s2;
+}
+
+void
+Tokenizer::makeRestOfTheLine()
+{
+  m_restOfTheLine = getTokenString(1);
+}
+
+bool
+Tokenizer::doesTokenExist(string token)
+{
+  std::list<string>::iterator it = std::find_if(m_tokenList.begin(),
+                                                m_tokenList.end(),
+                                                bind(&tokenCompare, _1 , token));
+  if (it != m_tokenList.end())
+  {
+    return true;
+  }
+  return false;
+}
+
+}//namespace nlsr
diff --git a/src/utility/tokenizer.hpp b/src/utility/tokenizer.hpp
new file mode 100644
index 0000000..dd6254d
--- /dev/null
+++ b/src/utility/tokenizer.hpp
@@ -0,0 +1,118 @@
+#ifndef NLSR_TOKENIZER_HPP
+#define NLSR_TOKENIZER_HPP
+
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <list>
+#include <vector>
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr {
+
+class Tokenizer
+{
+public:
+  Tokenizer(const std::string& inputString)
+    : m_firstToken()
+    , m_restOfTheLine()
+    , m_currentPosition(0)
+  {
+    m_seps = " ";
+    m_originalString = inputString;
+    makeToken();
+  }
+
+  Tokenizer(const std::string& inputString, const std::string& separator)
+    : m_firstToken()
+    , m_restOfTheLine()
+    , m_currentPosition(0)
+  {
+    m_seps = separator;
+    m_originalString = inputString;
+    makeToken();
+  }
+
+  std::string
+  getFirstToken()
+  {
+    return m_firstToken;
+  }
+
+  std::string
+  getRestOfLine()
+  {
+    return m_restOfTheLine;
+  }
+
+  void
+  resetCurrentPosition(uint32_t cp = 0)
+  {
+    if (cp <= m_vTokenList.size())
+    {
+      m_currentPosition = cp;
+    }
+  }
+
+  std::string
+  getNextToken()
+  {
+    if (m_currentPosition <= (m_vTokenList.size() - 1))
+    {
+      return m_vTokenList[m_currentPosition++];
+    }
+    return "";
+  }
+
+  uint32_t
+  getTokenNumber()
+  {
+    return m_tokenList.size();
+  }
+
+  std::string
+  getToken(unsigned int position)
+  {
+    if (position < m_vTokenList.size())
+    {
+      return m_vTokenList[position];
+    }
+    return "";
+  }
+
+  uint32_t
+  getTokenPosition(std::string& token);
+
+  std::string
+  getTokenString(uint32_t from , uint32_t to);
+
+  std::string
+  getTokenString(uint32_t from);
+
+  bool
+  doesTokenExist(std::string token);
+
+
+private:
+
+  void
+  makeToken();
+
+  void
+  insertToken(const std::string& token);
+
+  void
+  makeRestOfTheLine();
+
+  std::string m_seps;
+  std::string m_originalString;
+  std::string m_firstToken;
+  std::string m_restOfTheLine;
+  std::list<std::string> m_tokenList;
+  std::vector<std::string> m_vTokenList;
+  uint32_t m_currentPosition;
+};
+
+}//namespace nlsr
+#endif //NLSR_TOKENIZER_HPP
