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
