diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
index 5365630..e425767 100644
--- a/src/communication/nlsr_dm.cpp
+++ b/src/communication/nlsr_dm.cpp
@@ -14,182 +14,198 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    void
-    DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
-                                const ndn::Data & data, interestManager& im)
+  void
+  DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                              const ndn::Data & data, interestManager& im)
+  {
+    cout << "I: " << interest.toUri() << endl;
+    string dataName(data.getName().toUri());
+    nlsrTokenizer nt(dataName,"/");
+    std::string chkString("keys");
+    if( nt.doesTokenExist(chkString) )
     {
-        cout << "I: " << interest.toUri() << endl;
-        string dataName(data.getName().toUri());
-        nlsrTokenizer nt(dataName,"/");
-        string chkString("info");
+      processContentKeys(pnlsr, data);
+    }
+    else
+    {
+      if ( pnlsr.getKeyManager().verify(data))
+      {
+        std::cout<<"Verified Data Content"<<std::endl;
+        chkString="info";
         if( nt.doesTokenExist(chkString) )
         {
-            string dataContent((char *)data.getContent().value());
-            processContentInfo(pnlsr,dataName,dataContent);
+          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);
+          string dataContent((char *)data.getContent().value());
+          processContentLsa(pnlsr, dataName, dataContent);
         }
-        chkString="keys";
-        if( nt.doesTokenExist(chkString) )
-        {
-            processContentKeys(pnlsr, data);
-        }
+      }
+      else
+      {
+        std::cout<<"Unverified Data Content. Discarded"<<std::endl;
+      }
     }
+  }
 
-    void
-    DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
-                                    string& dataContent)
+  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
     {
-        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)));
-            }
-        }
+      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)
+  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
     {
-        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;
-        }
+      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)
+  void
+  DataManager::processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+                                     uint32_t lsSeqNo, string& dataContent)
+  {
+    if ( pnlsr.getLsdb().isNameLsaNew(lsaKey,lsSeqNo))
     {
-        if ( pnlsr.getLsdb().isNameLsaNew(lsaKey,lsSeqNo))
-        {
-            NameLsa nameLsa;
-            if( nameLsa.initNameLsaFromContent(dataContent) )
-            {
-                pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
-            }
-            else
-            {
-                cout<<"LSA data decoding error :("<<endl;
-            }
-        }
+      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)
+  void
+  DataManager::processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+                                    uint32_t lsSeqNo, string& dataContent)
+  {
+    if ( pnlsr.getLsdb().isAdjLsaNew(lsaKey,lsSeqNo))
     {
-        if ( pnlsr.getLsdb().isAdjLsaNew(lsaKey,lsSeqNo))
-        {
-            AdjLsa adjLsa;
-            if( adjLsa.initAdjLsaFromContent(dataContent) )
-            {
-                pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
-            }
-            else
-            {
-                cout<<"LSA data decoding error :("<<endl;
-            }
-        }
+      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)
+  void
+  DataManager::processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+                                    uint32_t lsSeqNo, string& dataContent)
+  {
+    if ( pnlsr.getLsdb().isCorLsaNew(lsaKey,lsSeqNo))
     {
-        if ( pnlsr.getLsdb().isCorLsaNew(lsaKey,lsSeqNo))
-        {
-            CorLsa corLsa;
-            if( corLsa.initCorLsaFromContent(dataContent) )
-            {
-                pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
-            }
-            else
-            {
-                cout<<"LSA data decoding error :("<<endl;
-            }
-        }
+      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)
+  }
+
+  void
+  DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
+  {
+    cout<<" processContentKeys called "<<endl;
+    ndn::shared_ptr<ndn::IdentityCertificate> cert=
+      ndn::make_shared<ndn::IdentityCertificate>();
+    cert->wireDecode(data.getContent().blockFromValue());
+    cout<<*(cert)<<endl;
+    std::string dataName=data.getName().toUri();
+    nlsrTokenizer nt(dataName,"/");
+    std::string certName=nt.getTokenString(0,nt.getTokenNumber()-3);
+    uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(
+                      nt.getTokenNumber()-2));
+    cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
+    if ( pnlsr.getKeyManager().verify(*(cert)))
     {
-        cout<<" processContentKeys called "<<endl;
-        ndn::shared_ptr<ndn::IdentityCertificate> cert=ndn::make_shared<ndn::IdentityCertificate>();
-        cert->wireDecode(data.getContent().blockFromValue());
-        cout<<*(cert)<<endl;
-        std::string dataName=data.getName().toUri();
-        nlsrTokenizer nt(dataName,"/");
-        std::string certName=nt.getTokenString(0,nt.getTokenNumber()-3);
-        uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber()-2));
-        cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
-        pnlsr.getKeyManager().addCertificate(cert, seqNum, true);
-        pnlsr.getKeyManager().printCertStore();
+      pnlsr.getKeyManager().addCertificate(cert, seqNum, true);
+      //pnlsr.getKeyManager().printCertStore();
     }
