diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
new file mode 100644
index 0000000..92a911d
--- /dev/null
+++ b/src/communication/nlsr_dm.cpp
@@ -0,0 +1,202 @@
+#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"
+
+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());
+        //cout << "D: " << dataName << endl;
+        //cout << "Data Content: " << dataContent << endl;
+        nlsrTokenizer nt(dataName,"/");
+        //SignatureSha256WithRsa sig(data.getSignature());
+        //ndn::Name keyName=sig.getKeyLocator().getName();
+        //cout<<"Key Locator Name: "<<keyName.toUri()<<endl;
+        string 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);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processContentKeys(pnlsr, data);
+        }
+    }
+
+    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.initNameLsaFromContent(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.initAdjLsaFromContent(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.initCorLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+    
+    void 
+    DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
+    {
+        std::ofstream outFile("data_received");
+        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        cout<<" processContentKeys called "<<endl;
+        SignatureSha256WithRsa signature(data.getSignature());
+        cout<<"D: <<"<<data<<endl;
+        cout<<"Key Locator: "<<signature.getKeyLocator().getName().toUri()<<endl;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=ndn::make_shared<ndn::IdentityCertificate>();
+        cert->wireDecode(data.getContent().blockFromValue());
+        cout<<*(cert)<<endl;
+        
+        if( pnlsr.getKeyManager().verifySignature(*(cert),cert->getPublicKeyInfo()))
+        {
+            cout<<"Verified Data"<<endl;
+        }
+    }
+}//namespace nlsr
diff --git a/src/communication/nlsr_dm.hpp b/src/communication/nlsr_dm.hpp
new file mode 100644
index 0000000..fdb45db
--- /dev/null
+++ b/src/communication/nlsr_dm.hpp
@@ -0,0 +1,40 @@
+#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
new file mode 100644
index 0000000..7495265
--- /dev/null
+++ b/src/communication/nlsr_im.cpp
@@ -0,0 +1,300 @@
+#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"
+
+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);
+        }
+        //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
+        //data.setFreshnessPeriod(1000); // 10 sec
+        //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
+        //pnlsr.getKeyChain().sign(data);
+        //cout << ">> D: " << data << endl;
+        //pnlsr.getNlsrFace().put(data);
+    }
+
+    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(1000); // 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(1000); // 10 sec
+                string content=nameLsa.first.getNameLsaData();
+                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(1000); // 10 sec
+                string content=adjLsa.first.getAdjLsaData();
+                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(1000); // 10 sec
+                string content=corLsa.first.getCorLsaData();
+                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;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate("dummy");
+        Data data(ndn::Name(interest.getName()).appendVersion());
+        data.setFreshnessPeriod(1000); // 10 sec
+        data.setContent(cert->wireEncode());
+        pnlsr.getKeyManager().signData(data);
+        std::ofstream outFile("data_sent");
+        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        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(seconds*1000);
+        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).getAdjacentName()+"/"+"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
new file mode 100644
index 0000000..330874f
--- /dev/null
+++ b/src/communication/nlsr_im.hpp
@@ -0,0 +1,52 @@
+#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
new file mode 100644
index 0000000..ac29148
--- /dev/null
+++ b/src/communication/nlsr_slh.cpp
@@ -0,0 +1,147 @@
+#include "nlsr.hpp"
+#include "nlsr_slh.hpp"
+#include "security/nlsr_km.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+
+
+namespace nlsr
+{
+    void
+    SyncLogicHandler::createSyncSocket(Nlsr &pnlsr )
+    {
+        cout<<"Creating Sync socket ......"<<endl;
+        cout<<"Sync prefix: "<<syncPrefix.toUri()<<endl;
+        syncSocket=make_shared<SyncSocket>(syncPrefix, validator, 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
+            processKeysUpdateFromSync(updateName,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)
+    {
+        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.getRouterCertName().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");
+        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
new file mode 100644
index 0000000..3fef612
--- /dev/null
+++ b/src/communication/nlsr_slh.hpp
@@ -0,0 +1,65 @@
+#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)
+            : validator(new ndn::ValidatorNull())
+            , 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)
+        {
+            syncPrefix.clear();
+            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> validator;
+        ndn::shared_ptr<ndn::Face> syncFace;
+        ndn::shared_ptr<SyncSocket> syncSocket;
+        ndn::Name syncPrefix;
+    };
+}
+#endif
diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
new file mode 100644
index 0000000..5f4811c
--- /dev/null
+++ b/src/route/nlsr_fe.cpp
@@ -0,0 +1,48 @@
+#include <list>
+#include "nlsr_fe.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    bool
+    FibEntry::isEqualNextHops(Nhl &nhlOther)
+    {
+        if ( nhl.getNhlSize() != nhlOther.getNhlSize() )
+        {
+            return false;
+        }
+        else
+        {
+            int nhCount=0;
+            std::list<NextHop>::iterator it1, it2;
+            for ( it1=nhl.getNextHopList().begin(),
+                    it2 = nhlOther.getNextHopList().begin() ;
+                    it1 != nhl.getNextHopList().end() ; it1++, it2++)
+            {
+                if ((*it1).getConnectingFace() == (*it2).getConnectingFace() )
+                {
+                    (*it1).setRouteCost((*it2).getRouteCost());
+                    nhCount++;
+                }
+                else
+                {
+                    break;
+                }
+            }
+            return nhCount == nhl.getNhlSize();
+        }
+    }
+
+    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
new file mode 100644
index 0000000..c85e045
--- /dev/null
+++ b/src/route/nlsr_fe.hpp
@@ -0,0 +1,85 @@
+#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()
+            : name()
+            , timeToRefresh(0)
+            , feSeqNo(0)
+        {
+        }
+
+        FibEntry(string n)
+        {
+            name=n;
+        }
+
+        string getName()
+        {
+            return name;
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+
+        int getTimeToRefresh()
+        {
+            return timeToRefresh;
+        }
+
+        void setTimeToRefresh(int ttr)
+        {
+            timeToRefresh=ttr;
+        }
+
+        void setFeExpiringEventId(ndn::EventId feid)
+        {
+            feExpiringEventId=feid;
+        }
+
+        ndn::EventId getFeExpiringEventId()
+        {
+            return feExpiringEventId;
+        }
+
+        void setFeSeqNo(int fsn)
+        {
+            feSeqNo=fsn;
+        }
+
+        int getFeSeqNo()
+        {
+            return feSeqNo;
+        }
+
+        bool isEqualNextHops(Nhl &nhlOther);
+
+    private:
+        string name;
+        int timeToRefresh;
+        ndn::EventId feExpiringEventId;
+        int feSeqNo;
+        Nhl nhl;
+    };
+
+    ostream& operator<<(ostream& os, FibEntry& fe);
+
+} //namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
new file mode 100644
index 0000000..8fb7928
--- /dev/null
+++ b/src/route/nlsr_fib.cpp
@@ -0,0 +1,168 @@
+#include<list>
+#include "nlsr_fe.hpp"
+#include "nlsr_fib.hpp"
+#include "nlsr_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::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
+    {
+        pnlsr.getScheduler().cancelEvent(eid);
+    }
+
+
+    ndn::EventId
+    Fib::scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                                    int refreshTime)
+    {
+        return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
+                ndn::bind(&Fib::refreshFibEntry,this,name,feSeqNum));
+    }
+
+    void
+    Fib::refreshFibEntry(string name, int feSeqNum)
+    {
+    }
+
+    void
+    Fib::removeFromFib(Nlsr& pnlsr, string name)
+    {
+        std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                            fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+        if( it != fibTable.end() )
+        {
+            for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+            {
+                //remove entry from NDN-FIB
+            }
+            cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+            fibTable.erase(it);
+        }
+    }
+
+
+    void
+    Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        int startFace=0;
+        int endFace=getNumberOfFacesForName(nextHopList,maxFacesPerPrefix);
+        std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                            fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+        if( it != fibTable.end() )
+        {
+            nextHopList.sortNhl();
+            if ( !(*it).isEqualNextHops(nextHopList) )
+            {
+                std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+                (*it).getNhl().addNextHop((*nhit));
+                removeFibEntryHop((*it).getNhl(),(*nhit).getConnectingFace());
+                startFace++;
+                nhit++;
+                for( int i=startFace; i< endFace; nhit++,i++)
+                {
+                    (*it).getNhl().addNextHop((*nhit));
+                }
+                (*it).setTimeToRefresh(fibEntryRefreshTime);
+            }
+            (*it).getNhl().sortNhl();
+            cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+            (*it).setFeSeqNo((*it).getFeSeqNo()+1);
+            (*it).setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                       (*it).getName() ,
+                                       (*it).getFeSeqNo(),fibEntryRefreshTime));
+            //update NDN-FIB
+        }
+        else
+        {
+            nextHopList.sortNhl();
+            FibEntry newEntry(name);
+            std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+            for(int i=startFace; i< endFace ; i++)
+            {
+                newEntry.getNhl().addNextHop((*nhit));
+                ++nhit;
+            }
+            newEntry.getNhl().sortNhl();
+            newEntry.setTimeToRefresh(fibEntryRefreshTime);
+            newEntry.setFeSeqNo(1);
+            fibTable.push_back(newEntry);
+            //cancelScheduledFeExpiringEvent(pnlsr, newEntry().getFeExpiringEventId());
+            //Update NDN-FIB
+        }
+    }
+
+
+
+    void Fib::cleanFib(Nlsr& pnlsr)
+    {
+        for( std::list<FibEntry >::iterator it=fibTable.begin(); it != fibTable.end();
+                ++it)
+        {
+            for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+            {
+                cancelScheduledFeExpiringEvent(pnlsr,(*it).getFeExpiringEventId());
+                //remove entry from NDN-FIB
+            }
+        }
+        if ( fibTable.size() > 0 )
+        {
+            fibTable.clear();
+        }
+    }
+
+
+    void
+    Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
+    {
+        for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
+                it != nl.getNextHopList().end();   ++it)
+        {
+            if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
+            {
+                nl.getNextHopList().erase(it);
+            }
+        }
+    }
+
+
+    int
+    Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        int endFace=0;
+        if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
+        {
+            return nextHopList.getNhlSize();
+        }
+        else
+        {
+            return maxFacesPerPrefix;
+        }
+        return endFace;
+    }
+
+    void
+    Fib::printFib()
+    {
+        cout<<"-------------------FIB-----------------------------"<<endl;
+        for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
+                ++it)
+        {
+            cout<<(*it);
+        }
+    }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_fib.hpp b/src/route/nlsr_fib.hpp
new file mode 100644
index 0000000..d93d972
--- /dev/null
+++ b/src/route/nlsr_fib.hpp
@@ -0,0 +1,48 @@
+#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()
+        {
+        }
+
+        void removeFromFib(Nlsr& pnlsr, string name);
+        void updateFib(Nlsr& pnlsr, string name, Nhl& nextHopList,
+                       int maxFacesPerPrefix);
+        void cleanFib(Nlsr& pnlsr);
+        void setFibEntryRefreshTime(int fert)
+        {
+            fibEntryRefreshTime=fert;
+        }
+
+        void printFib();
+
+    private:
+        void removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId);
+        int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
+        ndn::EventId
+        scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                                   int refreshTime);
+        void cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid);
+        void refreshFibEntry(string name, int feSeqNum);
+
+    private:
+        std::list<FibEntry> fibTable;
+        int fibEntryRefreshTime;
+    };
+
+}//namespace nlsr
+#endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
new file mode 100644
index 0000000..47b02ec
--- /dev/null
+++ b/src/route/nlsr_map.cpp
@@ -0,0 +1,124 @@
+#include<iostream>
+#include<list>
+
+#include "nlsr.hpp"
+#include "nlsr_adjacent.hpp"
+#include "nlsr_lsa.hpp"
+#include "nlsr_lsdb.hpp"
+#include "nlsr_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::addMapElement(string& rtrName)
+    {
+        MapEntry me(rtrName,mappingIndex);
+        if (  addMapElement(me) )
+        {
+            mappingIndex++;
+        }
+    }
+
+    bool
+    Map::addMapElement(MapEntry& mpe)
+    {
+        //cout << mpe;
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByRouter, _1, mpe.getRouter()));
+        if ( it == rMap.end() )
+        {
+            rMap.push_back(mpe);
+            return true;
+        }
+        return false;
+    }
+
+    string
+    Map::getRouterNameByMappingNo(int mn)
+    {
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByMappingNo, _1, mn));
+        if ( it != rMap.end() )
+        {
+            return (*it).getRouter();
+        }
+        return "";
+    }
+
+    int
+    Map::getMappingNoByRouterName(string& rName)
+    {
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByRouter, _1, rName));
+        if ( it != rMap.end() )
+        {
+            return (*it).getMappingNumber();
+        }
+        return -1;
+    }
+
+    void
+    Map::createMapFromAdjLsdb(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();
+            addMapElement(linkStartRouter);
+            std::list<Adjacent> adl=(*it).getAdl().getAdjList();
+            for( std::list<Adjacent>::iterator itAdl=adl.begin();
+                    itAdl!= adl.end() ; itAdl++)
+            {
+                string linkEndRouter=(*itAdl).getAdjacentName();
+                addMapElement(linkEndRouter);
+            }
+        }
+    }
+
+    void
+    Map::resetMap()
+    {
+        rMap.clear();
+        mappingIndex=0;
+    }
+
+    ostream&
+    operator<<(ostream& os, Map& rMap)
+    {
+        os<<"---------------Map----------------------"<<endl;
+        std::list< MapEntry > ml=rMap.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
new file mode 100644
index 0000000..0352d1d
--- /dev/null
+++ b/src/route/nlsr_map.hpp
@@ -0,0 +1,88 @@
+#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()
+            : router()
+            , mappingNumber(-1)
+        {
+        }
+
+        ~MapEntry()
+        {
+        }
+
+        MapEntry(string rtr, int mn)
+        {
+            router=rtr;
+            mappingNumber=mn;
+        }
+
+        string getRouter()
+        {
+            return router;
+        }
+
+        int getMappingNumber()
+        {
+            return mappingNumber;
+        }
+    private:
+        string router;
+        int mappingNumber;
+    };
+
+    ostream&
+    operator<<(ostream& os, MapEntry& mpe);
+
+    class Map
+    {
+    public:
+        Map()
+            : mappingIndex(0)
+        {
+        }
+
+
+        void addMapElement(string& rtrName);
+        void createMapFromAdjLsdb(Nlsr& pnlsr);
+        string getRouterNameByMappingNo(int mn);
+        int getMappingNoByRouterName(string& rName);
+        void resetMap();
+        std::list< MapEntry >& getMapList()
+        {
+            return rMap;
+        }
+
+        int getMapSize()
+        {
+            return rMap.size();
+        }
+
+
+    private:
+        bool addMapElement(MapEntry& mpe);
+
+        int mappingIndex;
+        std::list< MapEntry > rMap;
+    };
+
+    ostream&
+    operator<<(ostream& os, Map& rMap);
+
+} // namespace nlsr
+#endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
new file mode 100644
index 0000000..e58b23c
--- /dev/null
+++ b/src/route/nlsr_nexthop.cpp
@@ -0,0 +1,13 @@
+#include "nlsr_nexthop.hpp"
+
+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
new file mode 100644
index 0000000..1361d52
--- /dev/null
+++ b/src/route/nlsr_nexthop.hpp
@@ -0,0 +1,56 @@
+#ifndef NLSR_NEXTHOP_HPP
+#define NLSR_NEXTHOP_HPP
+
+#include<iostream>
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class NextHop
+    {
+    public:
+        NextHop()
+            : connectingFace(0)
+            , routeCost(0)
+        {
+        }
+
+        NextHop(int cf, double rc)
+        {
+            connectingFace=cf;
+            routeCost=rc;
+        }
+
+        int getConnectingFace()
+        {
+            return connectingFace;
+        }
+
+        void setConnectingFace(int cf)
+        {
+            connectingFace=cf;
+        }
+
+        double getRouteCost()
+        {
+            return routeCost;
+        }
+
+        void setRouteCost(double rc)
+        {
+            routeCost=rc;
+        }
+    private:
+        int connectingFace;
+        double routeCost;
+    };
+
+
+    ostream&
+    operator<<(ostream& os, NextHop& nh);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
new file mode 100644
index 0000000..2aaa2a6
--- /dev/null
+++ b/src/route/nlsr_nhl.cpp
@@ -0,0 +1,90 @@
+#include <iostream>
+
+#include "nlsr_nhl.hpp"
+#include "nlsr_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(NextHop& nh1, 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( nexthopList.begin(),
+                                           nexthopList.end(),
+                                           bind(&nexthopCompare, _1, nh));
+        if ( it == nexthopList.end() )
+        {
+            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( nexthopList.begin(),
+                                           nexthopList.end(),
+                                           bind(&nexthopRemoveCompare, _1, nh));
+        if ( it != nexthopList.end() )
+        {
+            nexthopList.erase(it);
+        }
+    }
+
+    void
+    Nhl::sortNhl()
+    {
+        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
new file mode 100644
index 0000000..9f6bd76
--- /dev/null
+++ b/src/route/nlsr_nhl.hpp
@@ -0,0 +1,54 @@
+#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()
+        {
+        }
+
+        ~Nhl()
+        {
+        }
+        void addNextHop(NextHop &nh);
+        void removeNextHop(NextHop &nh);
+        void sortNhl();
+        int getNhlSize()
+        {
+            return nexthopList.size();
+        }
+        void resetNhl()
+        {
+            if (nexthopList.size() > 0 )
+            {
+                nexthopList.clear();
+            }
+        }
+        std::list< NextHop >& getNextHopList()
+        {
+            return nexthopList;
+        }
+
+    private:
+        std::list< NextHop > nexthopList;
+    };
+
+    ostream&
+    operator<<(ostream& os, Nhl& nhl);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
new file mode 100644
index 0000000..9c4d4cb
--- /dev/null
+++ b/src/route/nlsr_npt.cpp
@@ -0,0 +1,142 @@
+#include <list>
+#include <utility>
+#include <algorithm>
+
+#include "nlsr_npt.hpp"
+#include "nlsr_npte.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    static bool
+    npteCompare(Npte& npte, string& name)
+    {
+        return npte.getNamePrefix()==name;
+    }
+
+// Following two methods will update FIB with response to change in NPT
+
+    void
+    Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    {
+        std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+                                        npteList.end(), bind(&npteCompare, _1, name));
+        if ( it == npteList.end() )
+        {
+            Npte newEntry(	name);
+            newEntry.addRoutingTableEntry(rte);
+            newEntry.generateNhlfromRteList();
+            npteList.push_back(newEntry);
+            // update FIB here with nhl list newEntry.getNhl()
+            pnlsr.getFib().updateFib(pnlsr, name,newEntry.getNhl(),
+                                     pnlsr.getConfParameter().getMaxFacesPerPrefix());
+        }
+        else
+        {
+            (*it).addRoutingTableEntry(rte);
+            (*it).generateNhlfromRteList();
+            // update FIB here with nhl list from (*it).getNhl()
+            pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl() ,
+                                     pnlsr.getConfParameter().getMaxFacesPerPrefix());
+        }
+    }
+
+    void
+    Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    {
+        std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+                                        npteList.end(), bind(&npteCompare, _1, name));
+        if ( it != 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) )   )
+            {
+                npteList.erase(it); // remove entry from NPT
+                // remove FIB entry with this name
+                pnlsr.getFib().removeFromFib(pnlsr,name);
+            }
+            else
+            {
+                (*it).generateNhlfromRteList();
+                // update FIB entry with new NHL
+                pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl(),
+                                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
+            }
+        }
+    }
+
+
+    void
+    Npt::addNpte(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::updateNptWithNewRoute(Nlsr& pnlsr)
+    {
+        for(std::list<Npte >::iterator it=npteList.begin(); it!=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::printNpt()
+    {
+        cout<<"----------------NPT----------------------"<<endl;
+        for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
+        {
+            cout <<(*it)<<endl;
+        }
+    }
+
+}
diff --git a/src/route/nlsr_npt.hpp b/src/route/nlsr_npt.hpp
new file mode 100644
index 0000000..f4ddbf9
--- /dev/null
+++ b/src/route/nlsr_npt.hpp
@@ -0,0 +1,34 @@
+#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 addNpte(string name, string destRouter, Nlsr& pnlsr);
+        void removeNpte(string name, string destRouter, Nlsr& pnlsr);
+        void updateNptWithNewRoute(Nlsr& pnlsr);
+        void printNpt();
+    private:
+        void addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+        void removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+    private:
+        std::list<Npte> npteList;
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
new file mode 100644
index 0000000..60013ff
--- /dev/null
+++ b/src/route/nlsr_npte.cpp
@@ -0,0 +1,83 @@
+#include <list>
+#include <utility>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    void
+    Npte::generateNhlfromRteList()
+    {
+        nhl.resetNhl();
+        for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+                it != rteList.end(); ++it )
+        {
+            for(std::list< NextHop >::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().end(); ++nhit)
+            {
+                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( rteList.begin(),
+                rteList.end(),
+                bind(&rteCompare, _1, rte.getDestination()));
+        if ( it != rteList.end() )
+        {
+            rteList.erase(it);
+        }
+    }
+
+    void
+    Npte::addRoutingTableEntry(RoutingTableEntry &rte)
+    {
+        std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
+                rteList.end(),
+                bind(&rteCompare, _1, rte.getDestination()));
+        if ( it == rteList.end() )
+        {
+            rteList.push_back(rte);
+        }
+        else
+        {
+            (*it).getNhl().resetNhl(); // 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
new file mode 100644
index 0000000..e64328c
--- /dev/null
+++ b/src/route/nlsr_npte.hpp
@@ -0,0 +1,61 @@
+#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()
+            : namePrefix()
+            , nhl()
+        {
+        }
+        Npte(string np)
+            : nhl()
+        {
+            namePrefix=np;
+        }
+
+        string getNamePrefix()
+        {
+            return namePrefix;
+        }
+
+        std::list<RoutingTableEntry>& getRteList()
+        {
+            return rteList;
+        }
+
+        int getRteListSize()
+        {
+            return rteList.size();
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+        void generateNhlfromRteList();
+        void removeRoutingTableEntry(RoutingTableEntry& rte);
+        void addRoutingTableEntry(RoutingTableEntry &rte);
+
+    private:
+        string namePrefix;
+        std::list<RoutingTableEntry> rteList;
+        Nhl nhl;
+    };
+
+    ostream&
+    operator<<(ostream& os, Npte& npte);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
new file mode 100644
index 0000000..f9923f2
--- /dev/null
+++ b/src/route/nlsr_rt.cpp
@@ -0,0 +1,231 @@
+#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"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    void
+    RoutingTable::calculate(Nlsr& pnlsr)
+    {
+        //debugging purpose
+        pnlsr.getNpt().printNpt();
+        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().updateNptWithNewRoute(pnlsr);
+                    //debugging purpose
+                    printRoutingTable();
+                    pnlsr.getNpt().printNpt();
+                    pnlsr.getFib().printFib();
+                    //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
+                pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
+                //debugging purpose
+                printRoutingTable();
+                pnlsr.getNpt().printNpt();
+                pnlsr.getFib().printFib();
+                //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.createMapFromAdjLsdb(pnlsr);
+        int numOfRouter=vMap.getMapSize();
+        LinkStateRoutingTableCalculator lsrtc(numOfRouter);
+        lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+    }
+
+    void
+    RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
+    {
+        Map vMap;
+        vMap.createMapFromAdjLsdb(pnlsr);
+        int numOfRouter=vMap.getMapSize();
+        HypRoutingTableCalculator hrtc(numOfRouter,0);
+        hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+    }
+
+    void
+    RoutingTable::calculateHypDryRoutingTable(Nlsr& pnlsr)
+    {
+        Map vMap;
+        vMap.createMapFromAdjLsdb(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);
+            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( rTable.begin(),
+                rTable.end(),
+                bind(&routingTableEntryCompare, _1, destRouter));
+        if ( it != 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=rTable.begin() ;
+                it != 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( dryTable.begin(),
+                dryTable.end(),
+                bind(&routingTableEntryCompare, _1, destRouter));
+        if ( it == dryTable.end() )
+        {
+            RoutingTableEntry rte(destRouter);
+            rte.getNhl().addNextHop(nh);
+            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=dryTable.begin() ;
+                it != dryTable.end(); ++it)
+        {
+            cout<<(*it)<<endl;
+        }
+    }
+
+
+    void
+    RoutingTable::clearRoutingTable()
+    {
+        if( rTable.size() > 0 )
+        {
+            rTable.clear();
+        }
+    }
+
+    void
+    RoutingTable::clearDryRoutingTable()
+    {
+        if (dryTable.size()>0 )
+        {
+            dryTable.clear();
+        }
+    }
+
+}//namespace nlsr
+
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
new file mode 100644
index 0000000..fb9a060
--- /dev/null
+++ b/src/route/nlsr_rt.hpp
@@ -0,0 +1,50 @@
+#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 > rTable;
+        std::list< RoutingTableEntry > dryTable;
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
new file mode 100644
index 0000000..acdf6d5
--- /dev/null
+++ b/src/route/nlsr_rtc.cpp
@@ -0,0 +1,504 @@
+#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"
+
+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).getAdjacentName();
+                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++)
+        {
+            parent[i]=EMPTY_PARENT;
+            distance[i]=INF_DISTANCE;
+            Q[i]=i;
+        }
+        if ( sourceRouter != NO_MAPPING_NUM )
+        {
+            distance[sourceRouter]=0;
+            sortQueueByDistance(Q,distance,head,numOfRouter);
+            while (head < numOfRouter )
+            {
+                u=Q[head];
+                if(distance[u] == INF_DISTANCE)
+                {
+                    break;
+                }
+                for(v=0 ; v <numOfRouter; v++)
+                {
+                    if( adjMatrix[u][v] > 0 )
+                    {
+                        if ( isNotExplored(Q,v,head+1,numOfRouter) )
+                        {
+                            if( distance[u] + adjMatrix[u][v] <  distance[v])
+                            {
+                                distance[v]=distance[u] + adjMatrix[u][v] ;
+                                parent[v]=u;
+                            }
+                        }
+                    }
+                }
+                head++;
+                sortQueueByDistance(Q,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);
+                double routeCost=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 ( parent[dest] != EMPTY_PARENT )
+        {
+            nextHop=dest;
+            dest=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 (parent[destRouter] != EMPTY_PARENT )
+        {
+            printLsPath(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()
+    {
+        parent=new int[numOfRouter];
+    }
+
+    void
+    LinkStateRoutingTableCalculator::allocateDistance()
+    {
+        distance= new double[numOfRouter];
+    }
+
+    void
+    LinkStateRoutingTableCalculator::freeParent()
+    {
+        delete [] parent;
+    }
+
+    void LinkStateRoutingTableCalculator::freeDistance()
+    {
+        delete [] 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 )
+                    {
+                        linkFaces[k] = nextHopFace;
+                        distanceToNeighbor[k] = distToNbr;
+                        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(linkFaces[i],distFromNbrToDest[i]);
+            rt.addNextHop(destRouter,nh);
+            if( isDryRun == 1 )
+            {
+                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()
+    {
+        linkFaces=new int[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::allocateDistanceToNeighbor()
+    {
+        distanceToNeighbor=new double[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::allocateDistFromNbrToDest()
+    {
+        distFromNbrToDest=new double[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::freeLinkFaces()
+    {
+        delete [] linkFaces;
+    }
+
+    void
+    HypRoutingTableCalculator::freeDistanceToNeighbor()
+    {
+        delete [] distanceToNeighbor;
+    }
+
+    void
+    HypRoutingTableCalculator::freeDistFromNbrToDest()
+    {
+        delete [] distFromNbrToDest;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
new file mode 100644
index 0000000..987686e
--- /dev/null
+++ b/src/route/nlsr_rtc.hpp
@@ -0,0 +1,145 @@
+#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 *parent;
+        double *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;
+            isDryRun=0;
+        }
+        HypRoutingTableCalculator(int rn, int idr)
+            :  MATH_PI(3.141592654)
+        {
+            numOfRouter=rn;
+            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:
+        int isDryRun;
+
+        int *linkFaces;
+        double *distanceToNeighbor;
+        double *distFromNbrToDest;
+
+        const double MATH_PI;
+
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
new file mode 100644
index 0000000..f96da11
--- /dev/null
+++ b/src/route/nlsr_rte.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <string>
+
+#include "nlsr_rte.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/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
new file mode 100644
index 0000000..27d3601
--- /dev/null
+++ b/src/route/nlsr_rte.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_RTE_HPP
+#define NLSR_RTE_HPP
+
+#include<iostream>
+
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class RoutingTableEntry
+    {
+    public:
+        RoutingTableEntry()
+            : destination()
+            , nhl()
+        {
+        }
+
+        ~RoutingTableEntry()
+        {
+        }
+
+        RoutingTableEntry(string dest)
+            : nhl()
+        {
+            destination=dest;
+        }
+
+        string getDestination()
+        {
+            return destination;
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+
+    private:
+        string destination;
+        Nhl nhl;
+    };
+
+    ostream&
+    operator<<(ostream& os, RoutingTableEntry &rte);
+
+}
+
+#endif
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
new file mode 100644
index 0000000..5bbef9e
--- /dev/null
+++ b/src/security/nlsr_cert_store.hpp
@@ -0,0 +1,6 @@
+#ifndef NLSR_CERT_STORE_HPP
+#define NLSR_CERT_STORE_HPP
+
+
+
+#endif
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
new file mode 100644
index 0000000..69052eb
--- /dev/null
+++ b/src/security/nlsr_km.cpp
@@ -0,0 +1,84 @@
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/encoding/block.hpp>
+#include "nlsr_sm.hpp"
+#include "nlsr_km.hpp"
+
+namespace nlsr
+{
+    void
+    KeyManager::initKeyManager(ConfParameter &cp)
+    {
+        string processIdentityName(cp.getRootKeyPrefix());
+        processIdentityName += "/";
+        processIdentityName += cp.getSiteName();
+        processIdentityName += "/";
+        processIdentityName += "R.Start";
+        processIdentityName += "/";
+        processIdentityName += cp.getRouterName();
+        processIdentityName += "/";
+        processIdentityName += "nlsr";
+        cout<<"Proces Identity Name: "<<processIdentityName<<endl;
+        ndn::Name identityName(processIdentityName);
+        routerIdentity=identityName;
+        ndn::KeyChain::deleteIdentity(routerIdentity);
+        routerCertName = ndn::KeyChain::createIdentity(routerIdentity);
+        cout<<"Certificate Name: "<<routerCertName.toUri()<<endl;
+        routerKeyName=
+            ndn::IdentityCertificate::certificateNameToPublicKeyName(routerCertName);
+        cout<<"Key Name: "<<routerKeyName.toUri()<<endl;
+        initCertSeqFromFile(cp.getSeqFileDir());
+    }
+
+    ndn::Name
+    KeyManager::getRouterCertName()
+    {
+        return routerCertName;
+    }
+
+    uint32_t
+    KeyManager::getCertSeqNo()
+    {
+        return certSeqNo;
+    }
+
+    void
+    KeyManager::setCerSeqNo(uint32_t csn)
+    {
+        certSeqNo=csn;
+    }
+
+    void
+    KeyManager::initCertSeqFromFile(string certSeqFileDir)
+    {
+        certSeqFileNameWithPath=certSeqFileDir;
+        if( certSeqFileNameWithPath.empty() )
+        {
+            SequencingManager sm;
+            certSeqFileNameWithPath=sm.getUserHomeDirectory();
+        }
+        certSeqFileNameWithPath += "/nlsrCertSeqNo.txt";
+        cout<<"Key Seq File Name: "<< certSeqFileNameWithPath<<endl;
+        std::ifstream inputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+        if ( inputFile.good() )
+        {
+            inputFile>>certSeqNo;
+            certSeqNo++;
+        }
+        else
+        {
+            certSeqNo=1;
+        }
+        writeCertSeqToFile();
+    }
+
+    void
+    KeyManager::writeCertSeqToFile()
+    {
+        std::ofstream outputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+        outputFile<<certSeqNo;
+        outputFile.close();
+    }
+}
+
+
+
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
new file mode 100644
index 0000000..7b3b7ba
--- /dev/null
+++ b/src/security/nlsr_km.hpp
@@ -0,0 +1,158 @@
+#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/scheduler.hpp>
+#include <ndn-cpp-dev/util/random.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+
+#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
+#include <ndn-cpp-dev/security/sec-public-info-memory.hpp>
+//TPM
+#include <ndn-cpp-dev/security/sec-tpm-file.hpp>
+#include <ndn-cpp-dev/security/sec-tpm-memory.hpp>
+
+#ifdef NDN_CPP_HAVE_OSX_SECURITY
+#include <ndn-cpp-dev/security/sec-tpm-osx.hpp>
+#endif
+
+#include <list>
+#include "nlsr_conf_param.hpp"
+
+namespace nlsr
+{
+    enum nlsrKeyType
+    {
+        KEY_TYPE_ROOT,
+        KEY_TYPE_SITE,
+        KEY_TYPE_OPERATOR,
+        KEY_TYPE_ROUTER,
+        KEY_TYPE_PROCESS
+    };
+
+    class KeyManager: public ndn::KeyChain, public ndn::Validator
+    {
+        typedef SecPublicInfo::Error InfoError;
+        typedef SecTpm::Error TpmError;
+    public:
+        KeyManager()
+            : certSeqNo(1)
+        {
+        }
+
+        void initKeyManager(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,routerIdentity);
+            //ndn::SignatureSha256WithRsa signature(data.getSignature());
+            //signature.setKeyLocator(routerCertName);
+        }
+        
+        ndn::shared_ptr<ndn::IdentityCertificate>
+        getCertificate(ndn::Name certificateName)
+        {
+            return ndn::KeyChain::getCertificate(routerCertName);
+        }
+
+        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 ndn::shared_ptr<ndn::IdentityCertificate>()->getName();
+                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::getNow());
+                certificate->setNotAfter(ndn::getNow() + 31536000 /* 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;
+        }
+
+        ndn::Name getRouterCertName();
+
+        uint32_t getCertSeqNo();
+        void setCerSeqNo(uint32_t csn);
+        void initCertSeqFromFile(string certSeqFileDir);
+        void writeCertSeqToFile();
+
+    private:
+        ndn::Name routerIdentity;
+        ndn::Name routerCertName;
+        ndn::Name routerKeyName;
+        uint32_t certSeqNo;
+        string certSeqFileNameWithPath;
+
+    };
+}
+
+#endif
diff --git a/src/utility/nlsr_logger.cpp b/src/utility/nlsr_logger.cpp
new file mode 100644
index 0000000..804ef98
--- /dev/null
+++ b/src/utility/nlsr_logger.cpp
@@ -0,0 +1,59 @@
+#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 = 128 * 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 = 16 * 1024 * 1024 * 1024,
+                    keywords::min_free_space = 128 * 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
new file mode 100644
index 0000000..222ac52
--- /dev/null
+++ b/src/utility/nlsr_logger.hpp
@@ -0,0 +1,62 @@
+#ifndef NLSR_LOGGER_HPP
+#define NLSR_LOGGER_HPP
+
+#define BOOST_LOG_DYN_LINK 1
+
+#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>
+#include <boost/log/common.hpp>
+#include <boost/log/expressions.hpp>
+#include <boost/log/attributes.hpp>
+#include <boost/log/sources/logger.hpp>
+#include <boost/log/sinks/sync_frontend.hpp>
+#include <boost/log/sinks/text_file_backend.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
new file mode 100644
index 0000000..809e395
--- /dev/null
+++ b/src/utility/nlsr_tokenizer.cpp
@@ -0,0 +1,110 @@
+#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(seps.c_str());
+        tokenizer< char_separator<char> >tokens(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);
+            }
+        }
+        firstToken=vTokenList[0];
+        makeRestOfTheLine();
+    }
+
+    void
+    nlsrTokenizer::insertToken(const string& token)
+    {
+        tokenList.push_back(token);
+        vTokenList.push_back(token);
+    }
+
+    int
+    nlsrTokenizer::getTokenPosition(string& token)
+    {
+        int pos=-1;
+        int i=0;
+        for(std::list<string>::iterator it=tokenList.begin();
+                it!=tokenList.end(); it++)
+        {
+            if( (*it) == token )
+            {
+                break;
+            }
+            i++;
+        }
+        if( i < tokenList.size() )
+        {
+            pos=i;
+        }
+        return pos;
+    }
+
+    string
+    nlsrTokenizer::getTokenString(int from , int to)
+    {
+        string returnString="";
+        if((from>=0 && to<tokenList.size()) &&
+                (to>=from && to <tokenList.size()))
+        {
+            for(int i=from; i<=to; i++)
+            {
+                returnString+=seps;
+                returnString+=vTokenList[i];
+            }
+        }
+        trim(returnString);
+        return returnString;
+    }
+
+    string
+    nlsrTokenizer::getTokenString(int from)
+    {
+        return getTokenString(from,tokenList.size()-1);
+    }
+
+    static bool
+    tokenCompare(string& s1, string& s2)
+    {
+        return s1==s2;
+    }
+
+    void
+    nlsrTokenizer::makeRestOfTheLine()
+    {
+        restOfTheLine=getTokenString(1);
+    }
+
+    bool
+    nlsrTokenizer::doesTokenExist(string token)
+    {
+        std::list<string >::iterator it = std::find_if( tokenList.begin(),
+                                          tokenList.end(),
+                                          bind(&tokenCompare, _1 , token));
+        if( it != tokenList.end() )
+        {
+            return true;
+        }
+        return false;
+    }
+
+}//namespace nlsr
diff --git a/src/utility/nlsr_tokenizer.hpp b/src/utility/nlsr_tokenizer.hpp
new file mode 100644
index 0000000..6cd97e0
--- /dev/null
+++ b/src/utility/nlsr_tokenizer.hpp
@@ -0,0 +1,104 @@
+#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)
+            : firstToken()
+            , restOfTheLine()
+            , currentPosition(0)
+        {
+            seps = " ";
+            originalString = inputString;
+            makeToken();
+        }
+
+        nlsrTokenizer(const string& inputString, const string& separator)
+            : firstToken()
+            , restOfTheLine()
+            , currentPosition(0)
+        {
+            seps = separator;
+            originalString = inputString;
+            makeToken();
+        }
+
+        string getFirstToken()
+        {
+            return firstToken;
+        }
+
+        string getRestOfLine()
+        {
+            return restOfTheLine;
+        }
+
+        void resetCurrentPosition(uint32_t cp=0)
+        {
+            if( cp >=0 && cp <= vTokenList.size() )
+            {
+                currentPosition=cp;
+            }
+        }
+
+        string getNextToken()
+        {
+            if(currentPosition >= 0 && currentPosition <= (vTokenList.size()-1))
+            {
+                return vTokenList[currentPosition++];
+            }
+            return "";
+        }
+
+        uint32_t getTokenNumber()
+        {
+            return tokenList.size();
+        }
+
+        string getToken(int position)
+        {
+            if( position >=0 && position <vTokenList.size() )
+            {
+                return 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 seps;
+        string originalString;
+        string firstToken;
+        string restOfTheLine;
+        std::list<string> tokenList;
+        std::vector<string> vTokenList;
+        uint32_t currentPosition;
+    };
+
+}//namespace nlsr
+#endif