+  }
 }//namespace nlsr
diff --git a/src/communication/nlsr_dm.hpp b/src/communication/nlsr_dm.hpp
index fdb45db..4a807f2 100644
--- a/src/communication/nlsr_dm.hpp
+++ b/src/communication/nlsr_dm.hpp
@@ -10,31 +10,31 @@
 namespace nlsr
 {
 
-    using namespace ndn;
-    using namespace std;
+  using namespace ndn;
+  using namespace std;
 
-    class Nlsr;
+  class Nlsr;
 
-    class DataManager
-    {
-    public:
-        void processContent(Nlsr& pnlsr, const ndn::Interest &interest,
-                            const ndn::Data& data, interestManager& im);
-    private:
-        void processContentInfo(Nlsr& pnlsr, 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);
-        
+  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
index de551bb..b22b445 100644
--- a/src/communication/nlsr_im.cpp
+++ b/src/communication/nlsr_im.cpp
@@ -14,306 +14,307 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    void
-    interestManager::processInterest( Nlsr& pnlsr,
-                                      const ndn::Name &name,
-                                      const ndn::Interest &interest)
+  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) )
     {
-        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);
+      string nbr=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+      cout <<"Neighbor: " << nbr <<endl;
+      processInterestInfo(pnlsr,nbr,interest);
     }
-
-    void
-    interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
-                                         const ndn::Interest &interest)
+    chkString="LSA";
+    if( nt.doesTokenExist(chkString) )
     {
-        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());
-            }
-        }
+      processInterestLsa(pnlsr,interest);
     }
-
-    void
-    interestManager::processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest)
+    chkString="keys";
+    if( nt.doesTokenExist(chkString) )
     {
-        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;
-        }
+      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::processInterestForNameLsa(Nlsr& pnlsr,
-            const ndn::Interest &interest,
-            string lsaKey, uint32_t interestedlsSeqNo)
+  void
+  interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                       const ndn::Interest &interest)
+  {
+    if ( pnlsr.getAdl().isNeighbor(neighbor) )
     {
-        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);
-            }
-        }
+      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::processInterestForAdjLsa(Nlsr& pnlsr,
-            const ndn::Interest &interest,
-            string lsaKey, uint32_t interestedlsSeqNo)
+  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
     {
-        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);
-            }
-        }
+      interestedLsType=boost::lexical_cast<uint8_t>(lsTypeString);
+      interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeqString);
     }
-
-    void
-    interestManager::processInterestForCorLsa(Nlsr& pnlsr,
-            const ndn::Interest &interest,
-            string lsaKey, uint32_t interestedlsSeqNo)
+    catch(std::exception &e)
     {
-        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);
-            }
-        }
+      return;
     }
-
-    void
-    interestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest)
+    cout <<"Ls Type: "<<interestedLsType<<endl;
+    if( lsTypeString == "1" ) //Name Lsa
     {
-        cout<<"processInterestKeys called "<<endl;
-        string intName=interest.getName().toUri();
-        cout<<"Interest Name for Key: "<<intName<<std::endl;
-        nlsrTokenizer nt(intName,"/");
-        std::string certName=nt.getTokenString(0,nt.getTokenNumber()-2);
-        uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber()-1));
-        cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
-        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
-                pnlsr.getKeyManager().getCertificateFromStore(certName,seqNum);
-        if( chkCert.second )
-        {
-           Data data(ndn::Name(interest.getName()).appendVersion()); 
-           data.setFreshnessPeriod(1000); //10 sec
-           data.setContent(chkCert.first->wireEncode());
-           pnlsr.getKeyManager().signData(data);
-           pnlsr.getNlsrFace()->put(data);
-        }
-        //std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
-        /*
-        ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate();
+      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
-        data.setContent(cert->wireEncode());
+        string content=nameLsa.first.getNameLsaData();
+        data.setContent((const uint8_t*)content.c_str(),content.size());
         pnlsr.getKeyManager().signData(data);
-        //std::ofstream outFile("data_sent");
-        //ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        cout << ">> D: " << data << endl;
         pnlsr.getNlsrFace()->put(data);
-        */ 
+      }
     }
+  }
 
-
-    void
-    interestManager::processInterestTimedOut(Nlsr& pnlsr,
-            const ndn::Interest &interest)
+  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 )
     {
-        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);
-        }
+      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::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
-            const ndn::Interest &interest)
+  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 )
     {
-        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)));
-            }
-        }
+      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::processInterestTimedOutLsa(Nlsr& pnlsr,
-            const ndn::Interest &interest)
+  void
+  interestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest)
+  {
+    cout<<"processInterestKeys called "<<endl;
+    string intName=interest.getName().toUri();
+    cout<<"Interest Name for Key: "<<intName<<std::endl;
+    nlsrTokenizer nt(intName,"/");
+    std::string certName=nt.getTokenString(0,nt.getTokenNumber()-2);
+    uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(
+                      nt.getTokenNumber()-1));
+    cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
+      pnlsr.getKeyManager().getCertificateFromStore(certName,seqNum);
+    if( chkCert.second )
     {
+      Data data(ndn::Name(interest.getName()).appendVersion());
+      data.setFreshnessPeriod(1000); //10 sec
+      data.setContent(chkCert.first->wireEncode());
+      pnlsr.getKeyManager().signData(data);
+      pnlsr.getNlsrFace()->put(data);
     }
+    //std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
+    /*
+    ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate();
+    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::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
-                                     int scope, int seconds)
+
+  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) )
     {
-        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));
+      string nbr=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+      processInterestTimedOutInfo( pnlsr , nbr , interest);
     }
-
-
-    void
-    interestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
+    chkString="LSA";
+    if( nt.doesTokenExist(chkString) )
     {
-        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());
+      processInterestTimedOutLsa(pnlsr, interest);
     }
+  }
 
-    void
-    interestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
+  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()))
     {
-        EventId eid=pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
-                    ndn::bind(&interestManager::sendScheduledInfoInterest, this,
-                              boost::ref(pnlsr),seconds));
+      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
index 330874f..c150e8f 100644
--- a/src/communication/nlsr_im.hpp
+++ b/src/communication/nlsr_im.hpp
@@ -8,44 +8,44 @@
 namespace nlsr
 {
 
-    using namespace ndn;
-    using namespace std;
+  using namespace ndn;
+  using namespace std;
 
-    class Nlsr;
+  class Nlsr;
 
-    class interestManager
+  class interestManager
+  {
+  public:
+    interestManager()
     {
-    public:
-        interestManager()
-        {
-        }
-        void processInterest(Nlsr& pnlsr, const ndn::Name &name,
+    }
+    void processInterest(Nlsr& pnlsr, const ndn::Name &name,
+                         const ndn::Interest &interest);
+    void processInterestInfo(Nlsr& pnlsr, string& neighbor,
                              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 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 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);
+    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:
+  private:
 
 
-    };
+  };
 
 }//namespace nlsr
 
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
index 94517ae..098610d 100644
--- a/src/communication/nlsr_slh.cpp
+++ b/src/communication/nlsr_slh.cpp
@@ -6,152 +6,152 @@
 
 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::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)
+  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++)
     {
-        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);
-        }
+      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::nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr)
+  {
+    cout<<"nsyncRemoveCallBack called ...."<<endl;
+  }
 
-    void
-    SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
-    {
-    }
+  void
+  SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
+  {
+  }
 
-    void
-    SyncLogicHandler::processUpdateFromSync(std::string updateName,
-                                            uint64_t seqNo,  Nlsr& pnlsr)
+  void
+  SyncLogicHandler::processUpdateFromSync(std::string updateName,
+                                          uint64_t seqNo,  Nlsr& pnlsr)
+  {
+    nlsrTokenizer nt(updateName,"/");
+    string chkString("LSA");
+    if( nt.doesTokenExist(chkString) )
     {
-        nlsrTokenizer nt(updateName,"/");
-        string chkString("LSA");
-        if( nt.doesTokenExist(chkString) )
-        {
-            //process LSA Update here
-            string routerName=nt.getTokenString(nt.getTokenPosition(chkString)+1);
-            processRoutingUpdateFromSync(routerName, seqNo, pnlsr);
-        }
-        chkString="keys";
-        if( nt.doesTokenExist(chkString) )
-        {
-            //process keys update here
-            std::string certName=nt.getTokenString(0);
-            processKeysUpdateFromSync(certName,seqNo, pnlsr);
-        }
+      //process LSA Update here
+      string routerName=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+      processRoutingUpdateFromSync(routerName, seqNo, pnlsr);
     }
+    chkString="keys";
+    if( nt.doesTokenExist(chkString) )
+    {
+      //process keys update here
+      std::string certName=nt.getTokenString(0);
+      processKeysUpdateFromSync(certName,seqNo, pnlsr);
+    }
+  }
 
-    void
-    SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
-            uint64_t seqNo,  Nlsr& pnlsr)
+  void
+  SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
+      uint64_t seqNo,  Nlsr& pnlsr)
+  {
+    if( routerName != pnlsr.getConfParameter().getRouterPrefix() )
     {
-        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());
-            }
-        }
+      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)
+  void
+  SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
+      uint64_t seqNo, Nlsr& pnlsr)
+  {
+    cout<<"Cert Name: "<<certName<<std::endl;
+    if ( pnlsr.getKeyManager().isNewCertificate(certName,seqNo) )
     {
-        cout<<"Cert Name: "<<certName<<std::endl;
-        if ( pnlsr.getKeyManager().isNewCertificate(certName,seqNo) )
-        {
-            string certNamePrefix=certName + "/" + 
-                                             boost::lexical_cast<string>(seqNo);
-            pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
-                              pnlsr.getConfParameter().getInterestResendTime());
-        }
+      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::publishRoutingUpdate(SequencingManager& sm,
+                                         string updatePrefix)
+  {
+    sm.writeSeqNoToFile();
+    publishSyncUpdate(updatePrefix,sm.getCombinedSeqNo());
+  }
 
-    void
-    SyncLogicHandler::publishKeyUpdate(KeyManager& km)
-    {
-        publishSyncUpdate(km.getRootCertName().toUri(), 10);
-        publishSyncUpdate(km.getSiteCertName().toUri(), 10);
-        publishSyncUpdate(km.getOperatorCertName().toUri(), 10);
-        publishSyncUpdate(km.getRouterCertName().toUri(), km.getCertSeqNo());
-        publishSyncUpdate(km.getProcessCertName().toUri(),km.getCertSeqNo());
-    }
+  void
+  SyncLogicHandler::publishKeyUpdate(KeyManager& km)
+  {
+    publishSyncUpdate(km.getRootCertName().toUri(), 10);
+    publishSyncUpdate(km.getSiteCertName().toUri(), 10);
+    publishSyncUpdate(km.getOperatorCertName().toUri(), 10);
+    publishSyncUpdate(km.getRouterCertName().toUri(), km.getCertSeqNo());
+    publishSyncUpdate(km.getProcessCertName().toUri(),km.getCertSeqNo());
+  }
 
-    void
-    SyncLogicHandler::publishIdentityUpdate(string identityName)
-    {
-        publishSyncUpdate(identityName,0);
-    }
+  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);
-    }
+  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
index 3fef612..420210d 100644
--- a/src/communication/nlsr_slh.hpp
+++ b/src/communication/nlsr_slh.hpp
@@ -25,41 +25,41 @@
 
 namespace nlsr
 {
-    class SyncLogicHandler
+  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)
     {
-    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,
+      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 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;
-    };
+    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
