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
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index f28835f..e2c8e57 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -18,78 +18,74 @@
 namespace nlsr
 {
 
-    using namespace ndn;
-    using namespace std;
+  using namespace ndn;
+  using namespace std;
 
-    void
-    Nlsr::nlsrRegistrationFailed(const ndn::Name& name)
+  void
+  Nlsr::nlsrRegistrationFailed(const ndn::Name& name)
+  {
+    cerr << "ERROR: Failed to register prefix in local hub's daemon" << endl;
+    getNlsrFace()->shutdown();
+  }
+
+
+  void
+  Nlsr::setInterestFilterNlsr(const string& name)
+  {
+    getNlsrFace()->setInterestFilter(name,
+                                     func_lib::bind(&interestManager::processInterest, &im,
+                                         boost::ref(*this), _1, _2),
+                                     func_lib::bind(&Nlsr::nlsrRegistrationFailed, this, _1));
+  }
+
+  void
+  Nlsr::initNlsr()
+  {
+    confParam.buildRouterPrefix();
+    nlsrLogger.initNlsrLogger(confParam.getLogDir());
+    nlsrLsdb.setLsaRefreshTime(confParam.getLsaRefreshTime());
+    nlsrLsdb.setThisRouterPrefix(confParam.getRouterPrefix());
+    fib.setFibEntryRefreshTime(2*confParam.getLsaRefreshTime());
+    if( ! km.initKeyManager(confParam) )
     {
-        cerr << "ERROR: Failed to register prefix in local hub's daemon" << endl;
-        getNlsrFace()->shutdown();
+      std::cerr<<"Can not initiate certificate"<<endl;
     }
+    sm.setSeqFileName(confParam.getSeqFileDir());
+    sm.initiateSeqNoFromFile();
+    /* debugging purpose start */
+    cout <<	confParam;
+    adl.printAdl();
+    npl.printNpl();
+    /* debugging purpose end */
+    nlsrLsdb.buildAndInstallOwnNameLsa(boost::ref(*this));
+    nlsrLsdb.buildAndInstallOwnCorLsa(boost::ref(*this));
+    setInterestFilterNlsr(confParam.getRouterPrefix());
+    setInterestFilterNlsr(confParam.getChronosyncLsaPrefix()+
+                          confParam.getRouterPrefix());
+    setInterestFilterNlsr(confParam.getRootKeyPrefix());
+    slh.setSyncPrefix(confParam.getChronosyncSyncPrefix());
+    slh.createSyncSocket(boost::ref(*this));
+    slh.publishKeyUpdate(km);
+    im.scheduleInfoInterest(boost::ref(*this),10);
+  }
 
+  void
+  Nlsr::startEventLoop()
+  {
+    io->run();
+  }
 
-    void
-    Nlsr::setInterestFilterNlsr(const string& name)
-    {
-        getNlsrFace()->setInterestFilter(name,
-                                         func_lib::bind(&interestManager::processInterest, &im,
-                                                 boost::ref(*this), _1, _2),
-                                         func_lib::bind(&Nlsr::nlsrRegistrationFailed, this, _1));
-    }
-
-    void
-    Nlsr::initNlsr()
-    {
-        confParam.buildRouterPrefix();
-        nlsrLogger.initNlsrLogger(confParam.getLogDir());
-        nlsrLsdb.setLsaRefreshTime(confParam.getLsaRefreshTime());
-        nlsrLsdb.setThisRouterPrefix(confParam.getRouterPrefix());
-        fib.setFibEntryRefreshTime(2*confParam.getLsaRefreshTime());
-        if( ! km.initKeyManager(confParam) )
-        {
-            std::cerr<<"Can not initiate certificate"<<endl;
-        }
-        
-        sm.setSeqFileName(confParam.getSeqFileDir());
-        sm.initiateSeqNoFromFile();
-        
-        /* debugging purpose start */
-        cout <<	confParam;
-        adl.printAdl();
-        npl.printNpl();
-        /* debugging purpose end */
-        
-        nlsrLsdb.buildAndInstallOwnNameLsa(boost::ref(*this));
-        nlsrLsdb.buildAndInstallOwnCorLsa(boost::ref(*this));
-        setInterestFilterNlsr(confParam.getRouterPrefix());
-        setInterestFilterNlsr(confParam.getChronosyncLsaPrefix()+
-                                                   confParam.getRouterPrefix());
-        setInterestFilterNlsr(confParam.getRootKeyPrefix());
-        slh.setSyncPrefix(confParam.getChronosyncSyncPrefix());
-        slh.createSyncSocket(boost::ref(*this));
-        slh.publishKeyUpdate(km);
-    
-        im.scheduleInfoInterest(boost::ref(*this),10);
-    }
-
-    void
-    Nlsr::startEventLoop()
-    {
-        io->run();
-    }
-
-    int
-    Nlsr::usage(const string& progname)
-    {
-        cout << "Usage: " << progname << " [OPTIONS...]"<<endl;
-        cout << "   NDN routing...." << endl;
-        cout << "       -d, --daemon        Run in daemon mode" << endl;
-        cout << "       -f, --config_file   Specify configuration file name" <<endl;
-        cout << "       -p, --api_port      port where api client will connect" <<endl;
-        cout << "       -h, --help          Display this help message" << endl;
-        exit(EXIT_FAILURE);
-    }
+  int
+  Nlsr::usage(const string& progname)
+  {
+    cout << "Usage: " << progname << " [OPTIONS...]"<<endl;
+    cout << "   NDN routing...." << endl;
+    cout << "       -d, --daemon        Run in daemon mode" << endl;
+    cout << "       -f, --config_file   Specify configuration file name" <<endl;
+    cout << "       -p, --api_port      port where api client will connect" <<endl;
+    cout << "       -h, --help          Display this help message" << endl;
+    exit(EXIT_FAILURE);
+  }
 
 
 } // namespace nlsr
@@ -99,49 +95,48 @@
 int
 main(int argc, char **argv)
 {
-    nlsr::Nlsr nlsr_;
-    string programName(argv[0]);
-    nlsr_.setConfFileName("nlsr.conf");
-    int opt;
-    while ((opt = getopt(argc, argv, "df:p:h")) != -1)
+  nlsr::Nlsr nlsr_;
+  string programName(argv[0]);
+  nlsr_.setConfFileName("nlsr.conf");
+  int opt;
+  while ((opt = getopt(argc, argv, "df:p:h")) != -1)
+  {
+    switch (opt)
     {
-        switch (opt)
+      case 'f':
+        nlsr_.setConfFileName(optarg);
+        break;
+      case 'd':
+        nlsr_.setIsDaemonProcess(optarg);
+        break;
+      case 'p':
         {
-            case 'f':
-                nlsr_.setConfFileName(optarg);
-                break;
-            case 'd':
-                nlsr_.setIsDaemonProcess(optarg);
-                break;
-            case 'p':
-                {
-                    stringstream sst(optarg);
-                    int ap;
-                    sst>>ap;
-                    nlsr_.setApiPort(ap);
-                }
-                break;
-            case 'h':
-            default:
-                nlsr_.usage(programName);
-                return EXIT_FAILURE;
+          stringstream sst(optarg);
+          int ap;
+          sst>>ap;
+          nlsr_.setApiPort(ap);
         }
-    }
-    ConfFileProcessor cfp(nlsr_.getConfFileName());
-    int res=cfp.processConfFile(nlsr_);
-    if ( res < 0 )
-    {
+        break;
+      case 'h':
+      default:
+        nlsr_.usage(programName);
         return EXIT_FAILURE;
     }
-    nlsr_.initNlsr();
-    
-    try
-    {
-        nlsr_.startEventLoop();
-    }
-    catch(std::exception &e)
-    {
-        std::cerr << "ERROR: " << e.what() << std::endl;
-    }
-    return EXIT_SUCCESS;
+  }
+  ConfFileProcessor cfp(nlsr_.getConfFileName());
+  int res=cfp.processConfFile(nlsr_);
+  if ( res < 0 )
+  {
+    return EXIT_FAILURE;
+  }
+  nlsr_.initNlsr();
+  try
+  {
+    nlsr_.startEventLoop();
+  }
+  catch(std::exception &e)
+  {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+  }
+  return EXIT_SUCCESS;
 }
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index 51218f0..ffdcdc1 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -24,233 +24,233 @@
 namespace nlsr
 {
 
-    using namespace ndn;
-    using namespace std;
+  using namespace ndn;
+  using namespace std;
 
-    class Nlsr
+  class Nlsr
+  {
+  public:
+    Nlsr()
+      : io(ndn::make_shared<boost::asio::io_service>())
+      , nlsrFace(make_shared<ndn::Face>(io))
+      , scheduler(*io)
+      , confParam()
+      , adl()
+      , npl()
+      , im()
+      , dm()
+      , sm()
+      , km()
+      , isDaemonProcess(false)
+      , configFileName("nlsr.conf")
+      , nlsrLsdb()
+      , adjBuildCount(0)
+      , isBuildAdjLsaSheduled(0)
+      , isRouteCalculationScheduled(0)
+      , isRoutingTableCalculating(0)
+      , routingTable()
+      , npt()
+      , fib()
+      , slh(io)
+      , nlsrLogger()
+    {}
+
+    void nlsrRegistrationFailed(const ndn::Name& name);
+
+    void setInterestFilterNlsr(const string& name);
+    void startEventLoop();
+
+    int usage(const string& progname);
+
+    string getConfFileName()
     {
-    public:
-        Nlsr()
-            : io(ndn::make_shared<boost::asio::io_service>())
-            , nlsrFace(make_shared<ndn::Face>(io))
-            , scheduler(*io)
-            , confParam()
-            , adl()
-            , npl()
-            , im()
-            , dm()
-            , sm()
-            , km()
-            , isDaemonProcess(false)
-            , configFileName("nlsr.conf")
-            , nlsrLsdb()
-            , adjBuildCount(0)
-            , isBuildAdjLsaSheduled(0)
-            , isRouteCalculationScheduled(0)
-            , isRoutingTableCalculating(0)
-            , routingTable()
-            , npt()
-            , fib()
-            , slh(io)
-            , nlsrLogger()
-        {}
+      return configFileName;
+    }
 
-        void nlsrRegistrationFailed(const ndn::Name& name);
+    void setConfFileName(const string& fileName)
+    {
+      configFileName=fileName;
+    }
 
-        void setInterestFilterNlsr(const string& name);
-        void startEventLoop();
+    bool isSetDaemonProcess()
+    {
+      return isDaemonProcess;
+    }
 
-        int usage(const string& progname);
+    void setIsDaemonProcess(bool value)
+    {
+      isDaemonProcess=value;
+    }
 
-        string getConfFileName()
-        {
-            return configFileName;
-        }
+    ConfParameter& getConfParameter()
+    {
+      return confParam;
+    }
 
-        void setConfFileName(const string& fileName)
-        {
-            configFileName=fileName;
-        }
+    Adl& getAdl()
+    {
+      return adl;
+    }
 
-        bool isSetDaemonProcess()
-        {
-            return isDaemonProcess;
-        }
+    Npl& getNpl()
+    {
+      return npl;
+    }
 
-        void setIsDaemonProcess(bool value)
-        {
-            isDaemonProcess=value;
-        }
+    ndn::shared_ptr<boost::asio::io_service>& getIo()
+    {
+      return io;
+    }
 
-        ConfParameter& getConfParameter()
-        {
-            return confParam;
-        }
+    ndn::Scheduler& getScheduler()
+    {
+      return scheduler;
+    }
 
-        Adl& getAdl()
-        {
-            return adl;
-        }
+    ndn::shared_ptr<ndn::Face> getNlsrFace()
+    {
+      return nlsrFace;
+    }
 
-        Npl& getNpl()
-        {
-            return npl;
-        }
-
-        ndn::shared_ptr<boost::asio::io_service>& getIo()
-        {
-            return io;
-        }
-
-        ndn::Scheduler& getScheduler()
-        {
-            return scheduler;
-        }
-
-        ndn::shared_ptr<ndn::Face> getNlsrFace()
-        {
-            return nlsrFace;
-        }
-
-        KeyManager& getKeyManager()
-        {
-            return km;
-        }
+    KeyManager& getKeyManager()
+    {
+      return km;
+    }
 
 
-        interestManager& getIm()
-        {
-            return im;
-        }
+    interestManager& getIm()
+    {
+      return im;
+    }
 
-        DataManager& getDm()
-        {
-            return dm;
-        }
+    DataManager& getDm()
+    {
+      return dm;
+    }
 
-        SequencingManager& getSm()
-        {
-            return sm;
-        }
+    SequencingManager& getSm()
+    {
+      return sm;
+    }
 
-        Lsdb& getLsdb()
-        {
-            return nlsrLsdb;
-        }
+    Lsdb& getLsdb()
+    {
+      return nlsrLsdb;
+    }
 
-        RoutingTable& getRoutingTable()
-        {
-            return routingTable;
-        }
+    RoutingTable& getRoutingTable()
+    {
+      return routingTable;
+    }
 
-        Npt& getNpt()
-        {
-            return npt;
-        }
+    Npt& getNpt()
+    {
+      return npt;
+    }
 
-        Fib& getFib()
-        {
-            return fib;
-        }
+    Fib& getFib()
+    {
+      return fib;
+    }
 
-        long int getAdjBuildCount()
-        {
-            return adjBuildCount;
-        }
+    long int getAdjBuildCount()
+    {
+      return adjBuildCount;
+    }
 
-        void incrementAdjBuildCount()
-        {
-            adjBuildCount++;
-        }
+    void incrementAdjBuildCount()
+    {
+      adjBuildCount++;
+    }
 
-        void setAdjBuildCount(long int abc)
-        {
-            adjBuildCount=abc;
-        }
+    void setAdjBuildCount(long int abc)
+    {
+      adjBuildCount=abc;
+    }
 
-        int getIsBuildAdjLsaSheduled()
-        {
-            return isBuildAdjLsaSheduled;
-        }
+    int getIsBuildAdjLsaSheduled()
+    {
+      return isBuildAdjLsaSheduled;
+    }
 
-        void setIsBuildAdjLsaSheduled(int iabls)
-        {
-            isBuildAdjLsaSheduled=iabls;
-        }
+    void setIsBuildAdjLsaSheduled(int iabls)
+    {
+      isBuildAdjLsaSheduled=iabls;
+    }
 
 
-        void setApiPort(int ap)
-        {
-            apiPort=ap;
-        }
+    void setApiPort(int ap)
+    {
+      apiPort=ap;
+    }
 
-        int getApiPort()
-        {
-            return apiPort;
-        }
+    int getApiPort()
+    {
+      return apiPort;
+    }
 
-        int getIsRoutingTableCalculating()
-        {
-            return isRoutingTableCalculating;
-        }
+    int getIsRoutingTableCalculating()
+    {
+      return isRoutingTableCalculating;
+    }
 
-        void setIsRoutingTableCalculating(int irtc)
-        {
-            isRoutingTableCalculating=irtc;
-        }
+    void setIsRoutingTableCalculating(int irtc)
+    {
+      isRoutingTableCalculating=irtc;
+    }
 
-        int getIsRouteCalculationScheduled()
-        {
-            return isRouteCalculationScheduled;
-        }
+    int getIsRouteCalculationScheduled()
+    {
+      return isRouteCalculationScheduled;
+    }
 
-        void setIsRouteCalculationScheduled(int ircs)
-        {
-            isRouteCalculationScheduled=ircs;
-        }
+    void setIsRouteCalculationScheduled(int ircs)
+    {
+      isRouteCalculationScheduled=ircs;
+    }
 
-        SyncLogicHandler& getSlh()
-        {
-            return slh;
-        }
+    SyncLogicHandler& getSlh()
+    {
+      return slh;
+    }
 
-        NlsrLogger& getNlsrLogger()
-        {
-            return nlsrLogger;
-        }
+    NlsrLogger& getNlsrLogger()
+    {
+      return nlsrLogger;
+    }
 
-        void initNlsr();
+    void initNlsr();
 
-    private:
-        ConfParameter confParam;
-        Adl adl;
-        Npl npl;
-        ndn::shared_ptr<boost::asio::io_service> io;
-        ndn::Scheduler scheduler;
-        ndn::shared_ptr<ndn::Face> nlsrFace;
-        interestManager im;
-        DataManager dm;
-        SequencingManager sm;
-        KeyManager km;
-        bool isDaemonProcess;
-        string configFileName;
-        int apiPort;
+  private:
+    ConfParameter confParam;
+    Adl adl;
+    Npl npl;
+    ndn::shared_ptr<boost::asio::io_service> io;
+    ndn::Scheduler scheduler;
+    ndn::shared_ptr<ndn::Face> nlsrFace;
+    interestManager im;
+    DataManager dm;
+    SequencingManager sm;
+    KeyManager km;
+    bool isDaemonProcess;
+    string configFileName;
+    int apiPort;
 
-        Lsdb nlsrLsdb;
-        RoutingTable routingTable;
-        Npt npt;
-        Fib fib;
-        SyncLogicHandler slh;
-        NlsrLogger nlsrLogger;
+    Lsdb nlsrLsdb;
+    RoutingTable routingTable;
+    Npt npt;
+    Fib fib;
+    SyncLogicHandler slh;
+    NlsrLogger nlsrLogger;
 
-        long int adjBuildCount;
-        int isBuildAdjLsaSheduled;
-        int isRouteCalculationScheduled;
-        int isRoutingTableCalculating;
+    long int adjBuildCount;
+    int isBuildAdjLsaSheduled;
+    int isRouteCalculationScheduled;
+    int isRoutingTableCalculating;
 
 
 
-    };
+  };
 
 } //namespace nlsr
 
diff --git a/src/nlsr_adjacent.cpp b/src/nlsr_adjacent.cpp
index 6cc4db0..f636e5c 100644
--- a/src/nlsr_adjacent.cpp
+++ b/src/nlsr_adjacent.cpp
@@ -8,35 +8,35 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    Adjacent::Adjacent(const string& an, int cf, double lc, int s, int iton)
-    {
-        adjacentName=an;
-        connectingFace=cf;
-        linkCost=lc;
-        status=s;
-        interestTimedOutNo=iton;
-    }
+  Adjacent::Adjacent(const string& an, int cf, double lc, int s, int iton)
+  {
+    adjacentName=an;
+    connectingFace=cf;
+    linkCost=lc;
+    status=s;
+    interestTimedOutNo=iton;
+  }
 
-    bool
-    Adjacent::isAdjacentEqual(Adjacent& adj)
-    {
-        return ( adjacentName == adj.getAdjacentName() ) &&
-               ( connectingFace == adj.getConnectingFace() ) &&
-               (std::abs(linkCost - adj.getLinkCost()) <
-                std::numeric_limits<double>::epsilon()) ;
-    }
+  bool
+  Adjacent::isAdjacentEqual(Adjacent& adj)
+  {
+    return ( adjacentName == adj.getAdjacentName() ) &&
+           ( connectingFace == adj.getConnectingFace() ) &&
+           (std::abs(linkCost - adj.getLinkCost()) <
+            std::numeric_limits<double>::epsilon()) ;
+  }
 
-    std::ostream&
-    operator << (std::ostream &os, Adjacent &adj)
-    {
-        cout<<"Adjacent : "<< adj.getAdjacentName()	<< endl;
-        cout<<"Connecting Face: "<<adj.getConnectingFace()<<endl;
-        cout<<"Link Cost: "<<adj.getLinkCost()<<endl;
-        cout<<"Status: "<<adj.getStatus()<<endl;
-        cout<<"Interest Timed out: "<<adj.getInterestTimedOutNo()<<endl;
-        return os;
-    }
+  std::ostream&
+  operator << (std::ostream &os, Adjacent &adj)
+  {
+    cout<<"Adjacent : "<< adj.getAdjacentName()	<< endl;
+    cout<<"Connecting Face: "<<adj.getConnectingFace()<<endl;
+    cout<<"Link Cost: "<<adj.getLinkCost()<<endl;
+    cout<<"Status: "<<adj.getStatus()<<endl;
+    cout<<"Interest Timed out: "<<adj.getInterestTimedOutNo()<<endl;
+    return os;
+  }
 
 } //namespace nlsr
diff --git a/src/nlsr_adjacent.hpp b/src/nlsr_adjacent.hpp
index 8d97db6..23f334c 100644
--- a/src/nlsr_adjacent.hpp
+++ b/src/nlsr_adjacent.hpp
@@ -4,93 +4,93 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Adjacent
+  class Adjacent
+  {
+
+  public:
+    Adjacent()
+      :adjacentName()
+      ,connectingFace(0)
+      ,linkCost(10.0)
+      ,status(0)
+      ,interestTimedOutNo(0)
     {
+    }
 
-    public:
-        Adjacent()
-            :adjacentName()
-            ,connectingFace(0)
-            ,linkCost(10.0)
-            ,status(0)
-            ,interestTimedOutNo(0)
-        {
-        }
+    Adjacent(const string& an)
+      :connectingFace(0)
+      ,linkCost(0.0)
+      ,status(0)
+      ,interestTimedOutNo(0)
+    {
+      adjacentName=an;
+    }
 
-        Adjacent(const string& an)
-            :connectingFace(0)
-            ,linkCost(0.0)
-            ,status(0)
-            ,interestTimedOutNo(0)
-        {
-            adjacentName=an;
-        }
+    Adjacent(const string& an, int cf, double lc, int s, int iton);
 
-        Adjacent(const string& an, int cf, double lc, int s, int iton);
+    string getAdjacentName()
+    {
+      return adjacentName;
+    }
 
-        string getAdjacentName()
-        {
-            return adjacentName;
-        }
+    void setAdjacentName(const string& an)
+    {
+      adjacentName=an;
+    }
 
-        void setAdjacentName(const string& an)
-        {
-            adjacentName=an;
-        }
+    int getConnectingFace()
+    {
+      return connectingFace;
+    }
 
-        int getConnectingFace()
-        {
-            return connectingFace;
-        }
+    void setConnectingFace(int cf)
+    {
+      connectingFace=cf;
+    }
 
-        void setConnectingFace(int cf)
-        {
-            connectingFace=cf;
-        }
+    double getLinkCost()
+    {
+      return linkCost;
+    }
 
-        double getLinkCost()
-        {
-            return linkCost;
-        }
+    void setLinkCost(double lc)
+    {
+      linkCost=lc;
+    }
 
-        void setLinkCost(double lc)
-        {
-            linkCost=lc;
-        }
+    int getStatus()
+    {
+      return status;
+    }
 
-        int getStatus()
-        {
-            return status;
-        }
+    void setStatus(int s)
+    {
+      status=s;
+    }
 
-        void setStatus(int s)
-        {
-            status=s;
-        }
+    int getInterestTimedOutNo()
+    {
+      return interestTimedOutNo;
+    }
 
-        int getInterestTimedOutNo()
-        {
-            return interestTimedOutNo;
-        }
+    void setInterestTimedOutNo(int iton)
+    {
+      interestTimedOutNo=iton;
+    }
 
-        void setInterestTimedOutNo(int iton)
-        {
-            interestTimedOutNo=iton;
-        }
+    bool isAdjacentEqual(Adjacent& adj);
+  private:
+    string adjacentName;
+    int connectingFace;
+    double linkCost;
+    int status;
+    int interestTimedOutNo;
+  };
 
-        bool isAdjacentEqual(Adjacent& adj);
-    private:
-        string adjacentName;
-        int connectingFace;
-        double linkCost;
-        int status;
-        int interestTimedOutNo;
-    };
-
-    std::ostream&
-    operator << (std::ostream &os, Adjacent &adj);
+  std::ostream&
+  operator << (std::ostream &os, Adjacent &adj);
 
 } // namespace nlsr
 
diff --git a/src/nlsr_adl.cpp b/src/nlsr_adl.cpp
index 0d47e67..ab5db84 100644
--- a/src/nlsr_adl.cpp
+++ b/src/nlsr_adl.cpp
@@ -8,254 +8,254 @@
 namespace nlsr
 {
 
-    Adl::Adl()
-    {
-    }
+  Adl::Adl()
+  {
+  }
 
-    Adl::~Adl()
-    {
-    }
+  Adl::~Adl()
+  {
+  }
 
-    static bool
-    adjacent_compare(Adjacent& adj1, Adjacent& adj2)
-    {
-        return adj1.getAdjacentName()==adj2.getAdjacentName();
-    }
+  static bool
+  adjacent_compare(Adjacent& adj1, Adjacent& adj2)
+  {
+    return adj1.getAdjacentName()==adj2.getAdjacentName();
+  }
 
-    int
-    Adl::insert(Adjacent& adj)
+  int
+  Adl::insert(Adjacent& adj)
+  {
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if ( it != adjList.end() )
     {
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if ( it != adjList.end() )
+      return -1;
+    }
+    adjList.push_back(adj);
+    return 0;
+  }
+
+  void
+  Adl::addAdjacentsFromAdl(Adl& adl)
+  {
+    for(std::list<Adjacent >::iterator it=adl.getAdjList().begin();
+        it!=adl.getAdjList().end(); ++it)
+    {
+      insert((*it));
+    }
+  }
+
+  int
+  Adl::updateAdjacentStatus(string adjName, int s)
+  {
+    Adjacent adj(adjName);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it == adjList.end())
+    {
+      return -1;
+    }
+    (*it).setStatus(s);
+    return 0;
+  }
+
+  Adjacent
+  Adl::getAdjacent(string adjName)
+  {
+    Adjacent adj(adjName);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it != adjList.end())
+    {
+      return (*it);
+    }
+    return adj;
+  }
+
+
+  bool
+  Adl::isAdlEqual(Adl &adl)
+  {
+    if ( getAdlSize() != adl.getAdlSize() )
+    {
+      return false;
+    }
+    adjList.sort(adjacent_compare);
+    adl.getAdjList().sort(adjacent_compare);
+    int equalAdjCount=0;
+    std::list< Adjacent > adjList2=adl.getAdjList();
+    std::list<Adjacent>::iterator it1;
+    std::list<Adjacent>::iterator it2;
+    for(it1=adjList.begin() , it2=adjList2.begin() ;
+        it1!=adjList.end(); it1++,it2++)
+    {
+      if ( !(*it1).isAdjacentEqual((*it2)) )
+      {
+        break;
+      }
+      equalAdjCount++;
+    }
+    return equalAdjCount==getAdlSize();
+  }
+
+
+  int
+  Adl::updateAdjacentLinkCost(string adjName, double lc)
+  {
+    Adjacent adj(adjName);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it == adjList.end())
+    {
+      return -1;
+    }
+    (*it).setLinkCost(lc);
+    return 0;
+  }
+
+  bool
+  Adl::isNeighbor(string adjName)
+  {
+    Adjacent adj(adjName);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it == adjList.end())
+    {
+      return false;
+    }
+    return true;
+  }
+
+  void
+  Adl::incrementTimedOutInterestCount(string& neighbor)
+  {
+    Adjacent adj(neighbor);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it == adjList.end())
+    {
+      return ;
+    }
+    (*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
+  }
+
+  void
+  Adl::setTimedOutInterestCount(string& neighbor, int count)
+  {
+    Adjacent adj(neighbor);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it != adjList.end())
+    {
+      (*it).setInterestTimedOutNo(count);
+    }
+  }
+
+  int
+  Adl::getTimedOutInterestCount(string& neighbor)
+  {
+    Adjacent adj(neighbor);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it == adjList.end())
+    {
+      return -1;
+    }
+    return (*it).getInterestTimedOutNo();
+  }
+
+  int
+  Adl::getStatusOfNeighbor(string& neighbor)
+  {
+    Adjacent adj(neighbor);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it == adjList.end())
+    {
+      return -1;
+    }
+    return (*it).getStatus();
+  }
+
+  void
+  Adl::setStatusOfNeighbor(string& neighbor, int status)
+  {
+    Adjacent adj(neighbor);
+    std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                        adjList.end(),
+                                        bind(&adjacent_compare, _1, adj));
+    if( it != adjList.end())
+    {
+      (*it).setStatus(status);
+    }
+  }
+
+  std::list<Adjacent>&
+  Adl::getAdjList()
+  {
+    return adjList;
+  }
+
+  bool
+  Adl::isAdjLsaBuildable(Nlsr& pnlsr)
+  {
+    int nbrCount=0;
+    for( std::list<Adjacent>::iterator it=adjList.begin();
+         it!= adjList.end() ; it++)
+    {
+      if ( ((*it).getStatus() == 1 ) )
+      {
+        nbrCount++;
+      }
+      else
+      {
+        if ( (*it).getInterestTimedOutNo() >=
+             pnlsr.getConfParameter().getInterestRetryNumber())
         {
-            return -1;
+          nbrCount++;
         }
-        adjList.push_back(adj);
-        return 0;
+      }
     }
-
-    void
-    Adl::addAdjacentsFromAdl(Adl& adl)
+    if( nbrCount == adjList.size())
     {
-        for(std::list<Adjacent >::iterator it=adl.getAdjList().begin();
-                it!=adl.getAdjList().end(); ++it)
-        {
-            insert((*it));
-        }
+      return true;
     }
+    return false;
+  }
 
-    int
-    Adl::updateAdjacentStatus(string adjName, int s)
+  int
+  Adl::getNumOfActiveNeighbor()
+  {
+    int actNbrCount=0;
+    for( std::list<Adjacent>::iterator it=adjList.begin();
+         it!= adjList.end() ; it++)
     {
-        Adjacent adj(adjName);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it == adjList.end())
-        {
-            return -1;
-        }
-        (*it).setStatus(s);
-        return 0;
+      if ( ((*it).getStatus() == 1 ) )
+      {
+        actNbrCount++;
+      }
     }
-
-    Adjacent
-    Adl::getAdjacent(string adjName)
-    {
-        Adjacent adj(adjName);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it != adjList.end())
-        {
-            return (*it);
-        }
-        return adj;
-    }
-
-
-    bool
-    Adl::isAdlEqual(Adl &adl)
-    {
-        if ( getAdlSize() != adl.getAdlSize() )
-        {
-            return false;
-        }
-        adjList.sort(adjacent_compare);
-        adl.getAdjList().sort(adjacent_compare);
-        int equalAdjCount=0;
-        std::list< Adjacent > adjList2=adl.getAdjList();
-        std::list<Adjacent>::iterator it1;
-        std::list<Adjacent>::iterator it2;
-        for(it1=adjList.begin() , it2=adjList2.begin() ;
-                it1!=adjList.end(); it1++,it2++)
-        {
-            if ( !(*it1).isAdjacentEqual((*it2)) )
-            {
-                break;
-            }
-            equalAdjCount++;
-        }
-        return equalAdjCount==getAdlSize();
-    }
-
-
-    int
-    Adl::updateAdjacentLinkCost(string adjName, double lc)
-    {
-        Adjacent adj(adjName);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it == adjList.end())
-        {
-            return -1;
-        }
-        (*it).setLinkCost(lc);
-        return 0;
-    }
-
-    bool
-    Adl::isNeighbor(string adjName)
-    {
-        Adjacent adj(adjName);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it == adjList.end())
-        {
-            return false;
-        }
-        return true;
-    }
-
-    void
-    Adl::incrementTimedOutInterestCount(string& neighbor)
-    {
-        Adjacent adj(neighbor);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it == adjList.end())
-        {
-            return ;
-        }
-        (*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
-    }
-
-    void
-    Adl::setTimedOutInterestCount(string& neighbor, int count)
-    {
-        Adjacent adj(neighbor);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it != adjList.end())
-        {
-            (*it).setInterestTimedOutNo(count);
-        }
-    }
-
-    int
-    Adl::getTimedOutInterestCount(string& neighbor)
-    {
-        Adjacent adj(neighbor);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it == adjList.end())
-        {
-            return -1;
-        }
-        return (*it).getInterestTimedOutNo();
-    }
-
-    int
-    Adl::getStatusOfNeighbor(string& neighbor)
-    {
-        Adjacent adj(neighbor);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it == adjList.end())
-        {
-            return -1;
-        }
-        return (*it).getStatus();
-    }
-
-    void
-    Adl::setStatusOfNeighbor(string& neighbor, int status)
-    {
-        Adjacent adj(neighbor);
-        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
-                                            adjList.end(),
-                                            bind(&adjacent_compare, _1, adj));
-        if( it != adjList.end())
-        {
-            (*it).setStatus(status);
-        }
-    }
-
-    std::list<Adjacent>&
-    Adl::getAdjList()
-    {
-        return adjList;
-    }
-
-    bool
-    Adl::isAdjLsaBuildable(Nlsr& pnlsr)
-    {
-        int nbrCount=0;
-        for( std::list<Adjacent>::iterator it=adjList.begin();
-                it!= adjList.end() ; it++)
-        {
-            if ( ((*it).getStatus() == 1 ) )
-            {
-                nbrCount++;
-            }
-            else
-            {
-                if ( (*it).getInterestTimedOutNo() >=
-                        pnlsr.getConfParameter().getInterestRetryNumber())
-                {
-                    nbrCount++;
-                }
-            }
-        }
-        if( nbrCount == adjList.size())
-        {
-            return true;
-        }
-        return false;
-    }
-
-    int
-    Adl::getNumOfActiveNeighbor()
-    {
-        int actNbrCount=0;
-        for( std::list<Adjacent>::iterator it=adjList.begin();
-                it!= adjList.end() ; it++)
-        {
-            if ( ((*it).getStatus() == 1 ) )
-            {
-                actNbrCount++;
-            }
-        }
-        return actNbrCount;
-    }
+    return actNbrCount;
+  }
 
 // used for debugging purpose
-    void
-    Adl::printAdl()
+  void
+  Adl::printAdl()
+  {
+    for( std::list<Adjacent>::iterator it=adjList.begin(); it!= adjList.end() ;
+         it++)
     {
-        for( std::list<Adjacent>::iterator it=adjList.begin(); it!= adjList.end() ;
-                it++)
-        {
-            cout<< (*it) <<endl;
-        }
+      cout<< (*it) <<endl;
     }
+  }
 
 } //namespace nlsr
diff --git a/src/nlsr_adl.hpp b/src/nlsr_adl.hpp
index 4c44993..82edaf0 100644
--- a/src/nlsr_adl.hpp
+++ b/src/nlsr_adl.hpp
@@ -8,52 +8,52 @@
 namespace nlsr
 {
 
-    class Nlsr;
+  class Nlsr;
 
-    using namespace std;
+  using namespace std;
 
-    class Adl
+  class Adl
+  {
+
+  public:
+    Adl();
+    ~Adl();
+    int insert(Adjacent& adj);
+    int updateAdjacentStatus(string adjName, int s);
+    int updateAdjacentLinkCost(string adjName, double lc);
+    std::list<Adjacent>& getAdjList();
+    bool isNeighbor(string adjName);
+    void incrementTimedOutInterestCount(string& neighbor);
+    int getTimedOutInterestCount(string& neighbor);
+    int getStatusOfNeighbor(string& neighbor);
+    void setStatusOfNeighbor(string& neighbor, int status);
+    void setTimedOutInterestCount(string& neighbor, int count);
+    void addAdjacentsFromAdl(Adl& adl);
+
+    bool isAdjLsaBuildable(Nlsr& pnlsr);
+    int getNumOfActiveNeighbor();
+    Adjacent getAdjacent(string adjName);
+
+    bool isAdlEqual(Adl &adl);
+
+    int getAdlSize()
     {
+      return adjList.size();
+    }
 
-    public:
-        Adl();
-        ~Adl();
-        int insert(Adjacent& adj);
-        int updateAdjacentStatus(string adjName, int s);
-        int updateAdjacentLinkCost(string adjName, double lc);
-        std::list<Adjacent>& getAdjList();
-        bool isNeighbor(string adjName);
-        void incrementTimedOutInterestCount(string& neighbor);
-        int getTimedOutInterestCount(string& neighbor);
-        int getStatusOfNeighbor(string& neighbor);
-        void setStatusOfNeighbor(string& neighbor, int status);
-        void setTimedOutInterestCount(string& neighbor, int count);
-        void addAdjacentsFromAdl(Adl& adl);
+    void resetAdl()
+    {
+      if( adjList.size() > 0 )
+      {
+        adjList.clear();
+      }
+    }
 
-        bool isAdjLsaBuildable(Nlsr& pnlsr);
-        int getNumOfActiveNeighbor();
-        Adjacent getAdjacent(string adjName);
+    void printAdl();
 
-        bool isAdlEqual(Adl &adl);
-
-        int getAdlSize()
-        {
-            return adjList.size();
-        }
-
-        void resetAdl()
-        {
-            if( adjList.size() > 0 )
-            {
-                adjList.clear();
-            }
-        }
-
-        void printAdl();
-
-    private:
-        std::list< Adjacent > adjList;
-    };
+  private:
+    std::list< Adjacent > adjList;
+  };
 
 } //namespace nlsr
 #endif
diff --git a/src/nlsr_conf_param.cpp b/src/nlsr_conf_param.cpp
index 1fc0e41..4f879e3 100644
--- a/src/nlsr_conf_param.cpp
+++ b/src/nlsr_conf_param.cpp
@@ -4,29 +4,29 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    ostream&
-    operator << (ostream &os, ConfParameter& cfp)
-    {
-        os  <<"Router Name: "<< cfp.getRouterName()<<endl;
-        os  <<"Site Name: "<< cfp.getSiteName()<<endl;
-        os  <<"Network: "<< cfp.getNetwork()<<endl;
-        os  <<"Router Prefix: "<< cfp.getRouterPrefix()<<endl;
-        os  <<"ChronoSync sync Prifex: "<< cfp.getChronosyncSyncPrefix()<<endl;
-        os  <<"Interest Retry number: "<< cfp.getInterestRetryNumber()<<endl;
-        os  <<"Interest Resend second: "<< cfp.getInterestResendTime()<<endl;
-        os  <<"Info Interest Interval: "<<cfp.getInfoInterestInterval()<<endl;
-        os  <<"LSA refresh time: "<< cfp.getLsaRefreshTime()<<endl;
-        os  <<"Max Faces Per Prefix: "<< cfp.getMaxFacesPerPrefix()<<endl;
-        os  <<"Log Dir: "<< cfp.getLogDir()<<endl;
-        os  <<"Detalied logging: "<< cfp.getDetailedLogging()<<endl;
-        os  <<"Debugging: "<< cfp.getDebugging()<<endl;
-        os  <<"Hyperbolic ROuting: "<< cfp.getIsHyperbolicCalc()<<endl;
-        os  <<"Hyp R: "<< cfp.getCorR()<<endl;
-        os  <<"Hyp theta: "<< cfp.getCorTheta()<<endl;
-        os  <<"Tunnel Type: "<< cfp.getTunnelType()<<endl;
-        return os;
-    }
+  ostream&
+  operator << (ostream &os, ConfParameter& cfp)
+  {
+    os  <<"Router Name: "<< cfp.getRouterName()<<endl;
+    os  <<"Site Name: "<< cfp.getSiteName()<<endl;
+    os  <<"Network: "<< cfp.getNetwork()<<endl;
+    os  <<"Router Prefix: "<< cfp.getRouterPrefix()<<endl;
+    os  <<"ChronoSync sync Prifex: "<< cfp.getChronosyncSyncPrefix()<<endl;
+    os  <<"Interest Retry number: "<< cfp.getInterestRetryNumber()<<endl;
+    os  <<"Interest Resend second: "<< cfp.getInterestResendTime()<<endl;
+    os  <<"Info Interest Interval: "<<cfp.getInfoInterestInterval()<<endl;
+    os  <<"LSA refresh time: "<< cfp.getLsaRefreshTime()<<endl;
+    os  <<"Max Faces Per Prefix: "<< cfp.getMaxFacesPerPrefix()<<endl;
+    os  <<"Log Dir: "<< cfp.getLogDir()<<endl;
+    os  <<"Detalied logging: "<< cfp.getDetailedLogging()<<endl;
+    os  <<"Debugging: "<< cfp.getDebugging()<<endl;
+    os  <<"Hyperbolic ROuting: "<< cfp.getIsHyperbolicCalc()<<endl;
+    os  <<"Hyp R: "<< cfp.getCorR()<<endl;
+    os  <<"Hyp theta: "<< cfp.getCorTheta()<<endl;
+    os  <<"Tunnel Type: "<< cfp.getTunnelType()<<endl;
+    return os;
+  }
 
 } //namespace nlsr
diff --git a/src/nlsr_conf_param.hpp b/src/nlsr_conf_param.hpp
index 2bd7cd3..9446009 100644
--- a/src/nlsr_conf_param.hpp
+++ b/src/nlsr_conf_param.hpp
@@ -6,292 +6,292 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class ConfParameter
+  class ConfParameter
+  {
+
+  public:
+    ConfParameter()
+      : chronosyncSyncPrefix("ndn/nlsr/sync")
+      , chronosyncLsaPrefix("/ndn/nlsr/LSA")
+      , rootKeyPrefix("/ndn/keys")
+      , isStrictHierchicalKeyCheck(0)
+      , interestRetryNumber(3)
+      , interestResendTime(5)
+      , infoInterestInterval(60)
+      , lsaRefreshTime(1800)
+      , routerDeadInterval(3600)
+      , maxFacesPerPrefix(0)
+      , tunnelType(0)
+      , detailedLogging(0)
+      , certDir()
+      , debugging(0)
+      , isHyperbolicCalc(0)
+      , seqFileDir()
+      , corR(0)
+      , corTheta(0)
+    {}
+
+    void setRouterName(const string& rn)
     {
+      routerName=rn;
+    }
 
-    public:
-        ConfParameter()
-            : chronosyncSyncPrefix("ndn/nlsr/sync")
-            , chronosyncLsaPrefix("/ndn/nlsr/LSA")
-            , rootKeyPrefix("/ndn/keys")
-            , isStrictHierchicalKeyCheck(0)
-            , interestRetryNumber(3)
-            , interestResendTime(5)
-            , infoInterestInterval(60)
-            , lsaRefreshTime(1800)
-            , routerDeadInterval(3600)
-            , maxFacesPerPrefix(0)
-            , tunnelType(0)
-            , detailedLogging(0)
-            , certDir()
-            , debugging(0)
-            , isHyperbolicCalc(0)
-            , seqFileDir()
-            , corR(0)
-            , corTheta(0)
-        {}
+    string getRouterName()
+    {
+      return routerName;
+    }
 
-        void setRouterName(const string& rn)
-        {
-            routerName=rn;
-        }
+    void setSiteName(const string& sn)
+    {
+      siteName=sn;
+    }
 
-        string getRouterName()
-        {
-            return routerName;
-        }
+    string getSiteName()
+    {
+      return siteName;
+    }
 
-        void setSiteName(const string& sn)
-        {
-            siteName=sn;
-        }
+    void setNetwork(const string& nn)
+    {
+      network=nn;
+    }
 
-        string getSiteName()
-        {
-            return siteName;
-        }
+    string getNetwork()
+    {
+      return network;
+    }
 
-        void setNetwork(const string& nn)
-        {
-            network=nn;
-        }
+    void buildRouterPrefix()
+    {
+      routerPrefix="/"+network+"/"+siteName+"/"+routerName;
+    }
 
-        string getNetwork()
-        {
-            return network;
-        }
+    string getRouterPrefix()
+    {
+      return routerPrefix;
+    }
 
-        void buildRouterPrefix()
-        {
-            routerPrefix="/"+network+"/"+siteName+"/"+routerName;
-        }
+    string getRootKeyPrefix()
+    {
+      return rootKeyPrefix;
+    }
 
-        string getRouterPrefix()
-        {
-            return routerPrefix;
-        }
+    void setRootKeyPrefix(string rkp)
+    {
+      rootKeyPrefix=rkp;
+    }
 
-        string getRootKeyPrefix()
-        {
-            return rootKeyPrefix;
-        }
+    void setInterestRetryNumber(int irn)
+    {
+      interestRetryNumber=irn;
+    }
 
-        void setRootKeyPrefix(string rkp)
-        {
-            rootKeyPrefix=rkp;
-        }
+    int getInterestRetryNumber()
+    {
+      return interestRetryNumber;
+    }
 
-        void setInterestRetryNumber(int irn)
-        {
-            interestRetryNumber=irn;
-        }
+    void setInterestResendTime(int irt)
+    {
+      interestResendTime=irt;
+    }
 
-        int getInterestRetryNumber()
-        {
-            return interestRetryNumber;
-        }
+    int getInterestResendTime()
+    {
+      return interestResendTime;
+    }
 
-        void setInterestResendTime(int irt)
-        {
-            interestResendTime=irt;
-        }
+    void setLsaRefreshTime(int lrt)
+    {
+      lsaRefreshTime=lrt;
+      routerDeadInterval=2*lsaRefreshTime;
+    }
 
-        int getInterestResendTime()
-        {
-            return interestResendTime;
-        }
+    int getLsaRefreshTime()
+    {
+      return lsaRefreshTime;
+    }
 
-        void setLsaRefreshTime(int lrt)
-        {
-            lsaRefreshTime=lrt;
-            routerDeadInterval=2*lsaRefreshTime;
-        }
+    void setRouterDeadInterval(int rdt)
+    {
+      routerDeadInterval=rdt;
+    }
 
-        int getLsaRefreshTime()
-        {
-            return lsaRefreshTime;
-        }
+    long int getRouterDeadInterval()
+    {
+      return routerDeadInterval;
+    }
 
-        void setRouterDeadInterval(int rdt)
-        {
-            routerDeadInterval=rdt;
-        }
+    void setMaxFacesPerPrefix(int mfpp)
+    {
+      maxFacesPerPrefix=mfpp;
+    }
 
-        long int getRouterDeadInterval()
-        {
-            return routerDeadInterval;
-        }
+    int getMaxFacesPerPrefix()
+    {
+      return maxFacesPerPrefix;
+    }
 
-        void setMaxFacesPerPrefix(int mfpp)
-        {
-            maxFacesPerPrefix=mfpp;
-        }
+    void setLogDir(string ld)
+    {
+      logDir=ld;
+    }
 
-        int getMaxFacesPerPrefix()
-        {
-            return maxFacesPerPrefix;
-        }
+    string getLogDir()
+    {
+      return logDir;
+    }
 
-        void setLogDir(string ld)
-        {
-            logDir=ld;
-        }
+    void setCertDir(std::string cd)
+    {
+      certDir=cd;
+    }
 
-        string getLogDir()
-        {
-            return logDir;
-        }
-        
-        void setCertDir(std::string cd)
-        {
-            certDir=cd;
-        }
-        
-        std::string getCertDir()
-        {
-            return certDir;
-        }
+    std::string getCertDir()
+    {
+      return certDir;
+    }
 
-        void setSeqFileDir(string ssfd)
-        {
-            seqFileDir=ssfd;
-        }
+    void setSeqFileDir(string ssfd)
+    {
+      seqFileDir=ssfd;
+    }
 
-        string getSeqFileDir()
-        {
-            return seqFileDir;
-        }
+    string getSeqFileDir()
+    {
+      return seqFileDir;
+    }
 
-        void setDetailedLogging(int dl)
-        {
-            detailedLogging=dl;
-        }
+    void setDetailedLogging(int dl)
+    {
+      detailedLogging=dl;
+    }
 
-        int getDetailedLogging()
-        {
-            return detailedLogging;
-        }
+    int getDetailedLogging()
+    {
+      return detailedLogging;
+    }
 
-        void setDebugging(int d)
-        {
-            debugging=d;
-        }
+    void setDebugging(int d)
+    {
+      debugging=d;
+    }
 
-        int getDebugging()
-        {
-            return debugging;
-        }
+    int getDebugging()
+    {
+      return debugging;
+    }
 
-        void setIsHyperbolicCalc(int ihc)
-        {
-            isHyperbolicCalc=ihc;
-        }
+    void setIsHyperbolicCalc(int ihc)
+    {
+      isHyperbolicCalc=ihc;
+    }
 
-        int getIsHyperbolicCalc()
-        {
-            return isHyperbolicCalc;
-        }
+    int getIsHyperbolicCalc()
+    {
+      return isHyperbolicCalc;
+    }
 
-        void setCorR(double cr)
-        {
-            corR=cr;
-        }
+    void setCorR(double cr)
+    {
+      corR=cr;
+    }
 
-        double getCorR()
-        {
-            return corR;
-        }
+    double getCorR()
+    {
+      return corR;
+    }
 
-        void setCorTheta(double ct)
-        {
-            corTheta=ct;
-        }
+    void setCorTheta(double ct)
+    {
+      corTheta=ct;
+    }
 
-        double getCorTheta()
-        {
-            return corTheta;
-        }
+    double getCorTheta()
+    {
+      return corTheta;
+    }
 
-        void setTunnelType(int tt)
-        {
-            tunnelType=tt;
-        }
+    void setTunnelType(int tt)
+    {
+      tunnelType=tt;
+    }
 
-        int getTunnelType()
-        {
-            return tunnelType;
-        }
+    int getTunnelType()
+    {
+      return tunnelType;
+    }
 
-        void setChronosyncSyncPrefix(const string& csp)
-        {
-            chronosyncSyncPrefix=csp;
-        }
+    void setChronosyncSyncPrefix(const string& csp)
+    {
+      chronosyncSyncPrefix=csp;
+    }
 
-        string getChronosyncSyncPrefix()
-        {
-            return chronosyncSyncPrefix;
-        }
+    string getChronosyncSyncPrefix()
+    {
+      return chronosyncSyncPrefix;
+    }
 
-        void setChronosyncLsaPrefix(string clp)
-        {
-            chronosyncLsaPrefix=clp;
-        }
+    void setChronosyncLsaPrefix(string clp)
+    {
+      chronosyncLsaPrefix=clp;
+    }
 
-        string getChronosyncLsaPrefix()
-        {
-            return chronosyncLsaPrefix;
-        }
+    string getChronosyncLsaPrefix()
+    {
+      return chronosyncLsaPrefix;
+    }
 
-        int getInfoInterestInterval()
-        {
-            return infoInterestInterval;
-        }
+    int getInfoInterestInterval()
+    {
+      return infoInterestInterval;
+    }
 
-        void setInfoInterestInterval(int iii)
-        {
-            infoInterestInterval=iii;
-        }
+    void setInfoInterestInterval(int iii)
+    {
+      infoInterestInterval=iii;
+    }
 
-    private:
-        string routerName;
-        string siteName;
-        string network;
+  private:
+    string routerName;
+    string siteName;
+    string network;
 
-        string routerPrefix;
-        string lsaRouterPrefix;
+    string routerPrefix;
+    string lsaRouterPrefix;
 
-        string chronosyncSyncPrefix;
-        string chronosyncLsaPrefix;
+    string chronosyncSyncPrefix;
+    string chronosyncLsaPrefix;
 
-        string rootKeyPrefix;
+    string rootKeyPrefix;
 
-        int interestRetryNumber;
-        int interestResendTime;
-        int infoInterestInterval;
-        int lsaRefreshTime;
-        int routerDeadInterval;
+    int interestRetryNumber;
+    int interestResendTime;
+    int infoInterestInterval;
+    int lsaRefreshTime;
+    int routerDeadInterval;
 
-        int maxFacesPerPrefix;
-        string logDir;
-        string certDir;
-        string seqFileDir;
-        string logFile;
-        int detailedLogging;
-        int debugging;
+    int maxFacesPerPrefix;
+    string logDir;
+    string certDir;
+    string seqFileDir;
+    string logFile;
+    int detailedLogging;
+    int debugging;
 
-        int isHyperbolicCalc;
-        double corR;
-        double corTheta;
+    int isHyperbolicCalc;
+    double corR;
+    double corTheta;
 
-        int tunnelType;
-        int isStrictHierchicalKeyCheck;
+    int tunnelType;
+    int isStrictHierchicalKeyCheck;
 
-    };
+  };
 
-    std::ostream&
-    operator << (std::ostream &os, ConfParameter &cfp);
+  std::ostream&
+  operator << (std::ostream &os, ConfParameter &cfp);
 
 } // namespace nlsr
 
diff --git a/src/nlsr_conf_processor.cpp b/src/nlsr_conf_processor.cpp
index 13432d0..627be79 100644
--- a/src/nlsr_conf_processor.cpp
+++ b/src/nlsr_conf_processor.cpp
@@ -13,547 +13,547 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    int
-    ConfFileProcessor::processConfFile(Nlsr& pnlsr)
+  int
+  ConfFileProcessor::processConfFile(Nlsr& pnlsr)
+  {
+    int ret=0;
+    if ( !confFileName.empty())
     {
-        int ret=0;
-        if ( !confFileName.empty())
+      std::ifstream inputFile(confFileName.c_str());
+      if ( inputFile.is_open())
+      {
+        for( string line; getline( inputFile, line ); )
         {
-            std::ifstream inputFile(confFileName.c_str());
-            if ( inputFile.is_open())
+          if (!line.empty() )
+          {
+            if(line[0]!= '#' && line[0]!='!')
             {
-                for( string line; getline( inputFile, line ); )
-                {
-                    if (!line.empty() )
-                    {
-                        if(line[0]!= '#' && line[0]!='!')
-                        {
-                            ret=processConfCommand(pnlsr, line);
-                            if( ret == -1 )
-                            {
-                                break;
-                            }
-                        }
-                    }
-                }
+              ret=processConfCommand(pnlsr, line);
+              if( ret == -1 )
+              {
+                break;
+              }
             }
-            else
-            {
-                std::cerr <<"Configuration file: ("<<confFileName<<") does not exist :(";
-                std::cerr <<endl;
-                ret=-1;
-            }
+          }
         }
-        return ret;
+      }
+      else
+      {
+        std::cerr <<"Configuration file: ("<<confFileName<<") does not exist :(";
+        std::cerr <<endl;
+        ret=-1;
+      }
     }
+    return ret;
+  }
 
 
-    int
-    ConfFileProcessor::processConfCommand(Nlsr& pnlsr, string command)
+  int
+  ConfFileProcessor::processConfCommand(Nlsr& pnlsr, string command)
+  {
+    int ret=0;
+    nlsrTokenizer nt(command," ");
+    if( (nt.getFirstToken() == "network"))
     {
-        int ret=0;
-        nlsrTokenizer nt(command," ");
-        if( (nt.getFirstToken() == "network"))
-        {
-            ret=processConfCommandNetwork(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "site-name"))
-        {
-            ret=processConfCommandSiteName(pnlsr,nt.getRestOfLine());
-        }
-        else if ( (nt.getFirstToken() == "root-key-prefix"))
-        {
-            ret=processConfCommandRootKeyPrefix(pnlsr,nt.getRestOfLine());
-        }
-        else if ( (nt.getFirstToken() == "router-name"))
-        {
-            ret=processConfCommandRouterName(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "ndnneighbor") )
-        {
-            ret=processConfCommandNdnNeighbor(pnlsr, nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "link-cost"))
-        {
-            ret=processConfCommandLinkCost(pnlsr, nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "ndnname") )
-        {
-            ret=processConfCommandNdnName(pnlsr, nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "interest-retry-num"))
-        {
-            processConfCommandInterestRetryNumber(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "interest-resend-time"))
-        {
-            processConfCommandInterestResendTime(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "lsa-refresh-time"))
-        {
-            processConfCommandLsaRefreshTime(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "max-faces-per-prefix"))
-        {
-            processConfCommandMaxFacesPerPrefix(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "log-dir"))
-        {
-            processConfCommandLogDir(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "cert-dir"))
-        {
-            processConfCommandCertDir(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "detailed-logging") )
-        {
-            processConfCommandDetailedLogging(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "debugging") )
-        {
-            processConfCommandDebugging(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "chronosync-sync-prefix") )
-        {
-            processConfCommandChronosyncSyncPrefix(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "hyperbolic-cordinate") )
-        {
-            processConfCommandHyperbolicCordinate(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "hyperbolic-routing"))
-        {
-            processConfCommandIsHyperbolicCalc(pnlsr,nt.getRestOfLine());
-        }
-        else if( (nt.getFirstToken() == "tunnel-type"))
-        {
-            processConfCommandTunnelType(pnlsr,nt.getRestOfLine());
-        }
-        else
-        {
-            cout << "Wrong configuration Command: "<< nt.getFirstToken()<<endl;
-        }
-        return ret;
+      ret=processConfCommandNetwork(pnlsr,nt.getRestOfLine());
     }
-
-    int
-    ConfFileProcessor::processConfCommandNetwork(Nlsr& pnlsr, string command)
+    else if( (nt.getFirstToken() == "site-name"))
     {
-        if(command.empty() )
-        {
-            cerr <<" Network can not be null or empty :( !"<<endl;
-            return -1;
-        }
-        else
-        {
-            if(command[command.size()-1] == '/' )
-            {
-                command.erase(command.size() - 1);
-            }
-            if(command[0] == '/' )
-            {
-                command.erase(0,1);
-            }
-            pnlsr.getConfParameter().setNetwork(command);
-        }
+      ret=processConfCommandSiteName(pnlsr,nt.getRestOfLine());
+    }
+    else if ( (nt.getFirstToken() == "root-key-prefix"))
+    {
+      ret=processConfCommandRootKeyPrefix(pnlsr,nt.getRestOfLine());
+    }
+    else if ( (nt.getFirstToken() == "router-name"))
+    {
+      ret=processConfCommandRouterName(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "ndnneighbor") )
+    {
+      ret=processConfCommandNdnNeighbor(pnlsr, nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "link-cost"))
+    {
+      ret=processConfCommandLinkCost(pnlsr, nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "ndnname") )
+    {
+      ret=processConfCommandNdnName(pnlsr, nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "interest-retry-num"))
+    {
+      processConfCommandInterestRetryNumber(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "interest-resend-time"))
+    {
+      processConfCommandInterestResendTime(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "lsa-refresh-time"))
+    {
+      processConfCommandLsaRefreshTime(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "max-faces-per-prefix"))
+    {
+      processConfCommandMaxFacesPerPrefix(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "log-dir"))
+    {
+      processConfCommandLogDir(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "cert-dir"))
+    {
+      processConfCommandCertDir(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "detailed-logging") )
+    {
+      processConfCommandDetailedLogging(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "debugging") )
+    {
+      processConfCommandDebugging(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "chronosync-sync-prefix") )
+    {
+      processConfCommandChronosyncSyncPrefix(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "hyperbolic-cordinate") )
+    {
+      processConfCommandHyperbolicCordinate(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "hyperbolic-routing"))
+    {
+      processConfCommandIsHyperbolicCalc(pnlsr,nt.getRestOfLine());
+    }
+    else if( (nt.getFirstToken() == "tunnel-type"))
+    {
+      processConfCommandTunnelType(pnlsr,nt.getRestOfLine());
+    }
+    else
+    {
+      cout << "Wrong configuration Command: "<< nt.getFirstToken()<<endl;
+    }
+    return ret;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandNetwork(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Network can not be null or empty :( !"<<endl;
+      return -1;
+    }
+    else
+    {
+      if(command[command.size()-1] == '/' )
+      {
+        command.erase(command.size() - 1);
+      }
+      if(command[0] == '/' )
+      {
+        command.erase(0,1);
+      }
+      pnlsr.getConfParameter().setNetwork(command);
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandSiteName(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<"Site name can not be null or empty :( !"<<endl;
+      return -1;
+    }
+    else
+    {
+      if(command[command.size()-1] == '/' )
+      {
+        command.erase(command.size() - 1);
+      }
+      if(command[0] == '/' )
+      {
+        command.erase(0,1);
+      }
+      pnlsr.getConfParameter().setSiteName(command);
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<"Root Key Prefix can not be null or empty :( !"<<endl;
+      return -1;
+    }
+    else
+    {
+      if(command[command.size()-1] == '/' )
+      {
+        command.erase(command.size() - 1);
+      }
+      if(command[0] == '/' )
+      {
+        command.erase(0,1);
+      }
+      pnlsr.getConfParameter().setRootKeyPrefix(command);
+    }
+    return 0;
+  }
+
+
+  int
+  ConfFileProcessor::processConfCommandRouterName(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Router name can not be null or empty :( !"<<endl;
+      return -1;
+    }
+    else
+    {
+      if(command[command.size()-1] == '/' )
+      {
+        command.erase(command.size() - 1);
+      }
+      if(command[0] == '/' )
+      {
+        command.erase(0,1);
+      }
+      pnlsr.getConfParameter().setRouterName(command);
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandInterestRetryNumber(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [interest-retry-num n]"<<endl;
+    }
+    else
+    {
+      int irn;
+      stringstream ss(command.c_str());
+      ss>>irn;
+      if ( irn >=1 && irn <=5)
+      {
+        pnlsr.getConfParameter().setInterestRetryNumber(irn);
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandInterestResendTime(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
+    }
+    else
+    {
+      int irt;
+      stringstream ss(command.c_str());
+      ss>>irt;
+      if( irt>=1 && irt <=20)
+      {
+        pnlsr.getConfParameter().setInterestResendTime(irt);
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
+    }
+    else
+    {
+      int lrt;
+      stringstream ss(command.c_str());
+      ss>>lrt;
+      if ( lrt>= 240 && lrt<=7200)
+      {
+        pnlsr.getConfParameter().setLsaRefreshTime(lrt);
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [max-faces-per-prefix n]"<<endl;
+    }
+    else
+    {
+      int mfpp;
+      stringstream ss(command.c_str());
+      ss>>mfpp;
+      if ( mfpp>=0 && mfpp<=60)
+      {
+        pnlsr.getConfParameter().setMaxFacesPerPrefix(mfpp);
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandTunnelType(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
+    }
+    else
+    {
+      if(command == "tcp" || command == "TCP" )
+      {
+        pnlsr.getConfParameter().setTunnelType(1);
+      }
+      else if(command == "udp" || command == "UDP")
+      {
+        pnlsr.getConfParameter().setTunnelType(0);
+      }
+      else
+      {
+        cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [chronosync-sync-prefix name/prefix]!"<<endl;
+    }
+    else
+    {
+      pnlsr.getConfParameter().setChronosyncSyncPrefix(command);
+    }
+    return 0;
+  }
+
+
+  int
+  ConfFileProcessor::processConfCommandLogDir(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [log-dir /path/to/log/dir]!"<<endl;
+    }
+    else
+    {
+      pnlsr.getConfParameter().setLogDir(command);
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandCertDir(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [cert-dir /path/to/cert/dir]!"<<endl;
+    }
+    else
+    {
+      pnlsr.getConfParameter().setCertDir(command);
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandDebugging(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [debugging on/of]!"<<endl;
+    }
+    else
+    {
+      if(command == "on" || command == "ON" )
+      {
+        pnlsr.getConfParameter().setDebugging(1);
+      }
+      else if(command == "off" || command == "off")
+      {
+        pnlsr.getConfParameter().setDebugging(0);
+      }
+      else
+      {
+        cerr <<" Wrong command format ! [debugging on/off]!"<<endl;
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandDetailedLogging(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
+    }
+    else
+    {
+      if(command == "on" || command == "ON" )
+      {
+        pnlsr.getConfParameter().setDetailedLogging(1);
+      }
+      else if(command == "off" || command == "off")
+      {
+        pnlsr.getConfParameter().setDetailedLogging(0);
+      }
+      else
+      {
+        cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandIsHyperbolicCalc(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
+    }
+    else
+    {
+      if(command == "on" || command == "ON" )
+      {
+        pnlsr.getConfParameter().setIsHyperbolicCalc(1);
+      }
+      else if(command == "dry-run" || command == "DRY-RUN")
+      {
+        pnlsr.getConfParameter().setIsHyperbolicCalc(2);
+      }
+      else if(command == "off" || command == "off")
+      {
+        pnlsr.getConfParameter().setIsHyperbolicCalc(0);
+      }
+      else
+      {
+        cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
+      }
+    }
+    return 0;
+  }
+
+  int
+  ConfFileProcessor::processConfCommandHyperbolicCordinate(Nlsr& pnlsr,
+      string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [hyperbolic-cordinate r 0]!"<<endl;
+      if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
+      {
+        return -1;
+      }
+    }
+    else
+    {
+      nlsrTokenizer nt(command," ");
+      stringstream ssr(nt.getFirstToken().c_str());
+      stringstream sst(nt.getRestOfLine().c_str());
+      double r,theta;
+      ssr>>r;
+      sst>>theta;
+      pnlsr.getConfParameter().setCorR(r);
+      pnlsr.getConfParameter().setCorTheta(theta);
+    }
+    return 0;
+  }
+
+
+  int
+  ConfFileProcessor::processConfCommandNdnNeighbor(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
+    {
+      cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
+    }
+    else
+    {
+      nlsrTokenizer nt(command," ");
+      if( nt.getRestOfLine().empty())
+      {
+        cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
         return 0;
+      }
+      else
+      {
+        stringstream sst(nt.getRestOfLine().c_str());
+        int faceId;
+        sst>>faceId;
+        Adjacent adj(nt.getFirstToken(),faceId,0.0,0,0);
+        pnlsr.getAdl().insert(adj);
+      }
     }
+    return 0;
+  }
 
-    int
-    ConfFileProcessor::processConfCommandSiteName(Nlsr& pnlsr, string command)
+  int
+  ConfFileProcessor::processConfCommandNdnName(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
     {
-        if(command.empty() )
-        {
-            cerr <<"Site name can not be null or empty :( !"<<endl;
-            return -1;
-        }
-        else
-        {
-            if(command[command.size()-1] == '/' )
-            {
-                command.erase(command.size() - 1);
-            }
-            if(command[0] == '/' )
-            {
-                command.erase(0,1);
-            }
-            pnlsr.getConfParameter().setSiteName(command);
-        }
-        return 0;
+      cerr <<" Wrong command format ! [ndnname name/prefix]!"<<endl;
     }
-
-    int
-    ConfFileProcessor::processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command)
+    else
     {
-        if(command.empty() )
-        {
-            cerr <<"Root Key Prefix can not be null or empty :( !"<<endl;
-            return -1;
-        }
-        else
-        {
-            if(command[command.size()-1] == '/' )
-            {
-                command.erase(command.size() - 1);
-            }
-            if(command[0] == '/' )
-            {
-                command.erase(0,1);
-            }
-            pnlsr.getConfParameter().setRootKeyPrefix(command);
-        }
-        return 0;
+      pnlsr.getNpl().insertIntoNpl(command);
     }
+    return 0;
+  }
 
 
-    int
-    ConfFileProcessor::processConfCommandRouterName(Nlsr& pnlsr, string command)
+  int
+  ConfFileProcessor::processConfCommandLinkCost(Nlsr& pnlsr, string command)
+  {
+    if(command.empty() )
     {
-        if(command.empty() )
-        {
-            cerr <<" Router name can not be null or empty :( !"<<endl;
-            return -1;
-        }
-        else
-        {
-            if(command[command.size()-1] == '/' )
-            {
-                command.erase(command.size() - 1);
-            }
-            if(command[0] == '/' )
-            {
-                command.erase(0,1);
-            }
-            pnlsr.getConfParameter().setRouterName(command);
-        }
-        return 0;
+      cerr <<" Wrong command format ! [link-cost nbr/name cost]!"<<endl;
+      if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
+      {
+        return -1;
+      }
     }
-
-    int
-    ConfFileProcessor::processConfCommandInterestRetryNumber(Nlsr& pnlsr,
-            string command)
+    else
     {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [interest-retry-num n]"<<endl;
-        }
-        else
-        {
-            int irn;
-            stringstream ss(command.c_str());
-            ss>>irn;
-            if ( irn >=1 && irn <=5)
-            {
-                pnlsr.getConfParameter().setInterestRetryNumber(irn);
-            }
-        }
-        return 0;
+      nlsrTokenizer nt(command," ");
+      stringstream sst(nt.getRestOfLine().c_str());
+      double cost;
+      sst>>cost;
+      pnlsr.getAdl().updateAdjacentLinkCost(nt.getFirstToken(),cost);
     }
-
-    int
-    ConfFileProcessor::processConfCommandInterestResendTime(Nlsr& pnlsr,
-            string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
-        }
-        else
-        {
-            int irt;
-            stringstream ss(command.c_str());
-            ss>>irt;
-            if( irt>=1 && irt <=20)
-            {
-                pnlsr.getConfParameter().setInterestResendTime(irt);
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
-        }
-        else
-        {
-            int lrt;
-            stringstream ss(command.c_str());
-            ss>>lrt;
-            if ( lrt>= 240 && lrt<=7200)
-            {
-                pnlsr.getConfParameter().setLsaRefreshTime(lrt);
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr,
-            string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [max-faces-per-prefix n]"<<endl;
-        }
-        else
-        {
-            int mfpp;
-            stringstream ss(command.c_str());
-            ss>>mfpp;
-            if ( mfpp>=0 && mfpp<=60)
-            {
-                pnlsr.getConfParameter().setMaxFacesPerPrefix(mfpp);
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandTunnelType(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
-        }
-        else
-        {
-            if(command == "tcp" || command == "TCP" )
-            {
-                pnlsr.getConfParameter().setTunnelType(1);
-            }
-            else if(command == "udp" || command == "UDP")
-            {
-                pnlsr.getConfParameter().setTunnelType(0);
-            }
-            else
-            {
-                cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr,
-            string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [chronosync-sync-prefix name/prefix]!"<<endl;
-        }
-        else
-        {
-            pnlsr.getConfParameter().setChronosyncSyncPrefix(command);
-        }
-        return 0;
-    }
-
-
-    int
-    ConfFileProcessor::processConfCommandLogDir(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [log-dir /path/to/log/dir]!"<<endl;
-        }
-        else
-        {
-            pnlsr.getConfParameter().setLogDir(command);
-        }
-        return 0;
-    }
-    
-    int
-    ConfFileProcessor::processConfCommandCertDir(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [cert-dir /path/to/cert/dir]!"<<endl;
-        }
-        else
-        {
-            pnlsr.getConfParameter().setCertDir(command);
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandDebugging(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [debugging on/of]!"<<endl;
-        }
-        else
-        {
-            if(command == "on" || command == "ON" )
-            {
-                pnlsr.getConfParameter().setDebugging(1);
-            }
-            else if(command == "off" || command == "off")
-            {
-                pnlsr.getConfParameter().setDebugging(0);
-            }
-            else
-            {
-                cerr <<" Wrong command format ! [debugging on/off]!"<<endl;
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandDetailedLogging(Nlsr& pnlsr,
-            string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
-        }
-        else
-        {
-            if(command == "on" || command == "ON" )
-            {
-                pnlsr.getConfParameter().setDetailedLogging(1);
-            }
-            else if(command == "off" || command == "off")
-            {
-                pnlsr.getConfParameter().setDetailedLogging(0);
-            }
-            else
-            {
-                cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandIsHyperbolicCalc(Nlsr& pnlsr,
-            string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
-        }
-        else
-        {
-            if(command == "on" || command == "ON" )
-            {
-                pnlsr.getConfParameter().setIsHyperbolicCalc(1);
-            }
-            else if(command == "dry-run" || command == "DRY-RUN")
-            {
-                pnlsr.getConfParameter().setIsHyperbolicCalc(2);
-            }
-            else if(command == "off" || command == "off")
-            {
-                pnlsr.getConfParameter().setIsHyperbolicCalc(0);
-            }
-            else
-            {
-                cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandHyperbolicCordinate(Nlsr& pnlsr,
-            string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [hyperbolic-cordinate r 0]!"<<endl;
-            if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
-            {
-                return -1;
-            }
-        }
-        else
-        {
-            nlsrTokenizer nt(command," ");
-            stringstream ssr(nt.getFirstToken().c_str());
-            stringstream sst(nt.getRestOfLine().c_str());
-            double r,theta;
-            ssr>>r;
-            sst>>theta;
-            pnlsr.getConfParameter().setCorR(r);
-            pnlsr.getConfParameter().setCorTheta(theta);
-        }
-        return 0;
-    }
-
-
-    int
-    ConfFileProcessor::processConfCommandNdnNeighbor(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
-        }
-        else
-        {
-            nlsrTokenizer nt(command," ");
-            if( nt.getRestOfLine().empty())
-            {
-                cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
-                return 0;
-            }
-            else
-            {
-                stringstream sst(nt.getRestOfLine().c_str());
-                int faceId;
-                sst>>faceId;
-                Adjacent adj(nt.getFirstToken(),faceId,0.0,0,0);
-                pnlsr.getAdl().insert(adj);
-            }
-        }
-        return 0;
-    }
-
-    int
-    ConfFileProcessor::processConfCommandNdnName(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [ndnname name/prefix]!"<<endl;
-        }
-        else
-        {
-            pnlsr.getNpl().insertIntoNpl(command);
-        }
-        return 0;
-    }
-
-
-    int
-    ConfFileProcessor::processConfCommandLinkCost(Nlsr& pnlsr, string command)
-    {
-        if(command.empty() )
-        {
-            cerr <<" Wrong command format ! [link-cost nbr/name cost]!"<<endl;
-            if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
-            {
-                return -1;
-            }
-        }
-        else
-        {
-            nlsrTokenizer nt(command," ");
-            stringstream sst(nt.getRestOfLine().c_str());
-            double cost;
-            sst>>cost;
-            pnlsr.getAdl().updateAdjacentLinkCost(nt.getFirstToken(),cost);
-        }
-        return 0;
-    }
+    return 0;
+  }
 
 } //namespace nlsr
 
diff --git a/src/nlsr_conf_processor.hpp b/src/nlsr_conf_processor.hpp
index 0379b6c..25861a2 100644
--- a/src/nlsr_conf_processor.hpp
+++ b/src/nlsr_conf_processor.hpp
@@ -6,51 +6,51 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class ConfFileProcessor
+  class ConfFileProcessor
+  {
+  public:
+    ConfFileProcessor()
+      :confFileName()
     {
-    public:
-        ConfFileProcessor()
-            :confFileName()
-        {
-        }
-        ConfFileProcessor(const string& cfile)
-        {
-            confFileName=cfile;
-        }
+    }
+    ConfFileProcessor(const string& cfile)
+    {
+      confFileName=cfile;
+    }
 
-        int processConfFile(Nlsr& pnlsr);
-        
-    private:    
-        int processConfCommand(Nlsr& pnlsr, string command);
-        int processConfCommandNetwork(Nlsr& pnlsr, string command);
-        int processConfCommandSiteName(Nlsr& pnlsr, string command);
-        int processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command);
-        int processConfCommandRouterName(Nlsr& pnlsr, string command);
-        int processConfCommandInterestRetryNumber(Nlsr& pnlsr, string command);
-        int processConfCommandInterestResendTime(Nlsr& pnlsr, string command);
-        int processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command);
-        int processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr, string command);
-        int processConfCommandTunnelType(Nlsr& pnlsr, string command);
+    int processConfFile(Nlsr& pnlsr);
 
-        int processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
-        int processConfCommandLogDir(Nlsr& pnlsr, string command);
-        int processConfCommandCertDir(Nlsr& pnlsr, string command);
-        int processConfCommandDebugging(Nlsr& pnlsr, string command);
-        int processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
-        int processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
+  private:
+    int processConfCommand(Nlsr& pnlsr, string command);
+    int processConfCommandNetwork(Nlsr& pnlsr, string command);
+    int processConfCommandSiteName(Nlsr& pnlsr, string command);
+    int processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command);
+    int processConfCommandRouterName(Nlsr& pnlsr, string command);
+    int processConfCommandInterestRetryNumber(Nlsr& pnlsr, string command);
+    int processConfCommandInterestResendTime(Nlsr& pnlsr, string command);
+    int processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command);
+    int processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr, string command);
+    int processConfCommandTunnelType(Nlsr& pnlsr, string command);
 
-        int processConfCommandHyperbolicCordinate(Nlsr& pnlsr, string command);
+    int processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
+    int processConfCommandLogDir(Nlsr& pnlsr, string command);
+    int processConfCommandCertDir(Nlsr& pnlsr, string command);
+    int processConfCommandDebugging(Nlsr& pnlsr, string command);
+    int processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
+    int processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
 
-        int processConfCommandNdnNeighbor(Nlsr& pnlsr, string command);
-        int processConfCommandNdnName(Nlsr& pnlsr, string command);
-        int processConfCommandLinkCost(Nlsr& pnlsr, string command);
+    int processConfCommandHyperbolicCordinate(Nlsr& pnlsr, string command);
+
+    int processConfCommandNdnNeighbor(Nlsr& pnlsr, string command);
+    int processConfCommandNdnName(Nlsr& pnlsr, string command);
+    int processConfCommandLinkCost(Nlsr& pnlsr, string command);
 
 
-    private:
-        string confFileName;
-    };
+  private:
+    string confFileName;
+  };
 
 } //namespace nlsr
 #endif
diff --git a/src/nlsr_lsa.cpp b/src/nlsr_lsa.cpp
index 2a11e41..4354393 100644
--- a/src/nlsr_lsa.cpp
+++ b/src/nlsr_lsa.cpp
@@ -15,312 +15,312 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
 
-    string
-    NameLsa::getNameLsaKey()
+  string
+  NameLsa::getNameLsaKey()
+  {
+    string key;
+    key=origRouter + "/" + boost::lexical_cast<std::string>(1);
+    return key;
+  }
+
+  NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
+  {
+    origRouter=origR;
+    lsType=lst;
+    lsSeqNo=lsn;
+    lifeTime=lt;
+    std::list<string> nl=npl.getNameList();
+    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
     {
-        string key;
-        key=origRouter + "/" + boost::lexical_cast<std::string>(1);
-        return key;
+      addNameToLsa((*it));
     }
+  }
 
-    NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
+  string
+  NameLsa::getNameLsaData()
+  {
+    string nameLsaData;
+    nameLsaData=origRouter + "|" + boost::lexical_cast<std::string>(1) + "|"
+                + boost::lexical_cast<std::string>(lsSeqNo) + "|"
+                + boost::lexical_cast<std::string>(lifeTime);
+    nameLsaData+="|";
+    nameLsaData+=boost::lexical_cast<std::string>(npl.getNplSize());
+    std::list<string> nl=npl.getNameList();
+    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
     {
-        origRouter=origR;
-        lsType=lst;
-        lsSeqNo=lsn;
-        lifeTime=lt;
-        std::list<string> nl=npl.getNameList();
-        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-        {
-            addNameToLsa((*it));
-        }
+      nameLsaData+="|";
+      nameLsaData+=(*it);
     }
+    return nameLsaData+"|";
+  }
 
-    string
-    NameLsa::getNameLsaData()
+  bool
+  NameLsa::initNameLsaFromContent(string content)
+  {
+    uint32_t numName=0;
+    nlsrTokenizer nt(content, "|");
+    origRouter=nt.getNextToken();
+    if(origRouter.empty())
     {
-        string nameLsaData;
-        nameLsaData=origRouter + "|" + boost::lexical_cast<std::string>(1) + "|"
-                    + boost::lexical_cast<std::string>(lsSeqNo) + "|"
-                    + boost::lexical_cast<std::string>(lifeTime);
-        nameLsaData+="|";
-        nameLsaData+=boost::lexical_cast<std::string>(npl.getNplSize());
-        std::list<string> nl=npl.getNameList();
-        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-        {
-            nameLsaData+="|";
-            nameLsaData+=(*it);
-        }
-        return nameLsaData+"|";
+      return false;
     }
-
-    bool
-    NameLsa::initNameLsaFromContent(string content)
+    try
     {
-        uint32_t numName=0;
-        nlsrTokenizer nt(content, "|");
-        origRouter=nt.getNextToken();
-        if(origRouter.empty())
-        {
-            return false;
-        }
-        try
-        {
-            lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
-            lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
-            lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
-            numName=boost::lexical_cast<uint32_t>(nt.getNextToken());
-        }
-        catch(std::exception &e)
-        {
-            return false;
-        }
-        for(int i=0; i<numName; i++)
-        {
-            string name=nt.getNextToken();
-            addNameToLsa(name);
-        }
-        return true;
+      lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
+      lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
+      lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
+      numName=boost::lexical_cast<uint32_t>(nt.getNextToken());
     }
-
-    std::ostream&
-    operator<<(std::ostream& os, NameLsa& nLsa)
+    catch(std::exception &e)
     {
-        os<<"Name Lsa: "<<endl;
-        os<<"  Origination Router: "<<nLsa.getOrigRouter()<<endl;
-        os<<"  Ls Type: "<<(unsigned short)nLsa.getLsType()<<endl;
-        os<<"  Ls Seq No: "<<(unsigned int)nLsa.getLsSeqNo()<<endl;
-        os<<"  Ls Lifetime: "<<(unsigned int)nLsa.getLifeTime()<<endl;
-        os<<"  Names: "<<endl;
-        int i=1;
-        std::list<string> nl=nLsa.getNpl().getNameList();
-        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-        {
-            os<<"    Name "<<i<<": "<<(*it)<<endl;
-        }
-        return os;
+      return false;
     }
-
-
-
-    CorLsa::CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
-                   , double r, double theta)
+    for(int i=0; i<numName; i++)
     {
-        origRouter=origR;
-        lsType=lst;
-        lsSeqNo=lsn;
-        lifeTime=lt;
-        corRad=r;
-        corTheta=theta;
+      string name=nt.getNextToken();
+      addNameToLsa(name);
     }
+    return true;
+  }
 
-    string
-    CorLsa::getCorLsaKey()
+  std::ostream&
+  operator<<(std::ostream& os, NameLsa& nLsa)
+  {
+    os<<"Name Lsa: "<<endl;
+    os<<"  Origination Router: "<<nLsa.getOrigRouter()<<endl;
+    os<<"  Ls Type: "<<(unsigned short)nLsa.getLsType()<<endl;
+    os<<"  Ls Seq No: "<<(unsigned int)nLsa.getLsSeqNo()<<endl;
+    os<<"  Ls Lifetime: "<<(unsigned int)nLsa.getLifeTime()<<endl;
+    os<<"  Names: "<<endl;
+    int i=1;
+    std::list<string> nl=nLsa.getNpl().getNameList();
+    for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
     {
-        string key;
-        key=origRouter + "/" + boost::lexical_cast<std::string>(3);
-        return key;
+      os<<"    Name "<<i<<": "<<(*it)<<endl;
     }
+    return os;
+  }
 
-    bool
-    CorLsa::isLsaContentEqual(CorLsa& clsa)
+
+
+  CorLsa::CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
+                 , double r, double theta)
+  {
+    origRouter=origR;
+    lsType=lst;
+    lsSeqNo=lsn;
+    lifeTime=lt;
+    corRad=r;
+    corTheta=theta;
+  }
+
+  string
+  CorLsa::getCorLsaKey()
+  {
+    string key;
+    key=origRouter + "/" + boost::lexical_cast<std::string>(3);
+    return key;
+  }
+
+  bool
+  CorLsa::isLsaContentEqual(CorLsa& clsa)
+  {
+    return (std::abs(corRad - clsa.getCorRadius()) <
+            std::numeric_limits<double>::epsilon()) &&
+           (std::abs(corTheta - clsa.getCorTheta()) <
+            std::numeric_limits<double>::epsilon());
+  }
+
+  string
+  CorLsa::getCorLsaData()
+  {
+    string corLsaData;
+    corLsaData=origRouter + "|";
+    corLsaData+=(boost::lexical_cast<std::string>(3) + "|");
+    corLsaData+=(boost::lexical_cast<std::string>(lsSeqNo) + "|");
+    corLsaData+=(boost::lexical_cast<std::string>(lifeTime) + "|");
+    corLsaData+=(boost::lexical_cast<std::string>(corRad) + "|");
+    corLsaData+=(boost::lexical_cast<std::string>(corTheta) + "|");
+    return corLsaData;
+  }
+
+  bool
+  CorLsa::initCorLsaFromContent(string content)
+  {
+    nlsrTokenizer nt(content, "|");
+    origRouter=nt.getNextToken();
+    if(origRouter.empty())
     {
-        return (std::abs(corRad - clsa.getCorRadius()) <
-                std::numeric_limits<double>::epsilon()) &&
-               (std::abs(corTheta - clsa.getCorTheta()) <
-                std::numeric_limits<double>::epsilon());
+      return false;
     }
-
-    string
-    CorLsa::getCorLsaData()
+    try
     {
-        string corLsaData;
-        corLsaData=origRouter + "|";
-        corLsaData+=(boost::lexical_cast<std::string>(3) + "|");
-        corLsaData+=(boost::lexical_cast<std::string>(lsSeqNo) + "|");
-        corLsaData+=(boost::lexical_cast<std::string>(lifeTime) + "|");
-        corLsaData+=(boost::lexical_cast<std::string>(corRad) + "|");
-        corLsaData+=(boost::lexical_cast<std::string>(corTheta) + "|");
-        return corLsaData;
+      lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
+      lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
+      lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
+      corRad=boost::lexical_cast<double>(nt.getNextToken());
+      corTheta=boost::lexical_cast<double>(nt.getNextToken());
     }
-
-    bool
-    CorLsa::initCorLsaFromContent(string content)
+    catch(std::exception &e)
     {
-        nlsrTokenizer nt(content, "|");
-        origRouter=nt.getNextToken();
-        if(origRouter.empty())
-        {
-            return false;
-        }
-        try
-        {
-            lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
-            lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
-            lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
-            corRad=boost::lexical_cast<double>(nt.getNextToken());
-            corTheta=boost::lexical_cast<double>(nt.getNextToken());
-        }
-        catch(std::exception &e)
-        {
-            return false;
-        }
-        return true;
+      return false;
     }
+    return true;
+  }
 
-    std::ostream&
-    operator<<(std::ostream& os, CorLsa& cLsa)
+  std::ostream&
+  operator<<(std::ostream& os, CorLsa& cLsa)
+  {
+    os<<"Cor Lsa: "<<endl;
+    os<<"  Origination Router: "<<cLsa.getOrigRouter()<<endl;
+    os<<"  Ls Type: "<<(unsigned short)cLsa.getLsType()<<endl;
+    os<<"  Ls Seq No: "<<(unsigned int)cLsa.getLsSeqNo()<<endl;
+    os<<"  Ls Lifetime: "<<(unsigned int)cLsa.getLifeTime()<<endl;
+    os<<"    Hyperbolic Radius: "<<cLsa.getCorRadius()<<endl;
+    os<<"    Hyperbolic Theta: "<<cLsa.getCorTheta()<<endl;
+    return os;
+  }
+
+
+  AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
+                 uint32_t nl ,Adl padl)
+  {
+    origRouter=origR;
+    lsType=lst;
+    lsSeqNo=lsn;
+    lifeTime=lt;
+    noLink=nl;
+    std::list<Adjacent> al=padl.getAdjList();
+    for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
     {
-        os<<"Cor Lsa: "<<endl;
-        os<<"  Origination Router: "<<cLsa.getOrigRouter()<<endl;
-        os<<"  Ls Type: "<<(unsigned short)cLsa.getLsType()<<endl;
-        os<<"  Ls Seq No: "<<(unsigned int)cLsa.getLsSeqNo()<<endl;
-        os<<"  Ls Lifetime: "<<(unsigned int)cLsa.getLifeTime()<<endl;
-        os<<"    Hyperbolic Radius: "<<cLsa.getCorRadius()<<endl;
-        os<<"    Hyperbolic Theta: "<<cLsa.getCorTheta()<<endl;
-        return os;
+      if((*it).getStatus()==1)
+      {
+        addAdjacentToLsa((*it));
+      }
     }
+  }
+
+  string
+  AdjLsa::getAdjLsaKey()
+  {
+    string key;
+    key=origRouter + "/" + boost::lexical_cast<std::string>(2);
+    return key;
+  }
+
+  bool
+  AdjLsa::isLsaContentEqual(AdjLsa& alsa)
+  {
+    return adl.isAdlEqual(alsa.getAdl());
+  }
 
 
-    AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
-                   uint32_t nl ,Adl padl)
+  string
+  AdjLsa::getAdjLsaData()
+  {
+    string adjLsaData;
+    adjLsaData=origRouter + "|" + boost::lexical_cast<std::string>(2) + "|"
+               + boost::lexical_cast<std::string>(lsSeqNo) + "|"
+               + boost::lexical_cast<std::string>(lifeTime);
+    adjLsaData+="|";
+    adjLsaData+=boost::lexical_cast<std::string>(adl.getAdlSize());
+    std::list<Adjacent> al=adl.getAdjList();
+    for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
     {
-        origRouter=origR;
-        lsType=lst;
-        lsSeqNo=lsn;
-        lifeTime=lt;
-        noLink=nl;
-        std::list<Adjacent> al=padl.getAdjList();
-        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-        {
-            if((*it).getStatus()==1)
-            {
-                addAdjacentToLsa((*it));
-            }
-        }
+      adjLsaData+="|";
+      adjLsaData+=(*it).getAdjacentName();
+      adjLsaData+="|";
+      adjLsaData+=boost::lexical_cast<std::string>((*it).getConnectingFace());
+      adjLsaData+="|";
+      adjLsaData+=boost::lexical_cast<std::string>((*it).getLinkCost());
     }
+    return adjLsaData+"|";
+  }
 
-    string
-    AdjLsa::getAdjLsaKey()
+  bool
+  AdjLsa::initAdjLsaFromContent(string content)
+  {
+    uint32_t numLink=0;
+    nlsrTokenizer nt(content, "|");
+    origRouter=nt.getNextToken();
+    if(origRouter.empty())
     {
-        string key;
-        key=origRouter + "/" + boost::lexical_cast<std::string>(2);
-        return key;
+      return false;
     }
-
-    bool
-    AdjLsa::isLsaContentEqual(AdjLsa& alsa)
+    try
     {
-        return adl.isAdlEqual(alsa.getAdl());
+      lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
+      lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
+      lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
+      numLink=boost::lexical_cast<uint32_t>(nt.getNextToken());
     }
-
-
-    string
-    AdjLsa::getAdjLsaData()
+    catch(std::exception &e)
     {
-        string adjLsaData;
-        adjLsaData=origRouter + "|" + boost::lexical_cast<std::string>(2) + "|"
-                   + boost::lexical_cast<std::string>(lsSeqNo) + "|"
-                   + boost::lexical_cast<std::string>(lifeTime);
-        adjLsaData+="|";
-        adjLsaData+=boost::lexical_cast<std::string>(adl.getAdlSize());
-        std::list<Adjacent> al=adl.getAdjList();
-        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-        {
-            adjLsaData+="|";
-            adjLsaData+=(*it).getAdjacentName();
-            adjLsaData+="|";
-            adjLsaData+=boost::lexical_cast<std::string>((*it).getConnectingFace());
-            adjLsaData+="|";
-            adjLsaData+=boost::lexical_cast<std::string>((*it).getLinkCost());
-        }
-        return adjLsaData+"|";
+      return false;
     }
-
-    bool
-    AdjLsa::initAdjLsaFromContent(string content)
+    for(int i=0; i< numLink; i++)
     {
-        uint32_t numLink=0;
-        nlsrTokenizer nt(content, "|");
-        origRouter=nt.getNextToken();
-        if(origRouter.empty())
-        {
-            return false;
-        }
-        try
-        {
-            lsType=boost::lexical_cast<uint8_t>(nt.getNextToken());
-            lsSeqNo=boost::lexical_cast<uint32_t>(nt.getNextToken());
-            lifeTime=boost::lexical_cast<uint32_t>(nt.getNextToken());
-            numLink=boost::lexical_cast<uint32_t>(nt.getNextToken());
-        }
-        catch(std::exception &e)
-        {
-            return false;
-        }
-        for(int i=0; i< numLink; i++)
-        {
-            try
-            {
-                string adjName=nt.getNextToken();
-                int connectingFace=boost::lexical_cast<int>(nt.getNextToken());
-                double linkCost=boost::lexical_cast<double>(nt.getNextToken());
-                Adjacent adjacent(adjName, connectingFace, linkCost, 0, 0);
-                addAdjacentToLsa(adjacent);
-            }
-            catch( std::exception &e )
-            {
-                return false;
-            }
-        }
-        return true;
+      try
+      {
+        string adjName=nt.getNextToken();
+        int connectingFace=boost::lexical_cast<int>(nt.getNextToken());
+        double linkCost=boost::lexical_cast<double>(nt.getNextToken());
+        Adjacent adjacent(adjName, connectingFace, linkCost, 0, 0);
+        addAdjacentToLsa(adjacent);
+      }
+      catch( std::exception &e )
+      {
+        return false;
+      }
     }
+    return true;
+  }
 
 
-    void
-    AdjLsa::addNptEntriesForAdjLsa(Nlsr& pnlsr)
+  void
+  AdjLsa::addNptEntriesForAdjLsa(Nlsr& pnlsr)
+  {
+    if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
     {
-        if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-        {
-            pnlsr.getNpt().addNpte(getOrigRouter(), getOrigRouter(),pnlsr);
-        }
+      pnlsr.getNpt().addNpteByDestName(getOrigRouter(), getOrigRouter(),pnlsr);
     }
+  }
 
 
-    void
-    AdjLsa::removeNptEntriesForAdjLsa(Nlsr& pnlsr)
+  void
+  AdjLsa::removeNptEntriesForAdjLsa(Nlsr& pnlsr)
+  {
+    if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
     {
-        if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-        {
-            pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(),pnlsr);
-        }
+      pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(),pnlsr);
     }
+  }
 
 
 
-    std::ostream&
-    operator<<(std::ostream& os, AdjLsa& aLsa)
+  std::ostream&
+  operator<<(std::ostream& os, AdjLsa& aLsa)
+  {
+    os<<"Adj Lsa: "<<endl;
+    os<<"  Origination Router: "<<aLsa.getOrigRouter()<<endl;
+    os<<"  Ls Type: "<<(unsigned short)aLsa.getLsType()<<endl;
+    os<<"  Ls Seq No: "<<(unsigned int)aLsa.getLsSeqNo()<<endl;
+    os<<"  Ls Lifetime: "<<(unsigned int)aLsa.getLifeTime()<<endl;
+    os<<"  No Link: "<<(unsigned int)aLsa.getNoLink()<<endl;
+    os<<"  Adjacents: "<<endl;
+    int i=1;
+    std::list<Adjacent> al=aLsa.getAdl().getAdjList();
+    for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
     {
-        os<<"Adj Lsa: "<<endl;
-        os<<"  Origination Router: "<<aLsa.getOrigRouter()<<endl;
-        os<<"  Ls Type: "<<(unsigned short)aLsa.getLsType()<<endl;
-        os<<"  Ls Seq No: "<<(unsigned int)aLsa.getLsSeqNo()<<endl;
-        os<<"  Ls Lifetime: "<<(unsigned int)aLsa.getLifeTime()<<endl;
-        os<<"  No Link: "<<(unsigned int)aLsa.getNoLink()<<endl;
-        os<<"  Adjacents: "<<endl;
-        int i=1;
-        std::list<Adjacent> al=aLsa.getAdl().getAdjList();
-        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-        {
-            os<<"    Adjacent "<<i<<": "<<endl;
-            os<<"      Adjacent Name: "<<(*it).getAdjacentName()<<endl;
-            os<<"      Connecting Face: "<<(*it).getConnectingFace()<<endl;
-            os<<"      Link Cost: "<<(*it).getLinkCost()<<endl;
-        }
-        return os;
+      os<<"    Adjacent "<<i<<": "<<endl;
+      os<<"      Adjacent Name: "<<(*it).getAdjacentName()<<endl;
+      os<<"      Connecting Face: "<<(*it).getConnectingFace()<<endl;
+      os<<"      Link Cost: "<<(*it).getLinkCost()<<endl;
     }
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/nlsr_lsa.hpp b/src/nlsr_lsa.hpp
index a0968f1..06dcbc6 100644
--- a/src/nlsr_lsa.hpp
+++ b/src/nlsr_lsa.hpp
@@ -9,213 +9,213 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    class Lsa
+  class Lsa
+  {
+  public:
+    Lsa()
+      : origRouter()
+      , lsSeqNo()
+      , lifeTime()
+      , lsaExpiringEventId()
     {
-    public:
-        Lsa()
-            : origRouter()
-            , lsSeqNo()
-            , lifeTime()
-            , lsaExpiringEventId()
-        {
-        }
+    }
 
 
-        void setLsType(uint8_t lst)
-        {
-            lsType=lst;
-        }
-
-        uint8_t getLsType()
-        {
-            return lsType;
-        }
-
-        void setLsSeqNo(uint32_t lsn)
-        {
-            lsSeqNo=lsn;
-        }
-
-        uint32_t getLsSeqNo()
-        {
-            return lsSeqNo;
-        }
-
-        string& getOrigRouter()
-        {
-            return origRouter;
-        }
-
-        void setOrigRouter(string& org)
-        {
-            origRouter=org;
-        }
-
-        uint32_t getLifeTime()
-        {
-            return lifeTime;
-        }
-
-        void setLifeTime(uint32_t lt)
-        {
-            lifeTime=lt;
-        }
-
-        void setLsaExpiringEventId(ndn::EventId leei)
-        {
-            lsaExpiringEventId=leei;
-        }
-
-        ndn::EventId getLsaExpiringEventId()
-        {
-            return lsaExpiringEventId;
-        }
-
-
-    protected:
-        string origRouter;
-        uint8_t lsType;
-        uint32_t lsSeqNo;
-        uint32_t lifeTime;
-        ndn::EventId lsaExpiringEventId;
-    };
-
-    class NameLsa:public Lsa
+    void setLsType(uint8_t lst)
     {
-    public:
-        NameLsa()
-            : Lsa()
-            , npl()
-        {
-            setLsType(1);
-        }
+      lsType=lst;
+    }
 
-        NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
-
-        Npl& getNpl()
-        {
-            return npl;
-        }
-
-        void addNameToLsa(string& name)
-        {
-            npl.insertIntoNpl(name);
-        }
-
-        void removeNameFromLsa(string& name)
-        {
-            npl.removeFromNpl(name);
-        }
-
-        string getNameLsaKey();
-
-        string getNameLsaData();
-        bool initNameLsaFromContent(string content);
-
-    private:
-        Npl npl;
-
-    };
-
-    std::ostream&
-    operator<<(std::ostream& os, NameLsa& nLsa);
-
-    class AdjLsa: public Lsa
+    uint8_t getLsType()
     {
-    public:
-        AdjLsa()
-            : Lsa()
-            , adl()
-        {
-            setLsType(2);
-        }
+      return lsType;
+    }
 
-        AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
-               uint32_t nl ,Adl padl);
-        Adl& getAdl()
-        {
-            return adl;
-        }
-
-        void addAdjacentToLsa(Adjacent adj)
-        {
-            adl.insert(adj);
-        }
-        string getAdjLsaKey();
-        string getAdjLsaData();
-        bool initAdjLsaFromContent(string content);
-        uint32_t getNoLink()
-        {
-            return noLink;
-        }
-
-        bool isLsaContentEqual(AdjLsa& alsa);
-        void addNptEntriesForAdjLsa(Nlsr& pnlsr);
-        void removeNptEntriesForAdjLsa(Nlsr& pnlsr);
-
-    private:
-        uint32_t noLink;
-        Adl adl;
-    };
-
-    std::ostream&
-    operator<<(std::ostream& os, AdjLsa& aLsa);
-
-    class CorLsa:public Lsa
+    void setLsSeqNo(uint32_t lsn)
     {
-    public:
-        CorLsa()
-            : Lsa()
-            , corRad(0)
-            , corTheta(0)
-        {
-            setLsType(3);
-        }
+      lsSeqNo=lsn;
+    }
 
-        CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
-               , double r, double theta);
-        string getCorLsaKey();
-        string getCorLsaData();
-        bool initCorLsaFromContent(string content);
-        double getCorRadius()
-        {
-            if ( corRad >= 0 )
-            {
-                return corRad;
-            }
-            else
-            {
-                return -1;
-            }
-        }
+    uint32_t getLsSeqNo()
+    {
+      return lsSeqNo;
+    }
 
-        void setCorRadius(double cr)
-        {
-            corRad=cr;
-        }
+    string& getOrigRouter()
+    {
+      return origRouter;
+    }
 
-        double getCorTheta()
-        {
-            return corTheta;
-        }
+    void setOrigRouter(string& org)
+    {
+      origRouter=org;
+    }
 
-        void setCorTheta(double ct)
-        {
-            corTheta=ct;
-        }
+    uint32_t getLifeTime()
+    {
+      return lifeTime;
+    }
 
-        bool isLsaContentEqual(CorLsa& clsa);
-    private:
-        double corRad;
-        double corTheta;
+    void setLifeTime(uint32_t lt)
+    {
+      lifeTime=lt;
+    }
 
-    };
+    void setLsaExpiringEventId(ndn::EventId leei)
+    {
+      lsaExpiringEventId=leei;
+    }
 
-    std::ostream&
-    operator<<(std::ostream& os, CorLsa& cLsa);
+    ndn::EventId getLsaExpiringEventId()
+    {
+      return lsaExpiringEventId;
+    }
+
+
+  protected:
+    string origRouter;
+    uint8_t lsType;
+    uint32_t lsSeqNo;
+    uint32_t lifeTime;
+    ndn::EventId lsaExpiringEventId;
+  };
+
+  class NameLsa:public Lsa
+  {
+  public:
+    NameLsa()
+      : Lsa()
+      , npl()
+    {
+      setLsType(1);
+    }
+
+    NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
+
+    Npl& getNpl()
+    {
+      return npl;
+    }
+
+    void addNameToLsa(string& name)
+    {
+      npl.insertIntoNpl(name);
+    }
+
+    void removeNameFromLsa(string& name)
+    {
+      npl.removeFromNpl(name);
+    }
+
+    string getNameLsaKey();
+
+    string getNameLsaData();
+    bool initNameLsaFromContent(string content);
+
+  private:
+    Npl npl;
+
+  };
+
+  std::ostream&
+  operator<<(std::ostream& os, NameLsa& nLsa);
+
+  class AdjLsa: public Lsa
+  {
+  public:
+    AdjLsa()
+      : Lsa()
+      , adl()
+    {
+      setLsType(2);
+    }
+
+    AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
+           uint32_t nl ,Adl padl);
+    Adl& getAdl()
+    {
+      return adl;
+    }
+
+    void addAdjacentToLsa(Adjacent adj)
+    {
+      adl.insert(adj);
+    }
+    string getAdjLsaKey();
+    string getAdjLsaData();
+    bool initAdjLsaFromContent(string content);
+    uint32_t getNoLink()
+    {
+      return noLink;
+    }
+
+    bool isLsaContentEqual(AdjLsa& alsa);
+    void addNptEntriesForAdjLsa(Nlsr& pnlsr);
+    void removeNptEntriesForAdjLsa(Nlsr& pnlsr);
+
+  private:
+    uint32_t noLink;
+    Adl adl;
+  };
+
+  std::ostream&
+  operator<<(std::ostream& os, AdjLsa& aLsa);
+
+  class CorLsa:public Lsa
+  {
+  public:
+    CorLsa()
+      : Lsa()
+      , corRad(0)
+      , corTheta(0)
+    {
+      setLsType(3);
+    }
+
+    CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
+           , double r, double theta);
+    string getCorLsaKey();
+    string getCorLsaData();
+    bool initCorLsaFromContent(string content);
+    double getCorRadius()
+    {
+      if ( corRad >= 0 )
+      {
+        return corRad;
+      }
+      else
+      {
+        return -1;
+      }
+    }
+
+    void setCorRadius(double cr)
+    {
+      corRad=cr;
+    }
+
+    double getCorTheta()
+    {
+      return corTheta;
+    }
+
+    void setCorTheta(double ct)
+    {
+      corTheta=ct;
+    }
+
+    bool isLsaContentEqual(CorLsa& clsa);
+  private:
+    double corRad;
+    double corTheta;
+
+  };
+
+  std::ostream&
+  operator<<(std::ostream& os, CorLsa& cLsa);
 
 
 }//namespace nlsr
diff --git a/src/nlsr_lsdb.cpp b/src/nlsr_lsdb.cpp
index cada99d..3da115a 100644
--- a/src/nlsr_lsdb.cpp
+++ b/src/nlsr_lsdb.cpp
@@ -6,724 +6,726 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    Lsdb::cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid)
+  void
+  Lsdb::cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid)
+  {
+    pnlsr.getScheduler().cancelEvent(eid);
+  }
+
+  static bool
+  nameLsaCompareByKey(NameLsa& nlsa1, string& key)
+  {
+    return nlsa1.getNameLsaKey()==key;
+  }
+
+
+  bool
+  Lsdb::buildAndInstallOwnNameLsa(Nlsr& pnlsr)
+  {
+    NameLsa nameLsa(pnlsr.getConfParameter().getRouterPrefix()
+                    , 1
+                    , pnlsr.getSm().getNameLsaSeq()+1
+                    , pnlsr.getConfParameter().getRouterDeadInterval()
+                    , pnlsr.getNpl() );
+    pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq()+1);
+    return installNameLsa(pnlsr,nameLsa);
+  }
+
+  std::pair<NameLsa&, bool>
+  Lsdb::getNameLsa(string key)
+  {
+    std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
+                                       nameLsdb.end(),
+                                       bind(nameLsaCompareByKey, _1, key));
+    if( it != nameLsdb.end())
     {
-        pnlsr.getScheduler().cancelEvent(eid);
+      return std::make_pair(boost::ref((*it)),true);
     }
+    NameLsa nlsa;
+    return std::make_pair(boost::ref(nlsa),false);
+  }
 
-    static bool
-    nameLsaCompareByKey(NameLsa& nlsa1, string& key)
+  bool
+  Lsdb::isNameLsaNew(string key, uint64_t seqNo)
+  {
+    std::pair<NameLsa& , bool>  nameLsaCheck=getNameLsa(key);
+    if(nameLsaCheck.second)
     {
-        return nlsa1.getNameLsaKey()==key;
-    }
-
-
-    bool
-    Lsdb::buildAndInstallOwnNameLsa(Nlsr& pnlsr)
-    {
-        NameLsa nameLsa(pnlsr.getConfParameter().getRouterPrefix()
-                        , 1
-                        , pnlsr.getSm().getNameLsaSeq()+1
-                        , pnlsr.getConfParameter().getRouterDeadInterval()
-                        , pnlsr.getNpl() );
-        pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq()+1);
-        return installNameLsa(pnlsr,nameLsa);
-    }
-
-    std::pair<NameLsa&, bool>
-    Lsdb::getNameLsa(string key)
-    {
-        std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
-                                           nameLsdb.end(),
-                                           bind(nameLsaCompareByKey, _1, key));
-        if( it != nameLsdb.end())
-        {
-            return std::make_pair(boost::ref((*it)),true);
-        }
-        NameLsa nlsa;
-        return std::make_pair(boost::ref(nlsa),false);
-    }
-
-    bool
-    Lsdb::isNameLsaNew(string key, uint64_t seqNo)
-    {
-        std::pair<NameLsa& , bool>  nameLsaCheck=getNameLsa(key);
-        if(nameLsaCheck.second)
-        {
-            if(nameLsaCheck.first.getLsSeqNo() < seqNo)
-            {
-                return true;
-            }
-            else
-            {
-                return false;
-            }
-        }
+      if(nameLsaCheck.first.getLsSeqNo() < seqNo)
+      {
         return true;
-    }
-
-    ndn::EventId
-    Lsdb::scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
-    {
-        return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-                ndn::bind(&Lsdb::exprireOrRefreshNameLsa,
-                          this,boost::ref(pnlsr), key, seqNo));
-    }
-
-    bool
-    Lsdb::installNameLsa(Nlsr& pnlsr, NameLsa &nlsa)
-    {
-        int timeToExpire=lsaRefreshTime;
-        std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(nlsa.getNameLsaKey());
-        if ( !chkNameLsa.second )
-        {
-            addNameLsa(nlsa);
-            printNameLsdb();
-            if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-            {
-                pnlsr.getNpt().addNpte(nlsa.getOrigRouter(),nlsa.getOrigRouter(),pnlsr);
-                std::list<string> nameList=nlsa.getNpl().getNameList();
-                for(std::list<string>::iterator it=nameList.begin(); it!=nameList.end(); it++)
-                {
-                    if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-                    {
-                        pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
-                    }
-                }
-            }
-            if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-            {
-                timeToExpire=nlsa.getLifeTime();
-            }
-            nlsa.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
-                                       nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
-        }
-        else
-        {
-            if ( chkNameLsa.first.getLsSeqNo() < nlsa.getLsSeqNo() )
-            {
-                chkNameLsa.first.setLsSeqNo(nlsa.getLsSeqNo());
-                chkNameLsa.first.setLifeTime(nlsa.getLifeTime());
-                chkNameLsa.first.getNpl().sortNpl();
-                nlsa.getNpl().sortNpl();
-                std::list<string> nameToAdd;
-                std::set_difference(nlsa.getNpl().getNameList().begin(),
-                                    nlsa.getNpl().getNameList().end(),
-                                    chkNameLsa.first.getNpl().getNameList().begin(),
-                                    chkNameLsa.first.getNpl().getNameList().end(),
-                                    std::inserter(nameToAdd, nameToAdd.begin()));
-                for(std::list<string>::iterator it=nameToAdd.begin(); it!=nameToAdd.end();
-                        ++it)
-                {
-                    chkNameLsa.first.addNameToLsa((*it));
-                    if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-                    {
-                        if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-                        {
-                            pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
-                        }
-                    }
-                }
-                std::list<string> nameToRemove;
-                std::set_difference(chkNameLsa.first.getNpl().getNameList().begin(),
-                                    chkNameLsa.first.getNpl().getNameList().end(),
-                                    nlsa.getNpl().getNameList().begin(),
-                                    nlsa.getNpl().getNameList().end(),
-                                    std::inserter(nameToRemove, nameToRemove.begin()));
-                for(std::list<string>::iterator it=nameToRemove.begin();
-                        it!=nameToRemove.end(); ++it)
-                {
-                    chkNameLsa.first.removeNameFromLsa((*it));
-                    if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-                    {
-                        if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-                        {
-                            pnlsr.getNpt().removeNpte((*it),nlsa.getOrigRouter(),pnlsr);
-                        }
-                    }
-                }
-                if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-                {
-                    timeToExpire=nlsa.getLifeTime();
-                }
-                cancelScheduleLsaExpiringEvent(pnlsr,
-                                               chkNameLsa.first.getLsaExpiringEventId());
-                chkNameLsa.first.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
-                                                       nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
-            }
-        }
-        return true;
-    }
-
-    bool
-    Lsdb::addNameLsa(NameLsa &nlsa)
-    {
-        std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
-                                           nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getNameLsaKey()));
-        if( it == nameLsdb.end())
-        {
-            nameLsdb.push_back(nlsa);
-            return true;
-        }
+      }
+      else
+      {
         return false;
+      }
     }
+    return true;
+  }
 
-    bool
-    Lsdb::removeNameLsa(Nlsr& pnlsr, string& key)
+  ndn::EventId
+  Lsdb::scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+  {
+    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
+           ndn::bind(&Lsdb::exprireOrRefreshNameLsa,
+                     this,boost::ref(pnlsr), key, seqNo));
+  }
+
+  bool
+  Lsdb::installNameLsa(Nlsr& pnlsr, NameLsa &nlsa)
+  {
+    int timeToExpire=lsaRefreshTime;
+    std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(nlsa.getNameLsaKey());
+    if ( !chkNameLsa.second )
     {
-        std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
-                                           nameLsdb.end(),
-                                           bind(nameLsaCompareByKey, _1, key));
-        if ( it != nameLsdb.end() )
+      addNameLsa(nlsa);
+      printNameLsdb();
+      if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+      {
+        pnlsr.getNpt().addNpteByDestName(nlsa.getOrigRouter(),nlsa.getOrigRouter(),
+                                         pnlsr);
+        std::list<string> nameList=nlsa.getNpl().getNameList();
+        for(std::list<string>::iterator it=nameList.begin(); it!=nameList.end(); it++)
         {
-            if ( (*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()  )
+          if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
+          {
+            pnlsr.getNpt().addNpteByDestName((*it),nlsa.getOrigRouter(),pnlsr);
+          }
+        }
+      }
+      if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+      {
+        timeToExpire=nlsa.getLifeTime();
+      }
+      nlsa.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
+                                 nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
+    }
+    else
+    {
+      if ( chkNameLsa.first.getLsSeqNo() < nlsa.getLsSeqNo() )
+      {
+        chkNameLsa.first.setLsSeqNo(nlsa.getLsSeqNo());
+        chkNameLsa.first.setLifeTime(nlsa.getLifeTime());
+        chkNameLsa.first.getNpl().sortNpl();
+        nlsa.getNpl().sortNpl();
+        std::list<string> nameToAdd;
+        std::set_difference(nlsa.getNpl().getNameList().begin(),
+                            nlsa.getNpl().getNameList().end(),
+                            chkNameLsa.first.getNpl().getNameList().begin(),
+                            chkNameLsa.first.getNpl().getNameList().end(),
+                            std::inserter(nameToAdd, nameToAdd.begin()));
+        for(std::list<string>::iterator it=nameToAdd.begin(); it!=nameToAdd.end();
+            ++it)
+        {
+          chkNameLsa.first.addNameToLsa((*it));
+          if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+          {
+            if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
             {
-                pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
-                for( std::list<string>::iterator nit=(*it).getNpl().getNameList().begin();
-                        nit!=(*it).getNpl().getNameList().end(); ++nit)
-                {
-                    if ( (*nit) !=pnlsr.getConfParameter().getRouterPrefix())
-                    {
-                        pnlsr.getNpt().removeNpte((*nit),(*it).getOrigRouter(),pnlsr);
-                    }
-                }
+              pnlsr.getNpt().addNpteByDestName((*it),nlsa.getOrigRouter(),pnlsr);
             }
-            nameLsdb.erase(it);
-            return true;
+          }
         }
-        return false;
-    }
-
-    bool
-    Lsdb::doesNameLsaExist(string key)
-    {
-        std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
-                                           nameLsdb.end(),
-                                           bind(nameLsaCompareByKey, _1, key));
-        if( it == nameLsdb.end())
+        std::list<string> nameToRemove;
+        std::set_difference(chkNameLsa.first.getNpl().getNameList().begin(),
+                            chkNameLsa.first.getNpl().getNameList().end(),
+                            nlsa.getNpl().getNameList().begin(),
+                            nlsa.getNpl().getNameList().end(),
+                            std::inserter(nameToRemove, nameToRemove.begin()));
+        for(std::list<string>::iterator it=nameToRemove.begin();
+            it!=nameToRemove.end(); ++it)
         {
-            return false;
+          chkNameLsa.first.removeNameFromLsa((*it));
+          if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+          {
+            if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
+            {
+              pnlsr.getNpt().removeNpte((*it),nlsa.getOrigRouter(),pnlsr);
+            }
+          }
         }
-        return true;
-    }
-
-    void
-    Lsdb::printNameLsdb()
-    {
-        cout<<"---------------Name LSDB-------------------"<<endl;
-        for( std::list<NameLsa>::iterator it=nameLsdb.begin();
-                it!= nameLsdb.end() ; it++)
+        if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
         {
-            cout<< (*it) <<endl;
+          timeToExpire=nlsa.getLifeTime();
         }
+        cancelScheduleLsaExpiringEvent(pnlsr,
+                                       chkNameLsa.first.getLsaExpiringEventId());
+        chkNameLsa.first.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
+                                               nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
+      }
     }
+    return true;
+  }
+
+  bool
+  Lsdb::addNameLsa(NameLsa &nlsa)
+  {
+    std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
+                                       nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getNameLsaKey()));
+    if( it == nameLsdb.end())
+    {
+      nameLsdb.push_back(nlsa);
+      return true;
+    }
+    return false;
+  }
+
+  bool
+  Lsdb::removeNameLsa(Nlsr& pnlsr, string& key)
+  {
+    std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
+                                       nameLsdb.end(),
+                                       bind(nameLsaCompareByKey, _1, key));
+    if ( it != nameLsdb.end() )
+    {
+      if ( (*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()  )
+      {
+        pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
+        for( std::list<string>::iterator nit=(*it).getNpl().getNameList().begin();
+             nit!=(*it).getNpl().getNameList().end(); ++nit)
+        {
+          if ( (*nit) !=pnlsr.getConfParameter().getRouterPrefix())
+          {
+            pnlsr.getNpt().removeNpte((*nit),(*it).getOrigRouter(),pnlsr);
+          }
+        }
+      }
+      nameLsdb.erase(it);
+      return true;
+    }
+    return false;
+  }
+
+  bool
+  Lsdb::doesNameLsaExist(string key)
+  {
+    std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
+                                       nameLsdb.end(),
+                                       bind(nameLsaCompareByKey, _1, key));
+    if( it == nameLsdb.end())
+    {
+      return false;
+    }
+    return true;
+  }
+
+  void
+  Lsdb::printNameLsdb()
+  {
+    cout<<"---------------Name LSDB-------------------"<<endl;
+    for( std::list<NameLsa>::iterator it=nameLsdb.begin();
+         it!= nameLsdb.end() ; it++)
+    {
+      cout<< (*it) <<endl;
+    }
+  }
 
 // Cor LSA and LSDB related Functions start here
 
 
-    static bool
-    corLsaCompareByKey(CorLsa& clsa, string& key)
-    {
-        return clsa.getCorLsaKey()==key;
-    }
+  static bool
+  corLsaCompareByKey(CorLsa& clsa, string& key)
+  {
+    return clsa.getCorLsaKey()==key;
+  }
 
-    bool
-    Lsdb::buildAndInstallOwnCorLsa(Nlsr& pnlsr)
+  bool
+  Lsdb::buildAndInstallOwnCorLsa(Nlsr& pnlsr)
+  {
+    CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
+                  , 3
+                  , pnlsr.getSm().getCorLsaSeq()+1
+                  , pnlsr.getConfParameter().getRouterDeadInterval()
+                  , pnlsr.getConfParameter().getCorR()
+                  , pnlsr.getConfParameter().getCorTheta() );
+    pnlsr.getSm().setCorLsaSeq(pnlsr.getSm().getCorLsaSeq()+1);
+    installCorLsa(pnlsr, corLsa);
+    return true;
+  }
+
+  std::pair<CorLsa&, bool>
+  Lsdb::getCorLsa(string key)
+  {
+    std::list< CorLsa >::iterator it = std::find_if( corLsdb.begin(),
+                                       corLsdb.end(),
+                                       bind(corLsaCompareByKey, _1, key));
+    if( it != corLsdb.end())
     {
-        CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
-                      , 3
-                      , pnlsr.getSm().getCorLsaSeq()+1
-                      , pnlsr.getConfParameter().getRouterDeadInterval()
-                      , pnlsr.getConfParameter().getCorR()
-                      , pnlsr.getConfParameter().getCorTheta() );
-        pnlsr.getSm().setCorLsaSeq(pnlsr.getSm().getCorLsaSeq()+1);
-        installCorLsa(pnlsr, corLsa);
+      return std::make_pair(boost::ref((*it)), true);
+    }
+    CorLsa clsa;
+    return std::make_pair(boost::ref(clsa),false);
+  }
+
+  bool
+  Lsdb::isCorLsaNew(string key, uint64_t seqNo)
+  {
+    std::pair<CorLsa& , bool>  corLsaCheck=getCorLsa(key);
+    if(corLsaCheck.second)
+    {
+      if(corLsaCheck.first.getLsSeqNo() < seqNo)
+      {
         return true;
-    }
-
-    std::pair<CorLsa&, bool>
-    Lsdb::getCorLsa(string key)
-    {
-        std::list< CorLsa >::iterator it = std::find_if( corLsdb.begin(),
-                                           corLsdb.end(),
-                                           bind(corLsaCompareByKey, _1, key));
-        if( it != corLsdb.end())
-        {
-            return std::make_pair(boost::ref((*it)), true);
-        }
-        CorLsa clsa;
-        return std::make_pair(boost::ref(clsa),false);
-    }
-
-    bool
-    Lsdb::isCorLsaNew(string key, uint64_t seqNo)
-    {
-        std::pair<CorLsa& , bool>  corLsaCheck=getCorLsa(key);
-        if(corLsaCheck.second)
-        {
-            if(corLsaCheck.first.getLsSeqNo() < seqNo)
-            {
-                return true;
-            }
-            else
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    ndn::EventId
-    Lsdb::scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
-    {
-        return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-                ndn::bind(&Lsdb::exprireOrRefreshCorLsa,
-                          this,boost::ref(pnlsr),key,seqNo));
-    }
-
-    bool
-    Lsdb::installCorLsa(Nlsr& pnlsr, CorLsa &clsa)
-    {
-        int timeToExpire=lsaRefreshTime;
-        std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(clsa.getCorLsaKey());
-        if ( !chkCorLsa.second )
-        {
-            addCorLsa(clsa);
-            printCorLsdb(); //debugging purpose
-            if ( clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-            {
-                pnlsr.getNpt().addNpte(clsa.getOrigRouter(),clsa.getOrigRouter(),pnlsr);
-            }
-            if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-            {
-                pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-            }
-            if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-            {
-                timeToExpire=clsa.getLifeTime();
-            }
-            scheduleCorLsaExpiration(pnlsr,clsa.getCorLsaKey(),
-                                     clsa.getLsSeqNo(), timeToExpire);
-        }
-        else
-        {
-            if ( chkCorLsa.first.getLsSeqNo() < clsa.getLsSeqNo() )
-            {
-                chkCorLsa.first.setLsSeqNo(clsa.getLsSeqNo());
-                chkCorLsa.first.setLifeTime(clsa.getLifeTime());
-                if ( !chkCorLsa.first.isLsaContentEqual(clsa) )
-                {
-                    chkCorLsa.first.setCorRadius(clsa.getCorRadius());
-                    chkCorLsa.first.setCorTheta(clsa.getCorTheta());
-                    if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-                    {
-                        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-                    }
-                }
-                if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-                {
-                    timeToExpire=clsa.getLifeTime();
-                }
-                cancelScheduleLsaExpiringEvent(pnlsr,
-                                               chkCorLsa.first.getLsaExpiringEventId());
-                chkCorLsa.first.setLsaExpiringEventId(scheduleCorLsaExpiration(pnlsr,
-                                                      clsa.getCorLsaKey(),
-                                                      clsa.getLsSeqNo(), timeToExpire));
-            }
-        }
-        return true;
-    }
-
-    bool
-    Lsdb::addCorLsa(CorLsa& clsa)
-    {
-        std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
-                                          corLsdb.end(),
-                                          bind(corLsaCompareByKey, _1, clsa.getCorLsaKey()));
-        if( it == corLsdb.end())
-        {
-            corLsdb.push_back(clsa);
-            return true;
-        }
+      }
+      else
+      {
         return false;
+      }
     }
+    return true;
+  }
 
-    bool
-    Lsdb::removeCorLsa(Nlsr& pnlsr, string& key)
-    {
-        std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
-                                          corLsdb.end(),
-                                          bind(corLsaCompareByKey, _1, key));
-        if ( it != corLsdb.end() )
-        {
-            if ( (*it).getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-            {
-                pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
-            }
-            corLsdb.erase(it);
-            return true;
-        }
-        return false;
-    }
+  ndn::EventId
+  Lsdb::scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+  {
+    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
+           ndn::bind(&Lsdb::exprireOrRefreshCorLsa,
+                     this,boost::ref(pnlsr),key,seqNo));
+  }
 
-    bool
-    Lsdb::doesCorLsaExist(string key)
+  bool
+  Lsdb::installCorLsa(Nlsr& pnlsr, CorLsa &clsa)
+  {
+    int timeToExpire=lsaRefreshTime;
+    std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(clsa.getCorLsaKey());
+    if ( !chkCorLsa.second )
     {
-        std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
-                                          corLsdb.end(),
-                                          bind(corLsaCompareByKey, _1, key));
-        if( it == corLsdb.end())
-        {
-            return false;
-        }
-        return true;
+      addCorLsa(clsa);
+      printCorLsdb(); //debugging purpose
+      if ( clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+      {
+        pnlsr.getNpt().addNpteByDestName(clsa.getOrigRouter(),clsa.getOrigRouter(),
+                                         pnlsr);
+      }
+      if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
+      {
+        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+      }
+      if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+      {
+        timeToExpire=clsa.getLifeTime();
+      }
+      scheduleCorLsaExpiration(pnlsr,clsa.getCorLsaKey(),
+                               clsa.getLsSeqNo(), timeToExpire);
     }
+    else
+    {
+      if ( chkCorLsa.first.getLsSeqNo() < clsa.getLsSeqNo() )
+      {
+        chkCorLsa.first.setLsSeqNo(clsa.getLsSeqNo());
+        chkCorLsa.first.setLifeTime(clsa.getLifeTime());
+        if ( !chkCorLsa.first.isLsaContentEqual(clsa) )
+        {
+          chkCorLsa.first.setCorRadius(clsa.getCorRadius());
+          chkCorLsa.first.setCorTheta(clsa.getCorTheta());
+          if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
+          {
+            pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+          }
+        }
+        if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+        {
+          timeToExpire=clsa.getLifeTime();
+        }
+        cancelScheduleLsaExpiringEvent(pnlsr,
+                                       chkCorLsa.first.getLsaExpiringEventId());
+        chkCorLsa.first.setLsaExpiringEventId(scheduleCorLsaExpiration(pnlsr,
+                                              clsa.getCorLsaKey(),
+                                              clsa.getLsSeqNo(), timeToExpire));
+      }
+    }
+    return true;
+  }
 
-    void
-    Lsdb::printCorLsdb() //debugging
+  bool
+  Lsdb::addCorLsa(CorLsa& clsa)
+  {
+    std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
+                                      corLsdb.end(),
+                                      bind(corLsaCompareByKey, _1, clsa.getCorLsaKey()));
+    if( it == corLsdb.end())
     {
-        cout<<"---------------Cor LSDB-------------------"<<endl;
-        for( std::list<CorLsa>::iterator it=corLsdb.begin();
-                it!= corLsdb.end() ; it++)
-        {
-            cout<< (*it) <<endl;
-        }
+      corLsdb.push_back(clsa);
+      return true;
     }
+    return false;
+  }
+
+  bool
+  Lsdb::removeCorLsa(Nlsr& pnlsr, string& key)
+  {
+    std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
+                                      corLsdb.end(),
+                                      bind(corLsaCompareByKey, _1, key));
+    if ( it != corLsdb.end() )
+    {
+      if ( (*it).getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+      {
+        pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
+      }
+      corLsdb.erase(it);
+      return true;
+    }
+    return false;
+  }
+
+  bool
+  Lsdb::doesCorLsaExist(string key)
+  {
+    std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(),
+                                      corLsdb.end(),
+                                      bind(corLsaCompareByKey, _1, key));
+    if( it == corLsdb.end())
+    {
+      return false;
+    }
+    return true;
+  }
+
+  void
+  Lsdb::printCorLsdb() //debugging
+  {
+    cout<<"---------------Cor LSDB-------------------"<<endl;
+    for( std::list<CorLsa>::iterator it=corLsdb.begin();
+         it!= corLsdb.end() ; it++)
+    {
+      cout<< (*it) <<endl;
+    }
+  }
 
 
 // Adj LSA and LSDB related function starts here
 
-    static bool
-    adjLsaCompareByKey(AdjLsa& alsa, string& key)
-    {
-        return alsa.getAdjLsaKey()==key;
-    }
+  static bool
+  adjLsaCompareByKey(AdjLsa& alsa, string& key)
+  {
+    return alsa.getAdjLsaKey()==key;
+  }
 
 
-    void
-    Lsdb::scheduledAdjLsaBuild(Nlsr& pnlsr)
+  void
+  Lsdb::scheduledAdjLsaBuild(Nlsr& pnlsr)
+  {
+    cout<<"scheduledAdjLsaBuild Called"<<endl;
+    pnlsr.setIsBuildAdjLsaSheduled(0);
+    if( pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
     {
-        cout<<"scheduledAdjLsaBuild Called"<<endl;
-        pnlsr.setIsBuildAdjLsaSheduled(0);
-        if( pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
+      int adjBuildCount=pnlsr.getAdjBuildCount();
+      if(adjBuildCount>0 )
+      {
+        if (pnlsr.getAdl().getNumOfActiveNeighbor()>0)
         {
-            int adjBuildCount=pnlsr.getAdjBuildCount();
-            if(adjBuildCount>0 )
-            {
-                if (pnlsr.getAdl().getNumOfActiveNeighbor()>0)
-                {
-                    buildAndInstallOwnAdjLsa(pnlsr);
-                }
-                else
-                {
-                    string key=pnlsr.getConfParameter().getRouterPrefix()+"/2";
-                    removeAdjLsa(pnlsr,key);
-                    pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-                }
-                pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount()-adjBuildCount);
-            }
+          buildAndInstallOwnAdjLsa(pnlsr);
         }
         else
         {
-            pnlsr.setIsBuildAdjLsaSheduled(1);
-            int schedulingTime=pnlsr.getConfParameter().getInterestRetryNumber()*
-                               pnlsr.getConfParameter().getInterestResendTime();
-            pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(schedulingTime),
-                                               ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
-                                                       boost::ref(pnlsr)));
+          string key=pnlsr.getConfParameter().getRouterPrefix()+"/2";
+          removeAdjLsa(pnlsr,key);
+          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
         }
+        pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount()-adjBuildCount);
+      }
     }
-
-
-    bool
-    Lsdb::addAdjLsa(AdjLsa &alsa)
+    else
     {
-        std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
-                                          adjLsdb.end(),
-                                          bind(adjLsaCompareByKey, _1, alsa.getAdjLsaKey()));
-        if( it == adjLsdb.end())
-        {
-            adjLsdb.push_back(alsa);
-            return true;
-        }
-        return false;
+      pnlsr.setIsBuildAdjLsaSheduled(1);
+      int schedulingTime=pnlsr.getConfParameter().getInterestRetryNumber()*
+                         pnlsr.getConfParameter().getInterestResendTime();
+      pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(schedulingTime),
+                                         ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
+                                             boost::ref(pnlsr)));
     }
+  }
 
-    std::pair<AdjLsa& , bool>
-    Lsdb::getAdjLsa(string key)
+
+  bool
+  Lsdb::addAdjLsa(AdjLsa &alsa)
+  {
+    std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
+                                      adjLsdb.end(),
+                                      bind(adjLsaCompareByKey, _1, alsa.getAdjLsaKey()));
+    if( it == adjLsdb.end())
     {
-        std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
-                                          adjLsdb.end(),
-                                          bind(adjLsaCompareByKey, _1, key));
-        if( it != adjLsdb.end())
-        {
-            return std::make_pair(boost::ref((*it)),true);
-        }
-        AdjLsa alsa;
-        return std::make_pair(boost::ref(alsa),false);
+      adjLsdb.push_back(alsa);
+      return true;
     }
+    return false;
+  }
 
-
-    bool
-    Lsdb::isAdjLsaNew(string key, uint64_t seqNo)
+  std::pair<AdjLsa& , bool>
+  Lsdb::getAdjLsa(string key)
+  {
+    std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
+                                      adjLsdb.end(),
+                                      bind(adjLsaCompareByKey, _1, key));
+    if( it != adjLsdb.end())
     {
-        std::pair<AdjLsa& , bool>  adjLsaCheck=getAdjLsa(key);
-        if(adjLsaCheck.second)
-        {
-            if(adjLsaCheck.first.getLsSeqNo() < seqNo)
-            {
-                return true;
-            }
-            else
-            {
-                return false;
-            }
-        }
+      return std::make_pair(boost::ref((*it)),true);
+    }
+    AdjLsa alsa;
+    return std::make_pair(boost::ref(alsa),false);
+  }
+
+
+  bool
+  Lsdb::isAdjLsaNew(string key, uint64_t seqNo)
+  {
+    std::pair<AdjLsa& , bool>  adjLsaCheck=getAdjLsa(key);
+    if(adjLsaCheck.second)
+    {
+      if(adjLsaCheck.first.getLsSeqNo() < seqNo)
+      {
         return true;
+      }
+      else
+      {
+        return false;
+      }
     }
+    return true;
+  }
 
 
-    ndn::EventId
-    Lsdb::scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+  ndn::EventId
+  Lsdb::scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime)
+  {
+    return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
+           ndn::bind(&Lsdb::exprireOrRefreshAdjLsa,
+                     this,boost::ref(pnlsr),key,seqNo));
+  }
+
+  bool
+  Lsdb::installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa)
+  {
+    int timeToExpire=lsaRefreshTime;
+    std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
+    if ( !chkAdjLsa.second )
     {
-        return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-                ndn::bind(&Lsdb::exprireOrRefreshAdjLsa,
-                          this,boost::ref(pnlsr),key,seqNo));
+      addAdjLsa(alsa);
+      alsa.addNptEntriesForAdjLsa(pnlsr);
+      pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+      if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+      {
+        timeToExpire=alsa.getLifeTime();
+      }
+      scheduleAdjLsaExpiration(pnlsr,alsa.getAdjLsaKey(),
+                               alsa.getLsSeqNo(),timeToExpire);
     }
-
-    bool
-    Lsdb::installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa)
+    else
     {
-        int timeToExpire=lsaRefreshTime;
-        std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
-        if ( !chkAdjLsa.second )
+      if ( chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo() )
+      {
+        chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
+        chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
+        if ( !	chkAdjLsa.first.isLsaContentEqual(alsa))
         {
-            addAdjLsa(alsa);
-            alsa.addNptEntriesForAdjLsa(pnlsr);
-            pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-            if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-            {
-                timeToExpire=alsa.getLifeTime();
-            }
-            scheduleAdjLsaExpiration(pnlsr,alsa.getAdjLsaKey(),
-                                     alsa.getLsSeqNo(),timeToExpire);
+          chkAdjLsa.first.getAdl().resetAdl();
+          chkAdjLsa.first.getAdl().addAdjacentsFromAdl(alsa.getAdl());
+          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+        }
+        if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+        {
+          timeToExpire=alsa.getLifeTime();
+        }
+        cancelScheduleLsaExpiringEvent(pnlsr,
+                                       chkAdjLsa.first.getLsaExpiringEventId());
+        chkAdjLsa.first.setLsaExpiringEventId(scheduleAdjLsaExpiration(pnlsr,
+                                              alsa.getAdjLsaKey(), alsa.getLsSeqNo(),timeToExpire));
+      }
+    }
+    return true;
+  }
+
+  bool
+  Lsdb::buildAndInstallOwnAdjLsa(Nlsr& pnlsr)
+  {
+    AdjLsa adjLsa(pnlsr.getConfParameter().getRouterPrefix()
+                  , 2
+                  , pnlsr.getSm().getAdjLsaSeq()+1
+                  , pnlsr.getConfParameter().getRouterDeadInterval()
+                  , pnlsr.getAdl().getNumOfActiveNeighbor()
+                  , pnlsr.getAdl() );
+    pnlsr.getSm().setAdjLsaSeq(pnlsr.getSm().getAdjLsaSeq()+1);
+    string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                     + pnlsr.getConfParameter().getRouterPrefix();
+    pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
+    return pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+  }
+
+  bool
+  Lsdb::removeAdjLsa(Nlsr& pnlsr, string& key)
+  {
+    std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
+                                      adjLsdb.end(),
+                                      bind(adjLsaCompareByKey, _1, key));
+    if ( it != adjLsdb.end() )
+    {
+      (*it).removeNptEntriesForAdjLsa(pnlsr);
+      adjLsdb.erase(it);
+      return true;
+    }
+    return false;
+  }
+
+  bool
+  Lsdb::doesAdjLsaExist(string key)
+  {
+    std::list< AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
+                                       adjLsdb.end(),
+                                       bind(adjLsaCompareByKey, _1, key));
+    if( it == adjLsdb.end())
+    {
+      return false;
+    }
+    return true;
+  }
+
+  std::list<AdjLsa>&
+  Lsdb::getAdjLsdb()
+  {
+    return adjLsdb;
+  }
+
+  void
+  Lsdb::setLsaRefreshTime(int lrt)
+  {
+    lsaRefreshTime=lrt;
+  }
+
+  void
+  Lsdb::setThisRouterPrefix(string trp)
+  {
+    thisRouterPrefix=trp;
+  }
+
+  void
+  Lsdb::exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
+  {
+    cout<<"Lsdb::exprireOrRefreshNameLsa Called "<<endl;
+    cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
+    std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(lsaKey);
+    if( chkNameLsa.second )
+    {
+      cout<<" LSA Exists with seq no: "<<chkNameLsa.first.getLsSeqNo()<<endl;
+      if ( chkNameLsa.first.getLsSeqNo() == seqNo )
+      {
+        if(chkNameLsa.first.getOrigRouter() == thisRouterPrefix )
+        {
+          cout<<"Own Name LSA, so refreshing name LSA"<<endl;
+          chkNameLsa.first.setLsSeqNo(chkNameLsa.first.getLsSeqNo()+1);
+          pnlsr.getSm().setNameLsaSeq(chkNameLsa.first.getLsSeqNo());
+          // publish routing update
+          string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                           + pnlsr.getConfParameter().getRouterPrefix();
+          pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
         }
         else
         {
-            if ( chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo() )
-            {
-                chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
-                chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
-                if ( !	chkAdjLsa.first.isLsaContentEqual(alsa))
-                {
-                    chkAdjLsa.first.getAdl().resetAdl();
-                    chkAdjLsa.first.getAdl().addAdjacentsFromAdl(alsa.getAdl());
-                    pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-                }
-                if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-                {
-                    timeToExpire=alsa.getLifeTime();
-                }
-                cancelScheduleLsaExpiringEvent(pnlsr,
-                                               chkAdjLsa.first.getLsaExpiringEventId());
-                chkAdjLsa.first.setLsaExpiringEventId(scheduleAdjLsaExpiration(pnlsr,
-                                                      alsa.getAdjLsaKey(), alsa.getLsSeqNo(),timeToExpire));
-            }
+          cout<<"Other's Name LSA, so removing form LSDB"<<endl;
+          removeNameLsa(pnlsr, lsaKey);
         }
-        return true;
+      }
     }
+  }
 
-    bool
-    Lsdb::buildAndInstallOwnAdjLsa(Nlsr& pnlsr)
+  void
+  Lsdb::exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
+  {
+    cout<<"Lsdb::exprireOrRefreshAdjLsa Called "<<endl;
+    cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
+    std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(lsaKey);
+    if( chkAdjLsa.second )
     {
-        AdjLsa adjLsa(pnlsr.getConfParameter().getRouterPrefix()
-                      , 2
-                      , pnlsr.getSm().getAdjLsaSeq()+1
-                      , pnlsr.getConfParameter().getRouterDeadInterval()
-                      , pnlsr.getAdl().getNumOfActiveNeighbor()
-                      , pnlsr.getAdl() );
-        pnlsr.getSm().setAdjLsaSeq(pnlsr.getSm().getAdjLsaSeq()+1);
-        string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                         + pnlsr.getConfParameter().getRouterPrefix();
-        pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-        return pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
-    }
-
-    bool
-    Lsdb::removeAdjLsa(Nlsr& pnlsr, string& key)
-    {
-        std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
-                                          adjLsdb.end(),
-                                          bind(adjLsaCompareByKey, _1, key));
-        if ( it != adjLsdb.end() )
+      cout<<" LSA Exists with seq no: "<<chkAdjLsa.first.getLsSeqNo()<<endl;
+      if ( chkAdjLsa.first.getLsSeqNo() == seqNo )
+      {
+        if(chkAdjLsa.first.getOrigRouter() == thisRouterPrefix )
         {
-            (*it).removeNptEntriesForAdjLsa(pnlsr);
-            adjLsdb.erase(it);
-            return true;
+          cout<<"Own Adj LSA, so refreshing Adj LSA"<<endl;
+          chkAdjLsa.first.setLsSeqNo(chkAdjLsa.first.getLsSeqNo()+1);
+          pnlsr.getSm().setAdjLsaSeq(chkAdjLsa.first.getLsSeqNo());
+          // publish routing update
+          string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                           + pnlsr.getConfParameter().getRouterPrefix();
+          pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
         }
-        return false;
-    }
-
-    bool
-    Lsdb::doesAdjLsaExist(string key)
-    {
-        std::list< AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
-                                           adjLsdb.end(),
-                                           bind(adjLsaCompareByKey, _1, key));
-        if( it == adjLsdb.end())
+        else
         {
-            return false;
+          cout<<"Other's Adj LSA, so removing form LSDB"<<endl;
+          removeAdjLsa(pnlsr, lsaKey);
         }
-        return true;
+        // schedule Routing table calculaiton
+        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+      }
     }
+  }
 
-    std::list<AdjLsa>&
-    Lsdb::getAdjLsdb()
+  void
+  Lsdb::exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
+  {
+    cout<<"Lsdb::exprireOrRefreshCorLsa Called "<<endl;
+    cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
+    std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(lsaKey);
+    if( chkCorLsa.second )
     {
-        return adjLsdb;
-    }
-
-    void
-    Lsdb::setLsaRefreshTime(int lrt)
-    {
-        lsaRefreshTime=lrt;
-    }
-
-    void
-    Lsdb::setThisRouterPrefix(string trp)
-    {
-        thisRouterPrefix=trp;
-    }
-
-    void
-    Lsdb::exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-    {
-        cout<<"Lsdb::exprireOrRefreshNameLsa Called "<<endl;
-        cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
-        std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(lsaKey);
-        if( chkNameLsa.second )
+      cout<<" LSA Exists with seq no: "<<chkCorLsa.first.getLsSeqNo()<<endl;
+      if ( chkCorLsa.first.getLsSeqNo() == seqNo )
+      {
+        if(chkCorLsa.first.getOrigRouter() == thisRouterPrefix )
         {
-            cout<<" LSA Exists with seq no: "<<chkNameLsa.first.getLsSeqNo()<<endl;
-            if ( chkNameLsa.first.getLsSeqNo() == seqNo )
-            {
-                if(chkNameLsa.first.getOrigRouter() == thisRouterPrefix )
-                {
-                    cout<<"Own Name LSA, so refreshing name LSA"<<endl;
-                    chkNameLsa.first.setLsSeqNo(chkNameLsa.first.getLsSeqNo()+1);
-                    pnlsr.getSm().setNameLsaSeq(chkNameLsa.first.getLsSeqNo());
-                    // publish routing update
-                    string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                                     + pnlsr.getConfParameter().getRouterPrefix();
-                    pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-                }
-                else
-                {
-                    cout<<"Other's Name LSA, so removing form LSDB"<<endl;
-                    removeNameLsa(pnlsr, lsaKey);
-                }
-            }
+          cout<<"Own Cor LSA, so refreshing Cor LSA"<<endl;
+          chkCorLsa.first.setLsSeqNo(chkCorLsa.first.getLsSeqNo()+1);
+          pnlsr.getSm().setCorLsaSeq(chkCorLsa.first.getLsSeqNo());
+          // publish routing update
+          string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
+                           + pnlsr.getConfParameter().getRouterPrefix();
+          pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
         }
-    }
-
-    void
-    Lsdb::exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-    {
-        cout<<"Lsdb::exprireOrRefreshAdjLsa Called "<<endl;
-        cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
-        std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(lsaKey);
-        if( chkAdjLsa.second )
+        else
         {
-            cout<<" LSA Exists with seq no: "<<chkAdjLsa.first.getLsSeqNo()<<endl;
-            if ( chkAdjLsa.first.getLsSeqNo() == seqNo )
-            {
-                if(chkAdjLsa.first.getOrigRouter() == thisRouterPrefix )
-                {
-                    cout<<"Own Adj LSA, so refreshing Adj LSA"<<endl;
-                    chkAdjLsa.first.setLsSeqNo(chkAdjLsa.first.getLsSeqNo()+1);
-                    pnlsr.getSm().setAdjLsaSeq(chkAdjLsa.first.getLsSeqNo());
-                    // publish routing update
-                    string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                                     + pnlsr.getConfParameter().getRouterPrefix();
-                    pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-                }
-                else
-                {
-                    cout<<"Other's Adj LSA, so removing form LSDB"<<endl;
-                    removeAdjLsa(pnlsr, lsaKey);
-                }
-                // schedule Routing table calculaiton
-                pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-            }
+          cout<<"Other's Cor LSA, so removing form LSDB"<<endl;
+          removeCorLsa(pnlsr, lsaKey);
         }
-    }
-
-    void
-    Lsdb::exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-    {
-        cout<<"Lsdb::exprireOrRefreshCorLsa Called "<<endl;
-        cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<seqNo<<endl;
-        std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(lsaKey);
-        if( chkCorLsa.second )
+        if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
         {
-            cout<<" LSA Exists with seq no: "<<chkCorLsa.first.getLsSeqNo()<<endl;
-            if ( chkCorLsa.first.getLsSeqNo() == seqNo )
-            {
-                if(chkCorLsa.first.getOrigRouter() == thisRouterPrefix )
-                {
-                    cout<<"Own Cor LSA, so refreshing Cor LSA"<<endl;
-                    chkCorLsa.first.setLsSeqNo(chkCorLsa.first.getLsSeqNo()+1);
-                    pnlsr.getSm().setCorLsaSeq(chkCorLsa.first.getLsSeqNo());
-                    // publish routing update
-                    string lsaPrefix=pnlsr.getConfParameter().getChronosyncLsaPrefix()
-                                     + pnlsr.getConfParameter().getRouterPrefix();
-                    pnlsr.getSlh().publishRoutingUpdate(pnlsr.getSm(),lsaPrefix);
-                }
-                else
-                {
-                    cout<<"Other's Cor LSA, so removing form LSDB"<<endl;
-                    removeCorLsa(pnlsr, lsaKey);
-                }
-                if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-                {
-                    pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-                }
-            }
+          pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
         }
+      }
     }
+  }
 
 
-    void
-    Lsdb::printAdjLsdb()
+  void
+  Lsdb::printAdjLsdb()
+  {
+    cout<<"---------------Adj LSDB-------------------"<<endl;
+    for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+         it!= adjLsdb.end() ; it++)
     {
-        cout<<"---------------Adj LSDB-------------------"<<endl;
-        for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
-                it!= adjLsdb.end() ; it++)
-        {
-            cout<< (*it) <<endl;
-        }
+      cout<< (*it) <<endl;
     }
+  }
 
 //-----utility function -----
-    bool
-    Lsdb::doesLsaExist(string key, int lsType)
+  bool
+  Lsdb::doesLsaExist(string key, int lsType)
+  {
+    if ( lsType == 1)
     {
-        if ( lsType == 1)
-        {
-            return doesNameLsaExist(key);
-        }
-        else if ( lsType == 2)
-        {
-            return doesAdjLsaExist(key);
-        }
-        else if ( lsType == 3)
-        {
-            return doesCorLsaExist(key);
-        }
-        return false;
+      return doesNameLsaExist(key);
     }
+    else if ( lsType == 2)
+    {
+      return doesAdjLsaExist(key);
+    }
+    else if ( lsType == 3)
+    {
+      return doesCorLsaExist(key);
+    }
+    return false;
+  }
 
 }//namespace nlsr
 
diff --git a/src/nlsr_lsdb.hpp b/src/nlsr_lsdb.hpp
index 6862224..24bfec3 100644
--- a/src/nlsr_lsdb.hpp
+++ b/src/nlsr_lsdb.hpp
@@ -7,83 +7,83 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Nlsr;
+  class Nlsr;
 
-    class Lsdb
+  class Lsdb
+  {
+  public:
+    Lsdb()
+      : lsaRefreshTime(0)
     {
-    public:
-        Lsdb()
-            : lsaRefreshTime(0)
-        {
-        }
+    }
 
 
-        bool doesLsaExist(string key, int lsType);
-        // function related to Name LSDB
-        bool buildAndInstallOwnNameLsa(Nlsr& pnlsr);
-        std::pair<NameLsa&, bool>  getNameLsa(string key);
-        bool installNameLsa(Nlsr& pnlsr, NameLsa &nlsa);
-        bool removeNameLsa(Nlsr& pnlsr, string& key);
-        bool isNameLsaNew(string key, uint64_t seqNo);
-        void printNameLsdb(); //debugging
+    bool doesLsaExist(string key, int lsType);
+    // function related to Name LSDB
+    bool buildAndInstallOwnNameLsa(Nlsr& pnlsr);
+    std::pair<NameLsa&, bool>  getNameLsa(string key);
+    bool installNameLsa(Nlsr& pnlsr, NameLsa &nlsa);
+    bool removeNameLsa(Nlsr& pnlsr, string& key);
+    bool isNameLsaNew(string key, uint64_t seqNo);
+    void printNameLsdb(); //debugging
 
-        //function related to Cor LSDB
-        bool buildAndInstallOwnCorLsa(Nlsr& pnlsr);
-        std::pair<CorLsa&, bool> getCorLsa(string key);
-        bool installCorLsa(Nlsr& pnlsr, CorLsa &clsa);
-        bool removeCorLsa(Nlsr& pnlsr, string& key);
-        bool isCorLsaNew(string key, uint64_t seqNo);
-        void printCorLsdb(); //debugging
+    //function related to Cor LSDB
+    bool buildAndInstallOwnCorLsa(Nlsr& pnlsr);
+    std::pair<CorLsa&, bool> getCorLsa(string key);
+    bool installCorLsa(Nlsr& pnlsr, CorLsa &clsa);
+    bool removeCorLsa(Nlsr& pnlsr, string& key);
+    bool isCorLsaNew(string key, uint64_t seqNo);
+    void printCorLsdb(); //debugging
 
-        //function related to Adj LSDB
-        void scheduledAdjLsaBuild(Nlsr& pnlsr);
-        bool buildAndInstallOwnAdjLsa(Nlsr& pnlsr);
-        bool removeAdjLsa(Nlsr& pnlsr, string& key);
-        bool isAdjLsaNew(string key, uint64_t seqNo);
-        bool installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa);
-        std::pair<AdjLsa& , bool> getAdjLsa(string key);
-        std::list<AdjLsa>& getAdjLsdb();
-        void printAdjLsdb();
+    //function related to Adj LSDB
+    void scheduledAdjLsaBuild(Nlsr& pnlsr);
+    bool buildAndInstallOwnAdjLsa(Nlsr& pnlsr);
+    bool removeAdjLsa(Nlsr& pnlsr, string& key);
+    bool isAdjLsaNew(string key, uint64_t seqNo);
+    bool installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa);
+    std::pair<AdjLsa& , bool> getAdjLsa(string key);
+    std::list<AdjLsa>& getAdjLsdb();
+    void printAdjLsdb();
 
-        //void scheduleRefreshLsdb(Nlsr& pnlsr, int interval);
-        void setLsaRefreshTime(int lrt);
-        void setThisRouterPrefix(string trp);
+    //void scheduleRefreshLsdb(Nlsr& pnlsr, int interval);
+    void setLsaRefreshTime(int lrt);
+    void setThisRouterPrefix(string trp);
 
-    private:
-        bool addNameLsa(NameLsa &nlsa);
-        bool doesNameLsaExist(string key);
+  private:
+    bool addNameLsa(NameLsa &nlsa);
+    bool doesNameLsaExist(string key);
 
 
-        bool addCorLsa(CorLsa& clsa);
-        bool doesCorLsaExist(string key);
+    bool addCorLsa(CorLsa& clsa);
+    bool doesCorLsaExist(string key);
 
-        bool addAdjLsa(AdjLsa &alsa);
-        bool doesAdjLsaExist(string key);
+    bool addAdjLsa(AdjLsa &alsa);
+    bool doesAdjLsaExist(string key);
 
-        ndn::EventId
-        scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
-        void exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
-        ndn::EventId
-        scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
-        void exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
-        ndn::EventId
-        scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
-        void exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
+    ndn::EventId
+    scheduleNameLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
+    void exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
+    ndn::EventId
+    scheduleAdjLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
+    void exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
+    ndn::EventId
+    scheduleCorLsaExpiration(Nlsr& pnlsr, string key, int seqNo, int expTime);
+    void exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo);
 
 
-    private:
-        void cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid);
+  private:
+    void cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid);
 
-        std::list<NameLsa> nameLsdb;
-        std::list<AdjLsa> adjLsdb;
-        std::list<CorLsa> corLsdb;
+    std::list<NameLsa> nameLsdb;
+    std::list<AdjLsa> adjLsdb;
+    std::list<CorLsa> corLsdb;
 
-        int lsaRefreshTime;
-        string thisRouterPrefix;
+    int lsaRefreshTime;
+    string thisRouterPrefix;
 
-    };
+  };
 
 }//namespace nlsr
 
diff --git a/src/nlsr_npl.cpp b/src/nlsr_npl.cpp
index e8356cb..d8b2087 100644
--- a/src/nlsr_npl.cpp
+++ b/src/nlsr_npl.cpp
@@ -6,65 +6,65 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    Npl::Npl()
-    {
-    }
+  Npl::Npl()
+  {
+  }
 
-    Npl::~Npl()
-    {
-    }
+  Npl::~Npl()
+  {
+  }
 
-    static bool
-    nameCompare(string& s1, string& s2)
-    {
-        return s1==s2;
-    }
+  static bool
+  nameCompare(string& s1, string& s2)
+  {
+    return s1==s2;
+  }
 
-    int
-    Npl::insertIntoNpl(string& name)
+  int
+  Npl::insertIntoNpl(string& name)
+  {
+    std::list<string >::iterator it = std::find_if( nameList.begin(),
+                                      nameList.end(),
+                                      bind(&nameCompare, _1 , name));
+    if( it != nameList.end() )
     {
-        std::list<string >::iterator it = std::find_if( nameList.begin(),
-                                          nameList.end(),
-                                          bind(&nameCompare, _1 , name));
-        if( it != nameList.end() )
-        {
-            return -1;
-        }
-        nameList.push_back(name);
-        return 0;
+      return -1;
     }
+    nameList.push_back(name);
+    return 0;
+  }
 
-    int
-    Npl::removeFromNpl(string& name)
+  int
+  Npl::removeFromNpl(string& name)
+  {
+    std::list<string >::iterator it = std::find_if( nameList.begin(),
+                                      nameList.end(),
+                                      bind(&nameCompare, _1 , name));
+    if( it != nameList.end() )
     {
-        std::list<string >::iterator it = std::find_if( nameList.begin(),
-                                          nameList.end(),
-                                          bind(&nameCompare, _1 , name));
-        if( it != nameList.end() )
-        {
-            nameList.erase(it);
-        }
-        return -1;
+      nameList.erase(it);
     }
+    return -1;
+  }
 
-    void
-    Npl::sortNpl()
-    {
-        nameList.sort();
-    }
+  void
+  Npl::sortNpl()
+  {
+    nameList.sort();
+  }
 
-    void
-    Npl::printNpl()
+  void
+  Npl::printNpl()
+  {
+    int i=1;
+    for( std::list<string>::iterator it=nameList.begin(); it != nameList.end();
+         it++)
     {
-        int i=1;
-        for( std::list<string>::iterator it=nameList.begin(); it != nameList.end();
-                it++)
-        {
-            cout<<"Name "<<i<<" : "<<(*it)<<endl;
-            i++;
-        }
+      cout<<"Name "<<i<<" : "<<(*it)<<endl;
+      i++;
     }
+  }
 
 }//namespace nlsr
diff --git a/src/nlsr_npl.hpp b/src/nlsr_npl.hpp
index 3fc3db9..dd1bafa 100644
--- a/src/nlsr_npl.hpp
+++ b/src/nlsr_npl.hpp
@@ -8,32 +8,32 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Npl
+  class Npl
+  {
+
+  public:
+    Npl();
+    ~Npl();
+
+    int insertIntoNpl(string& name);
+    int removeFromNpl(string& name);
+    void sortNpl();
+    int getNplSize()
     {
+      return nameList.size();
+    }
+    std::list<string>& getNameList()
+    {
+      return nameList;
+    }
+    void printNpl();
 
-    public:
-        Npl();
-        ~Npl();
+  private:
+    std::list<string> nameList;
 
-        int insertIntoNpl(string& name);
-        int removeFromNpl(string& name);
-        void sortNpl();
-        int getNplSize()
-        {
-            return nameList.size();
-        }
-        std::list<string>& getNameList()
-        {
-            return nameList;
-        }
-        void printNpl();
-
-    private:
-        std::list<string> nameList;
-
-    };
+  };
 
 }//namespace nlsr
 
diff --git a/src/nlsr_sm.cpp b/src/nlsr_sm.cpp
index cae7f60..efc7614 100644
--- a/src/nlsr_sm.cpp
+++ b/src/nlsr_sm.cpp
@@ -10,87 +10,87 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    SequencingManager::splittSequenceNo(uint64_t seqNo)
-    {
-        combinedSeqNo=seqNo;
-        adjLsaSeq = (combinedSeqNo & 0xFFFFF);
-        corLsaSeq = ((combinedSeqNo >> 20) & 0xFFFFF);
-        nameLsaSeq = ((combinedSeqNo >> 40) & 0xFFFFF);
-    }
+  void
+  SequencingManager::splittSequenceNo(uint64_t seqNo)
+  {
+    combinedSeqNo=seqNo;
+    adjLsaSeq = (combinedSeqNo & 0xFFFFF);
+    corLsaSeq = ((combinedSeqNo >> 20) & 0xFFFFF);
+    nameLsaSeq = ((combinedSeqNo >> 40) & 0xFFFFF);
+  }
 
-    void
-    SequencingManager::combineSequenceNo()
-    {
-        combinedSeqNo=0;
-        combinedSeqNo = combinedSeqNo | adjLsaSeq;
-        combinedSeqNo = combinedSeqNo | (corLsaSeq<<20);
-        combinedSeqNo = combinedSeqNo | (nameLsaSeq<<40);
-    }
+  void
+  SequencingManager::combineSequenceNo()
+  {
+    combinedSeqNo=0;
+    combinedSeqNo = combinedSeqNo | adjLsaSeq;
+    combinedSeqNo = combinedSeqNo | (corLsaSeq<<20);
+    combinedSeqNo = combinedSeqNo | (nameLsaSeq<<40);
+  }
 
-    void
-    SequencingManager::writeSeqNoToFile()
-    {
-        std::ofstream outputFile(seqFileNameWithPath.c_str(),ios::binary);
-        outputFile<<combinedSeqNo;
-        outputFile.close();
-    }
+  void
+  SequencingManager::writeSeqNoToFile()
+  {
+    std::ofstream outputFile(seqFileNameWithPath.c_str(),ios::binary);
+    outputFile<<combinedSeqNo;
+    outputFile.close();
+  }
 
-    void
-    SequencingManager::initiateSeqNoFromFile()
+  void
+  SequencingManager::initiateSeqNoFromFile()
+  {
+    cout<<"Seq File Name: "<< seqFileNameWithPath<<endl;
+    std::ifstream inputFile(seqFileNameWithPath.c_str(),ios::binary);
+    if ( inputFile.good() )
     {
-        cout<<"Seq File Name: "<< seqFileNameWithPath<<endl;
-        std::ifstream inputFile(seqFileNameWithPath.c_str(),ios::binary);
-        if ( inputFile.good() )
-        {
-            inputFile>>combinedSeqNo;
-            splittSequenceNo(combinedSeqNo);
-            adjLsaSeq+=10;
-            corLsaSeq+=10;
-            nameLsaSeq+=10;
-            combineSequenceNo();
-            inputFile.close();
-        }
-        else
-        {
-            splittSequenceNo(0);
-        }
+      inputFile>>combinedSeqNo;
+      splittSequenceNo(combinedSeqNo);
+      adjLsaSeq+=10;
+      corLsaSeq+=10;
+      nameLsaSeq+=10;
+      combineSequenceNo();
+      inputFile.close();
     }
+    else
+    {
+      splittSequenceNo(0);
+    }
+  }
 
-    void
-    SequencingManager::setSeqFileName(string filePath)
+  void
+  SequencingManager::setSeqFileName(string filePath)
+  {
+    seqFileNameWithPath=filePath;
+    if( seqFileNameWithPath.empty() )
     {
-        seqFileNameWithPath=filePath;
-        if( seqFileNameWithPath.empty() )
-        {
-            seqFileNameWithPath=getUserHomeDirectory();
-        }
-        seqFileNameWithPath=seqFileNameWithPath+"/nlsrSeqNo.txt";
+      seqFileNameWithPath=getUserHomeDirectory();
     }
+    seqFileNameWithPath=seqFileNameWithPath+"/nlsrSeqNo.txt";
+  }
 
-    string
-    SequencingManager::getUserHomeDirectory()
+  string
+  SequencingManager::getUserHomeDirectory()
+  {
+    string homeDirPath(getpwuid(getuid())->pw_dir);
+    if( homeDirPath.empty() )
     {
-        string homeDirPath(getpwuid(getuid())->pw_dir);
-        if( homeDirPath.empty() )
-        {
-            homeDirPath = getenv("HOME");
-        }
-        return homeDirPath;
+      homeDirPath = getenv("HOME");
     }
+    return homeDirPath;
+  }
 
-    ostream&
-    operator <<(ostream& os, const SequencingManager& sm)
-    {
-        std::cout<<"----SequencingManager----"<<std::endl;
-        std::cout<<"Adj LSA seq no: "<<sm.getAdjLsaSeq()<<endl;
-        std::cout<<"Cor LSA Seq no: "<<sm.getCorLsaSeq()<<endl;
-        std::cout<<"Name LSA Seq no: "<<sm.getNameLsaSeq()<<endl;
-        std::cout<<"Combined LSDB Seq no: "<<sm.getCombinedSeqNo()<<endl;
-        return os;
-    }
+  ostream&
+  operator <<(ostream& os, const SequencingManager& sm)
+  {
+    std::cout<<"----SequencingManager----"<<std::endl;
+    std::cout<<"Adj LSA seq no: "<<sm.getAdjLsaSeq()<<endl;
+    std::cout<<"Cor LSA Seq no: "<<sm.getCorLsaSeq()<<endl;
+    std::cout<<"Name LSA Seq no: "<<sm.getNameLsaSeq()<<endl;
+    std::cout<<"Combined LSDB Seq no: "<<sm.getCombinedSeqNo()<<endl;
+    return os;
+  }
 
 }//namespace nlsr
 
diff --git a/src/nlsr_sm.hpp b/src/nlsr_sm.hpp
index b1b1b39..d1cbb23 100644
--- a/src/nlsr_sm.hpp
+++ b/src/nlsr_sm.hpp
@@ -8,90 +8,90 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class SequencingManager
+  class SequencingManager
+  {
+  public:
+    SequencingManager()
+      : nameLsaSeq(0)
+      , adjLsaSeq(0)
+      , corLsaSeq(0)
+      , combinedSeqNo(0)
+      , seqFileNameWithPath()
     {
-    public:
-        SequencingManager()
-            : nameLsaSeq(0)
-            , adjLsaSeq(0)
-            , corLsaSeq(0)
-            , combinedSeqNo(0)
-            , seqFileNameWithPath()
-        {
-        }
+    }
 
-        SequencingManager(uint64_t seqNo)
-        {
-            splittSequenceNo(seqNo);
-        }
+    SequencingManager(uint64_t seqNo)
+    {
+      splittSequenceNo(seqNo);
+    }
 
-        SequencingManager(uint64_t nlsn, uint64_t alsn, uint64_t clsn)
-        {
-            nameLsaSeq=nlsn;
-            adjLsaSeq=alsn;
-            corLsaSeq=clsn;
-            combineSequenceNo();
-        }
+    SequencingManager(uint64_t nlsn, uint64_t alsn, uint64_t clsn)
+    {
+      nameLsaSeq=nlsn;
+      adjLsaSeq=alsn;
+      corLsaSeq=clsn;
+      combineSequenceNo();
+    }
 
-        uint64_t getNameLsaSeq() const
-        {
-            return nameLsaSeq;
-        }
+    uint64_t getNameLsaSeq() const
+    {
+      return nameLsaSeq;
+    }
 
-        void setNameLsaSeq(uint64_t nlsn)
-        {
-            nameLsaSeq=nlsn;
-            combineSequenceNo();
-        }
+    void setNameLsaSeq(uint64_t nlsn)
+    {
+      nameLsaSeq=nlsn;
+      combineSequenceNo();
+    }
 
-        uint64_t getAdjLsaSeq() const
-        {
-            return adjLsaSeq;
-        }
+    uint64_t getAdjLsaSeq() const
+    {
+      return adjLsaSeq;
+    }
 
-        void setAdjLsaSeq(uint64_t alsn)
-        {
-            adjLsaSeq=alsn;
-            combineSequenceNo();
-        }
+    void setAdjLsaSeq(uint64_t alsn)
+    {
+      adjLsaSeq=alsn;
+      combineSequenceNo();
+    }
 
-        uint64_t getCorLsaSeq() const
-        {
-            return corLsaSeq;
-        }
+    uint64_t getCorLsaSeq() const
+    {
+      return corLsaSeq;
+    }
 
-        void setCorLsaSeq(uint64_t clsn)
-        {
-            corLsaSeq=clsn;
-            combineSequenceNo();
-        }
+    void setCorLsaSeq(uint64_t clsn)
+    {
+      corLsaSeq=clsn;
+      combineSequenceNo();
+    }
 
-        uint64_t getCombinedSeqNo() const
-        {
-            return combinedSeqNo;
-        }
+    uint64_t getCombinedSeqNo() const
+    {
+      return combinedSeqNo;
+    }
 
-        void writeSeqNoToFile();
-        void initiateSeqNoFromFile();
-        void setSeqFileName(string filePath);
-        string getUserHomeDirectory();
+    void writeSeqNoToFile();
+    void initiateSeqNoFromFile();
+    void setSeqFileName(string filePath);
+    string getUserHomeDirectory();
 
-    private:
-        void splittSequenceNo(uint64_t seqNo);
-        void combineSequenceNo();
+  private:
+    void splittSequenceNo(uint64_t seqNo);
+    void combineSequenceNo();
 
 
-    private:
-        uint64_t nameLsaSeq;
-        uint64_t adjLsaSeq;
-        uint64_t corLsaSeq;
-        uint64_t combinedSeqNo;
-        string seqFileNameWithPath;
-    };
+  private:
+    uint64_t nameLsaSeq;
+    uint64_t adjLsaSeq;
+    uint64_t corLsaSeq;
+    uint64_t combinedSeqNo;
+    string seqFileNameWithPath;
+  };
 
 
-    ostream& operator <<(ostream& os, const SequencingManager& sm);
+  ostream& operator <<(ostream& os, const SequencingManager& sm);
 }//namespace nlsr
 #endif
diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
index 5f4811c..9464f63 100644
--- a/src/route/nlsr_fe.cpp
+++ b/src/route/nlsr_fe.cpp
@@ -5,44 +5,44 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    bool
-    FibEntry::isEqualNextHops(Nhl &nhlOther)
+  bool
+  FibEntry::isEqualNextHops(Nhl &nhlOther)
+  {
+    if ( nhl.getNhlSize() != nhlOther.getNhlSize() )
     {
-        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() )
         {
-            return false;
+          it1->setRouteCost(it2->getRouteCost());
+          nhCount++;
         }
         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();
+          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;
-    }
+  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
index c85e045..edd77ab 100644
--- a/src/route/nlsr_fe.hpp
+++ b/src/route/nlsr_fe.hpp
@@ -11,74 +11,78 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class FibEntry
+  class FibEntry
+  {
+  public:
+    FibEntry()
+      : name()
+      , timeToRefresh(0)
+      , feSeqNo(0)
+      , nhl()
     {
-    public:
-        FibEntry()
-            : name()
-            , timeToRefresh(0)
-            , feSeqNo(0)
-        {
-        }
+    }
 
-        FibEntry(string n)
-        {
-            name=n;
-        }
+    FibEntry(string n)
+      : timeToRefresh(0)
+      , feSeqNo(0)
+      , nhl()
+    {
+      name=n;
+    }
 
-        string getName()
-        {
-            return name;
-        }
+    string getName()
+    {
+      return name;
+    }
 
-        Nhl& getNhl()
-        {
-            return nhl;
-        }
+    Nhl& getNhl()
+    {
+      return nhl;
+    }
 
-        int getTimeToRefresh()
-        {
-            return timeToRefresh;
-        }
+    int getTimeToRefresh()
+    {
+      return timeToRefresh;
+    }
 
-        void setTimeToRefresh(int ttr)
-        {
-            timeToRefresh=ttr;
-        }
+    void setTimeToRefresh(int ttr)
+    {
+      timeToRefresh=ttr;
+    }
 
-        void setFeExpiringEventId(ndn::EventId feid)
-        {
-            feExpiringEventId=feid;
-        }
+    void setFeExpiringEventId(ndn::EventId feid)
+    {
+      feExpiringEventId=feid;
+    }
 
-        ndn::EventId getFeExpiringEventId()
-        {
-            return feExpiringEventId;
-        }
+    ndn::EventId getFeExpiringEventId()
+    {
+      return feExpiringEventId;
+    }
 
-        void setFeSeqNo(int fsn)
-        {
-            feSeqNo=fsn;
-        }
+    void setFeSeqNo(int fsn)
+    {
+      feSeqNo=fsn;
+    }
 
-        int getFeSeqNo()
-        {
-            return feSeqNo;
-        }
+    int getFeSeqNo()
+    {
+      return feSeqNo;
+    }
 
-        bool isEqualNextHops(Nhl &nhlOther);
+    bool isEqualNextHops(Nhl &nhlOther);
 
-    private:
-        string name;
-        int timeToRefresh;
-        ndn::EventId feExpiringEventId;
-        int feSeqNo;
-        Nhl nhl;
-    };
+  private:
+    string name;
+    int timeToRefresh;
+    ndn::EventId feExpiringEventId;
+    int feSeqNo;
+    Nhl nhl;
+  };
 
-    ostream& operator<<(ostream& os, FibEntry& fe);
+  ostream& operator<<(ostream& os,FibEntry fe);
 
 } //namespace nlsr
 
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
index 8fb7928..8b03409 100644
--- a/src/route/nlsr_fib.cpp
+++ b/src/route/nlsr_fib.cpp
@@ -7,162 +7,177 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    static bool
-    fibEntryNameCompare(FibEntry& fe, string name)
+  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() )
     {
-        return fe.getName() == name ;
+      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::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
+
+  void
+  Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList)
+  {
+    std::cout<<"Fib::updateFib Called"<<std::endl;
+    int startFace=0;
+    int endFace=getNumberOfFacesForName(nextHopList,
+                                        pnlsr.getConfParameter().getMaxFacesPerPrefix());
+    std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                        fibTable.end(),
+                                        bind(&fibEntryNameCompare, _1, name));
+    if( it == fibTable.end() )
     {
-        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() )
+      if( nextHopList.getNhlSize() > 0 )
+      {
+        nextHopList.sortNhl();
+        FibEntry newEntry(name);
+        std::list<NextHop> nhl=nextHopList.getNextHopList();
+        std::list<NextHop>::iterator nhit=nhl.begin();
+        for(int i=startFace; i< endFace && nhit!=nhl.end(); ++nhit, i++)
         {
-            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);
+          newEntry.getNhl().addNextHop((*nhit));
+          //Add entry to NDN-FIB
         }
+        newEntry.getNhl().sortNhl();
+        newEntry.setTimeToRefresh(fibEntryRefreshTime);
+        newEntry.setFeSeqNo(1);
+        newEntry.setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                      name ,1,fibEntryRefreshTime));
+        fibTable.push_back(newEntry);
+      }
     }
-
-
-    void
-    Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+    else
     {
-        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() )
+      std::cout<<"Old FIB Entry"<<std::endl;
+      if( nextHopList.getNhlSize() > 0 )
+      {
+        nextHopList.sortNhl();
+        if ( !it->isEqualNextHops(nextHopList) )
         {
-            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
+          std::list<NextHop> nhl=nextHopList.getNextHopList();
+          std::list<NextHop>::iterator nhit=nhl.begin();
+          // Add first Entry to NDN-FIB
+          removeFibEntryHop(pnlsr, it->getNhl(),nhit->getConnectingFace());
+          it->getNhl().resetNhl();
+          it->getNhl().addNextHop((*nhit));
+          ++startFace;
+          ++nhit;
+          for(int i=startFace; i< endFace && nhit!=nhl.end(); ++nhit, i++)
+          {
+            it->getNhl().addNextHop((*nhit));
+            //Add Entry to NDN_FIB
+          }
         }
-        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
-        }
+        it->setTimeToRefresh(fibEntryRefreshTime);
+        cancelScheduledFeExpiringEvent(pnlsr, it->getFeExpiringEventId());
+        it->setFeSeqNo(it->getFeSeqNo()+1);
+        (*it).setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                   it->getName() ,
+                                   it->getFeSeqNo(),fibEntryRefreshTime));
+      }
+      else
+      {
+        removeFromFib(pnlsr,name);
+      }
     }
+  }
 
 
 
-    void Fib::cleanFib(Nlsr& pnlsr)
+  void Fib::cleanFib(Nlsr& pnlsr)
+  {
+    for( std::list<FibEntry >::iterator it=fibTable.begin(); it != fibTable.end();
+         ++it)
     {
-        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();
-        }
+      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
+      }
     }
-
-
-    void
-    Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
+    if ( fibTable.size() > 0 )
     {
-        for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
-                it != nl.getNextHopList().end();   ++it)
-        {
-            if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
-            {
-                nl.getNextHopList().erase(it);
-            }
-        }
+      fibTable.clear();
     }
+  }
 
-
-    int
-    Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+  int
+  Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+  {
+    int endFace=0;
+    if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
     {
-        int endFace=0;
-        if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
-        {
-            return nextHopList.getNhlSize();
-        }
-        else
-        {
-            return maxFacesPerPrefix;
-        }
-        return endFace;
+      return nextHopList.getNhlSize();
     }
-
-    void
-    Fib::printFib()
+    else
     {
-        cout<<"-------------------FIB-----------------------------"<<endl;
-        for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
-                ++it)
-        {
-            cout<<(*it);
-        }
+      return maxFacesPerPrefix;
     }
+    return endFace;
+  }
+
+  void
+  Fib::removeFibEntryHop(Nlsr& pnlsr, Nhl& nl, int doNotRemoveHopFaceId)
+  {
+    for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
+         it != nl.getNextHopList().end();   ++it)
+    {
+      if ( it->getConnectingFace() != doNotRemoveHopFaceId )
+      {
+        //Remove FIB Entry from NDN-FIB
+      }
+    }
+  }
+
+  void
+  Fib::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
index d93d972..50369d4 100644
--- a/src/route/nlsr_fib.hpp
+++ b/src/route/nlsr_fib.hpp
@@ -7,42 +7,43 @@
 namespace nlsr
 {
 
-    class Nlsr;
+  class Nlsr;
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    class Fib
+  class Fib
+  {
+  public:
+    Fib()
+      : fibTable()
+      , fibEntryRefreshTime(0)
     {
-    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 removeFromFib(Nlsr& pnlsr, string name);
+    void updateFib(Nlsr& pnlsr, string name, Nhl& nextHopList);
+    void cleanFib(Nlsr& pnlsr);
+    void setFibEntryRefreshTime(int fert)
+    {
+      fibEntryRefreshTime=fert;
+    }
 
-        void printFib();
+    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:
+    void removeFibEntryHop(Nlsr& pnlsr, 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;
-    };
+  private:
+    std::list<FibEntry> fibTable;
+    int fibEntryRefreshTime;
+  };
 
 }//namespace nlsr
 #endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
index 47b02ec..19c57c1 100644
--- a/src/route/nlsr_map.cpp
+++ b/src/route/nlsr_map.cpp
@@ -10,115 +10,115 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    ostream&
-    operator<<(ostream& os, MapEntry& mpe)
-    {
-        os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
-        os<<mpe.getMappingNumber()<<" )"<<endl;
-        return os;
-    }
+  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
+  mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
+  {
+    return mpe1.getRouter()==rtrName;
+  }
 
-    static bool
-    mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
-    {
-        return mpe1.getMappingNumber()==mappingNo;
-    }
+  static bool
+  mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
+  {
+    return mpe1.getMappingNumber()==mappingNo;
+  }
 
-    void
-    Map::addMapElement(string& rtrName)
+  void
+  Map::addMapElement(string& rtrName)
+  {
+    MapEntry me(rtrName,mappingIndex);
+    if (  addMapElement(me) )
     {
-        MapEntry me(rtrName,mappingIndex);
-        if (  addMapElement(me) )
-        {
-            mappingIndex++;
-        }
+      mappingIndex++;
     }
+  }
 
-    bool
-    Map::addMapElement(MapEntry& mpe)
+  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() )
     {
-        //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;
+      rMap.push_back(mpe);
+      return true;
     }
+    return false;
+  }
 
-    string
-    Map::getRouterNameByMappingNo(int mn)
+  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() )
     {
-        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
-                                            rMap.end(),
-                                            bind(&mapEntryCompareByMappingNo, _1, mn));
-        if ( it != rMap.end() )
-        {
-            return (*it).getRouter();
-        }
-        return "";
+      return (*it).getRouter();
     }
+    return "";
+  }
 
-    int
-    Map::getMappingNoByRouterName(string& rName)
+  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() )
     {
-        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;
+      return (*it).getMappingNumber();
     }
+    return -1;
+  }
 
-    void
-    Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+  void
+  Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+  {
+    std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+    for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+         it!= adjLsdb.end() ; it++)
     {
-        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);
-            }
-        }
+      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;
-    }
+  void
+  Map::resetMap()
+  {
+    rMap.clear();
+    mappingIndex=0;
+  }
 
-    ostream&
-    operator<<(ostream& os, Map& rMap)
+  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<<"---------------Map----------------------"<<endl;
-        std::list< MapEntry > ml=rMap.getMapList();
-        for( std::list<MapEntry>::iterator it=ml.begin(); it!= ml.end() ; it++)
-        {
-            os<< (*it);
-        }
-        return os;
+      os<< (*it);
     }
+    return os;
+  }
 
 } //namespace nlsr
diff --git a/src/route/nlsr_map.hpp b/src/route/nlsr_map.hpp
index 0352d1d..c362706 100644
--- a/src/route/nlsr_map.hpp
+++ b/src/route/nlsr_map.hpp
@@ -9,80 +9,80 @@
 namespace nlsr
 {
 
-    class Nlsr;
+  class Nlsr;
 
-    using namespace std;
+  using namespace std;
 
-    class MapEntry
+  class MapEntry
+  {
+  public:
+    MapEntry()
+      : router()
+      , mappingNumber(-1)
     {
-    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
+    ~MapEntry()
     {
-    public:
-        Map()
-            : mappingIndex(0)
-        {
-        }
+    }
+
+    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;
-        }
+    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();
-        }
+    int getMapSize()
+    {
+      return rMap.size();
+    }
 
 
-    private:
-        bool addMapElement(MapEntry& mpe);
+  private:
+    bool addMapElement(MapEntry& mpe);
 
-        int mappingIndex;
-        std::list< MapEntry > rMap;
-    };
+    int mappingIndex;
+    std::list< MapEntry > rMap;
+  };
 
-    ostream&
-    operator<<(ostream& os, Map& rMap);
+  ostream&
+  operator<<(ostream& os, Map& rMap);
 
 } // namespace nlsr
 #endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
index e58b23c..1c7257b 100644
--- a/src/route/nlsr_nexthop.cpp
+++ b/src/route/nlsr_nexthop.cpp
@@ -3,11 +3,11 @@
 namespace nlsr
 {
 
-    ostream&
-    operator<<(ostream& os, NextHop& nh)
-    {
-        os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
-        return os;
-    }
+  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
index 1361d52..b8a0af0 100644
--- a/src/route/nlsr_nexthop.hpp
+++ b/src/route/nlsr_nexthop.hpp
@@ -6,50 +6,50 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class NextHop
+  class NextHop
+  {
+  public:
+    NextHop()
+      : connectingFace(0)
+      , routeCost(0)
     {
-    public:
-        NextHop()
-            : connectingFace(0)
-            , routeCost(0)
-        {
-        }
+    }
 
-        NextHop(int cf, double rc)
-        {
-            connectingFace=cf;
-            routeCost=rc;
-        }
+    NextHop(int cf, double rc)
+    {
+      connectingFace=cf;
+      routeCost=rc;
+    }
 
-        int getConnectingFace()
-        {
-            return connectingFace;
-        }
+    int getConnectingFace() const
+    {
+      return connectingFace;
+    }
 
-        void setConnectingFace(int cf)
-        {
-            connectingFace=cf;
-        }
+    void setConnectingFace(int cf)
+    {
+      connectingFace=cf;
+    }
 
-        double getRouteCost()
-        {
-            return routeCost;
-        }
+    double getRouteCost() const
+    {
+      return routeCost;
+    }
 
-        void setRouteCost(double rc)
-        {
-            routeCost=rc;
-        }
-    private:
-        int connectingFace;
-        double routeCost;
-    };
+    void setRouteCost(double rc)
+    {
+      routeCost=rc;
+    }
+  private:
+    int connectingFace;
+    double routeCost;
+  };
 
 
-    ostream&
-    operator<<(ostream& os, NextHop& nh);
+  ostream&
+  operator<<(ostream& os, NextHop& nh);
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
index 2aaa2a6..953a0b6 100644
--- a/src/route/nlsr_nhl.cpp
+++ b/src/route/nlsr_nhl.cpp
@@ -6,85 +6,85 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    static bool
-    nexthopCompare(NextHop& nh1, NextHop& nh2)
+  static bool
+  nexthopCompare(NextHop& nh1, NextHop& nh2)
+  {
+    return nh1.getConnectingFace()==nh2.getConnectingFace();
+  }
+
+  static bool
+  nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+  {
+    return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
+            nh1.getRouteCost() == nh2.getRouteCost()) ;
+  }
+
+  static bool
+  nextHopSortingComparator(const NextHop& nh1, const NextHop& nh2)
+  {
+    return nh1.getRouteCost() < nh2.getRouteCost();
+  }
+
+  /**
+  Add next hop to the Next Hop list
+  If next hop is new it is added
+  If next hop already exists in next
+  hop list then updates the route
+  cost with new next hop's route cost
+  */
+
+  void
+  Nhl::addNextHop(NextHop& nh)
+  {
+    std::list<NextHop >::iterator it = std::find_if( nexthopList.begin(),
+                                       nexthopList.end(),
+                                       bind(&nexthopCompare, _1, nh));
+    if ( it == nexthopList.end() )
     {
-        return nh1.getConnectingFace()==nh2.getConnectingFace();
+      nexthopList.push_back(nh);
     }
-
-    static bool
-    nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+    if ( (*it).getRouteCost() > nh.getRouteCost() )
     {
-        return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
-                nh1.getRouteCost() == nh2.getRouteCost()) ;
+      (*it).setRouteCost(nh.getRouteCost());
     }
+  }
 
-    static bool
-    nextHopSortingComparator(NextHop& nh1, NextHop& nh2)
+  /**
+  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() )
     {
-        return nh1.getRouteCost() < nh2.getRouteCost();
+      nexthopList.erase(it);
     }
+  }
 
-    /**
-    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::sortNhl()
+  {
+    nexthopList.sort(nextHopSortingComparator);
+  }
 
-    void
-    Nhl::addNextHop(NextHop& nh)
+  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++)
     {
-        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());
-        }
+      os << "Nexthop "<<i<<": "<<(*it)<<endl;
     }
-
-    /**
-    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;
-    }
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_nhl.hpp b/src/route/nlsr_nhl.hpp
index 9f6bd76..f82d37e 100644
--- a/src/route/nlsr_nhl.hpp
+++ b/src/route/nlsr_nhl.hpp
@@ -11,43 +11,44 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Nhl
+  class Nhl
+  {
+  public:
+    Nhl()
+      : nexthopList()
     {
-    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;
-        }
+    ~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;
-    };
+  private:
+    std::list< NextHop > nexthopList;
+  };
 
-    ostream&
-    operator<<(ostream& os, Nhl& nhl);
+  ostream&
+  operator<<(ostream& os, Nhl& nhl);
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
index 9c4d4cb..2dfa311 100644
--- a/src/route/nlsr_npt.cpp
+++ b/src/route/nlsr_npt.cpp
@@ -9,134 +9,141 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    static bool
-    npteCompare(Npte& npte, string& name)
+  static bool
+  npteCompare(Npte& npte, string& name)
+  {
+    return npte.getNamePrefix()==name;
+  }
+
+
+
+  void
+  Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+  {
+    std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+                                    npteList.end(), bind(&npteCompare, _1, name));
+    if ( it == npteList.end() )
     {
-        return npte.getNamePrefix()==name;
+      Npte newEntry(name);
+      newEntry.addRoutingTableEntry(rte);
+      newEntry.generateNhlfromRteList();
+      newEntry.getNhl().sortNhl();
+      npteList.push_back(newEntry);
+      if(rte.getNhl().getNhlSize()> 0)
+      {
+        pnlsr.getFib().updateFib(pnlsr, name,newEntry.getNhl());
+      }
     }
-
-// Following two methods will update FIB with response to change in NPT
-
-    void
-    Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    else
     {
-        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());
-        }
+      if ( rte.getNhl().getNhlSize()> 0 )
+      {
+        (*it).addRoutingTableEntry(rte);
+        (*it).generateNhlfromRteList();
+        (*it).getNhl().sortNhl();
+        pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl());
+      }
+      else
+      {
+        (*it).resetRteListNextHop();
+        (*it).getNhl().resetNhl();
+        pnlsr.getFib().removeFromFib(pnlsr,name);
+      }
     }
+  }
 
-    void
-    Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+  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() )
     {
-        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());
-            }
-        }
+      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);
+        pnlsr.getFib().removeFromFib(pnlsr,name);
+      }
+      else
+      {
+        (*it).generateNhlfromRteList();
+        pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl());
+      }
     }
+  }
 
 
-    void
-    Npt::addNpte(string name, string destRouter, Nlsr& pnlsr)
+  void
+  Npt::addNpteByDestName(string name, string destRouter, Nlsr& pnlsr)
+  {
+    std::pair<RoutingTableEntry& , bool> rteCheck=
+      pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+    if(rteCheck.second)
     {
+      addNpte(name,rteCheck.first,pnlsr);
+    }
+    else
+    {
+      RoutingTableEntry rte(destRouter);
+      addNpte(name, rte,pnlsr);
+    }
+  }
+
+  void
+  Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
+  {
+    std::pair<RoutingTableEntry& , bool> rteCheck=
+      pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+    if(rteCheck.second)
+    {
+      removeNpte(name,rteCheck.first,pnlsr);
+    }
+    else
+    {
+      RoutingTableEntry rte(destRouter);
+      removeNpte(name, rte,pnlsr);
+    }
+  }
+
+  void
+  Npt::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(destRouter);
+          pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
         if(rteCheck.second)
         {
-            addNpte(name,rteCheck.first,pnlsr);
+          addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
         }
         else
         {
-            RoutingTableEntry rte(destRouter);
-            addNpte(name, rte,pnlsr);
+          RoutingTableEntry rte((*rteit).getDestination());
+          addNpte((*it).getNamePrefix(), rte,pnlsr);
         }
+      }
     }
+  }
 
-    void
-    Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
+  void
+  Npt::printNpt()
+  {
+    cout<<"----------------NPT----------------------"<<endl;
+    for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
     {
-        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);
-        }
+      cout <<(*it)<<endl;
     }
-
-    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
index f4ddbf9..8e6a98c 100644
--- a/src/route/nlsr_npt.hpp
+++ b/src/route/nlsr_npt.hpp
@@ -8,26 +8,26 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Nlsr;
+  class Nlsr;
 
-    class Npt
+  class Npt
+  {
+  public:
+    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;
-    };
+    }
+    void addNpteByDestName(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
 
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
index 60013ff..c342a21 100644
--- a/src/route/nlsr_npte.cpp
+++ b/src/route/nlsr_npte.cpp
@@ -7,77 +7,77 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    Npte::generateNhlfromRteList()
+  void
+  Npte::generateNhlfromRteList()
+  {
+    nhl.resetNhl();
+    for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+         it != rteList.end(); ++it )
     {
-        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));
-            }
-        }
+      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)
+  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() )
     {
-        return rte.getDestination()==destRouter;
+      rteList.erase(it);
     }
+  }
 
-    void
-    Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
+  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() )
     {
-        std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
-                rteList.end(),
-                bind(&rteCompare, _1, rte.getDestination()));
-        if ( it != rteList.end() )
-        {
-            rteList.erase(it);
-        }
+      rteList.push_back(rte);
     }
-
-    void
-    Npte::addRoutingTableEntry(RoutingTableEntry &rte)
+    else
     {
-        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));
-            }
-        }
+      (*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)
+  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)
     {
-        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;
+      cout<<(*it);
     }
+    os<<npte.getNhl();
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_npte.hpp b/src/route/nlsr_npte.hpp
index e64328c..3dfa04a 100644
--- a/src/route/nlsr_npte.hpp
+++ b/src/route/nlsr_npte.hpp
@@ -8,53 +8,65 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Npte
+  class Npte
+  {
+  public:
+    Npte()
+      : namePrefix()
+      , nhl()
     {
-    public:
-        Npte()
-            : namePrefix()
-            , nhl()
-        {
-        }
-        Npte(string np)
-            : nhl()
-        {
-            namePrefix=np;
-        }
+    }
+    Npte(string np)
+      : nhl()
+    {
+      namePrefix=np;
+    }
 
-        string getNamePrefix()
+    string getNamePrefix()
+    {
+      return namePrefix;
+    }
+
+    std::list<RoutingTableEntry>& getRteList()
+    {
+      return rteList;
+    }
+
+    void resetRteListNextHop()
+    {
+      if (rteList.size() > 0 )
+      {
+        for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+             it != rteList.end(); ++it )
         {
-            return namePrefix;
+          (*it).getNhl().resetNhl();
         }
+      }
+    }
 
-        std::list<RoutingTableEntry>& getRteList()
-        {
-            return rteList;
-        }
+    int getRteListSize()
+    {
+      return rteList.size();
+    }
 
-        int getRteListSize()
-        {
-            return rteList.size();
-        }
+    Nhl& getNhl()
+    {
+      return nhl;
+    }
+    void generateNhlfromRteList();
+    void removeRoutingTableEntry(RoutingTableEntry& rte);
+    void addRoutingTableEntry(RoutingTableEntry &rte);
 
-        Nhl& getNhl()
-        {
-            return nhl;
-        }
-        void generateNhlfromRteList();
-        void removeRoutingTableEntry(RoutingTableEntry& rte);
-        void addRoutingTableEntry(RoutingTableEntry &rte);
+  private:
+    string namePrefix;
+    std::list<RoutingTableEntry> rteList;
+    Nhl nhl;
+  };
 
-    private:
-        string namePrefix;
-        std::list<RoutingTableEntry> rteList;
-        Nhl nhl;
-    };
-
-    ostream&
-    operator<<(ostream& os, Npte& npte);
+  ostream&
+  operator<<(ostream& os, Npte& npte);
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
index cc60650..2cd9b28 100644
--- a/src/route/nlsr_rt.cpp
+++ b/src/route/nlsr_rt.cpp
@@ -12,221 +12,222 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    RoutingTable::calculate(Nlsr& pnlsr)
+  void
+  RoutingTable::calculate(Nlsr& pnlsr)
+  {
+    //debugging purpose
+    std::cout<<pnlsr.getConfParameter()<<std::endl;
+    pnlsr.getNpt().printNpt();
+    pnlsr.getLsdb().printAdjLsdb();
+    pnlsr.getLsdb().printCorLsdb();
+    pnlsr.getLsdb().printNameLsdb();
+    if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
     {
-        //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)
         {
-            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
-                std::cout<<"Calling Update NPT With new Route"<<std::endl;
-                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
+          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
         {
-            scheduleRoutingTableCalculation(pnlsr);
+          cout<<"Adjacency building is scheduled, so ";
+          cout<<"routing table can not be calculated :("<<endl;
         }
+      }
+      else
+      {
+        cout<<"No Adj LSA of router itself,";
+        cout<<	" so Routing table can not be calculated :("<<endl;
+        clearRoutingTable();
+        clearDryRoutingTable(); // for dry run options
+        // need to update NPT here
+        std::cout<<"Calling Update NPT With new Route"<<std::endl;
+        pnlsr.getNpt().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
     }
-
-
-    void
-    RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
+    else
     {
-        cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
-        Map vMap;
-        vMap.createMapFromAdjLsdb(pnlsr);
-        int numOfRouter=vMap.getMapSize();
-        LinkStateRoutingTableCalculator lsrtc(numOfRouter);
-        lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+      scheduleRoutingTableCalculation(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::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::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);
-        }
-    }
+  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);
+  }
 
-    static bool
-    routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter)
+  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 )
     {
-        return rte.getDestination()==destRouter;
+      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)
+  void
+  RoutingTable::addNextHop(string destRouter, NextHop& nh)
+  {
+    std::pair<RoutingTableEntry&, bool> rte=findRoutingTableEntry(destRouter);
+    if( !rte.second )
     {
-        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);
-        }
+      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::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() )
     {
-        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);
+      return std::make_pair(boost::ref((*it)),true);
     }
+    RoutingTableEntry rteEmpty;
+    return std::make_pair(boost::ref(rteEmpty),false);
+  }
 
-    void
-    RoutingTable::printRoutingTable()
+  void
+  RoutingTable::printRoutingTable()
+  {
+    cout<<"---------------Routing Table------------------"<<endl;
+    for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
+        it != rTable.end(); ++it)
     {
-        cout<<"---------------Routing Table------------------"<<endl;
-        for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
-                it != rTable.end(); ++it)
-        {
-            cout<<(*it)<<endl;
-        }
+      cout<<(*it)<<endl;
     }
+  }
 
 
 //function related to manipulation of dry routing table
-    void
-    RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
+  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() )
     {
-        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);
-        }
+      RoutingTableEntry rte(destRouter);
+      rte.getNhl().addNextHop(nh);
+      dryTable.push_back(rte);
     }
+    else
+    {
+      (*it).getNhl().addNextHop(nh);
+    }
+  }
 
-    void
-    RoutingTable::printDryRoutingTable()
+  void
+  RoutingTable::printDryRoutingTable()
+  {
+    cout<<"--------Dry Run's Routing Table--------------"<<endl;
+    for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
+        it != dryTable.end(); ++it)
     {
-        cout<<"--------Dry Run's Routing Table--------------"<<endl;
-        for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
-                it != dryTable.end(); ++it)
-        {
-            cout<<(*it)<<endl;
-        }
+      cout<<(*it)<<endl;
     }
+  }
 
 
-    void
-    RoutingTable::clearRoutingTable()
+  void
+  RoutingTable::clearRoutingTable()
+  {
+    if( rTable.size() > 0 )
     {
-        if( rTable.size() > 0 )
-        {
-            rTable.clear();
-        }
+      rTable.clear();
     }
+  }
 
-    void
-    RoutingTable::clearDryRoutingTable()
+  void
+  RoutingTable::clearDryRoutingTable()
+  {
+    if (dryTable.size()>0 )
     {
-        if (dryTable.size()>0 )
-        {
-            dryTable.clear();
-        }
+      dryTable.clear();
     }
+  }
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
index fb9a060..bf4e489 100644
--- a/src/route/nlsr_rt.hpp
+++ b/src/route/nlsr_rt.hpp
@@ -10,40 +10,40 @@
 namespace nlsr
 {
 
-    class Nlsr;
-    class NextHop;
+  class Nlsr;
+  class NextHop;
 
-    using namespace std;
+  using namespace std;
 
-    class RoutingTable
+  class RoutingTable
+  {
+  public:
+    RoutingTable()
+      : NO_NEXT_HOP(-12345)
     {
-    public:
-        RoutingTable()
-            : NO_NEXT_HOP(-12345)
-        {
-        }
-        void calculate(Nlsr& pnlsr);
-        void addNextHop(string destRouter, NextHop& nh);
-        void printRoutingTable();
+    }
+    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);
+    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);
+  private:
+    void calculateLsRoutingTable(Nlsr& pnlsr);
+    void calculateHypRoutingTable(Nlsr& pnlsr);
+    void calculateHypDryRoutingTable(Nlsr&pnlsr);
 
-        void clearRoutingTable();
-        void clearDryRoutingTable();
+    void clearRoutingTable();
+    void clearDryRoutingTable();
 
-        const int NO_NEXT_HOP;
+    const int NO_NEXT_HOP;
 
-        std::list< RoutingTableEntry > rTable;
-        std::list< RoutingTableEntry > dryTable;
-    };
+    std::list< RoutingTableEntry > rTable;
+    std::list< RoutingTableEntry > dryTable;
+  };
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
index acdf6d5..90200e5 100644
--- a/src/route/nlsr_rtc.cpp
+++ b/src/route/nlsr_rtc.cpp
@@ -10,495 +10,499 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    RoutingTableCalculator::allocateAdjMatrix()
+  void
+  RoutingTableCalculator::allocateAdjMatrix()
+  {
+    adjMatrix = new double*[numOfRouter];
+    for(int i = 0; i < numOfRouter; ++i)
     {
-        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[i] = new double[numOfRouter];
+          adjMatrix[row][col]=cost;
         }
+      }
     }
+  }
 
-    void
-    RoutingTableCalculator::initMatrix()
+  void
+  RoutingTableCalculator::printAdjMatrix()
+  {
+    for(int i=0; i<numOfRouter; i++)
     {
-        for(int i=0; i<numOfRouter; i++)
-        {
-            for(int j=0; j<numOfRouter; j++)
-                adjMatrix[i][j]=0;
-        }
+      for(int j=0; j<numOfRouter; j++)
+        printf("%f ",adjMatrix[i][j]);
+      printf("\n");
     }
+  }
 
-    void
-    RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
+  void
+  RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+  {
+    for ( int i = 0; i < numOfRouter; i++ )
     {
-        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;
-                }
-            }
-        }
+      if ( i == link )
+      {
+        adjMatrix[source][i]=linkCost;
+      }
+      else
+      {
+        adjMatrix[source][i]=0;
+      }
     }
+  }
 
-    void
-    RoutingTableCalculator::printAdjMatrix()
+  int
+  RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+  {
+    int noLink=0;
+    for(int i=0; i<numOfRouter; i++)
     {
-        for(int i=0; i<numOfRouter; i++)
-        {
-            for(int j=0; j<numOfRouter; j++)
-                printf("%f ",adjMatrix[i][j]);
-            printf("\n");
-        }
+      if ( adjMatrix[sRouter][i] > 0 )
+      {
+        noLink++;
+      }
     }
+    return noLink;
+  }
 
-    void
-    RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+  void
+  RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
+      double *linkCosts, int source)
+  {
+    int j=0;
+    for (int i=0; i <numOfRouter; i++)
     {
-        for ( int i = 0; i < numOfRouter; i++ )
-        {
-            if ( i == link )
-            {
-                adjMatrix[source][i]=linkCost;
-            }
-            else
-            {
-                adjMatrix[source][i]=0;
-            }
-        }
+      if ( adjMatrix[source][i] > 0 )
+      {
+        links[j]=i;
+        linkCosts[j]=adjMatrix[source][i];
+        j++;
+      }
     }
+  }
 
-    int
-    RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+  void
+  RoutingTableCalculator::freeAdjMatrix()
+  {
+    for(int i = 0; i < numOfRouter; ++i)
     {
-        int noLink=0;
-        for(int i=0; i<numOfRouter; i++)
-        {
-            if ( adjMatrix[sRouter][i] > 0 )
-            {
-                noLink++;
-            }
-        }
-        return noLink;
+      delete [] adjMatrix[i];
     }
+    delete [] adjMatrix;
+  }
 
-    void
-    RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
-            double *linkCosts, int source)
+
+  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 )
     {
-        int j=0;
-        for (int i=0; i <numOfRouter; i++)
-        {
-            if ( adjMatrix[source][i] > 0 )
-            {
-                links[j]=i;
-                linkCosts[j]=adjMatrix[source][i];
-                j++;
-            }
-        }
+      // Single Path
+      doDijkstraPathCalculation(sourceRouter);
+      // print all ls path -- debugging purpose
+      printAllLsPath(sourceRouter);
+      // update routing table
+      addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
     }
-
-    void
-    RoutingTableCalculator::freeAdjMatrix()
+    else
     {
-        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;
+      // 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();
-        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();
+        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)
+  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++)
     {
-        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;
+      parent[i]=EMPTY_PARENT;
+      distance[i]=INF_DISTANCE;
+      Q[i]=i;
     }
-
-    void
-    LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
-            RoutingTable& rt, Map& pMap, int sourceRouter)
+    if ( sourceRouter != NO_MAPPING_NUM )
     {
-        cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
+      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);
+        if ( nextHopRouter != NO_NEXT_HOP )
+        {
+          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;
-        for(int i=0; i < numOfRouter ; i++)
+      }
+    }
+  }
+
+  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]])
         {
-            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 tempU=Q[j];
+          Q[j]=Q[i];
+          Q[i]=tempU;
         }
+      }
     }
+  }
 
-    int
-    LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+  int
+  LinkStateRoutingTableCalculator::isNotExplored(int *Q,
+      int u,int start, int element)
+  {
+    int ret=0;
+    for(int i=start; i< element; i++)
     {
-        int nextHop;
-        while ( parent[dest] != EMPTY_PARENT )
+      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++)
         {
-            nextHop=dest;
-            dest=parent[dest];
+          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++;
+          }
         }
-        if ( dest != source )
-        {
-            nextHop=NO_NEXT_HOP;
-        }
-        return nextHop;
+        addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
+        freeLinkFaces();
+        freeDistanceToNeighbor();
+        freeDistFromNbrToDest();
+      }
     }
+    freeLinks();
+    freeLinksCosts();
+    freeAdjMatrix();
+  }
 
-    void
-    LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
+  void
+  HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+      RoutingTable& rt, int noFaces, int dest)
+  {
+    for(int i=0 ; i < noFaces ; ++i)
     {
-        cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
-        cout<<"Source Router: "<<sourceRouter<<endl;
-        for(int i=0; i < numOfRouter ; i++)
-        {
-            if ( i!= sourceRouter )
-            {
-                printLsPath(i);
-                cout<<endl;
-            }
-        }
+      string destRouter=pMap.getRouterNameByMappingNo(dest);
+      NextHop nh(linkFaces[i],distFromNbrToDest[i]);
+      rt.addNextHop(destRouter,nh);
+      if( isDryRun == 1 )
+      {
+        rt.addNextHopToDryTable(destRouter,nh);
+      }
     }
+  }
 
-    void
-    LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+  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)
     {
-        if (parent[destRouter] != EMPTY_PARENT )
-        {
-            printLsPath(parent[destRouter]);
-        }
-        cout<<" "<<destRouter;
+      diffTheta = 2 * MATH_PI - diffTheta;
     }
-
-    void
-    LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
-            double *dist,int start,int element)
+    if ( srcRadius != -1 && destRadius != -1 )
     {
-        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;
-                }
-            }
-        }
+      if (diffTheta == 0)
+        distance = fabs (srcRadius - destRadius);
+      else
+        distance = acosh((cosh(srcRadius)*cosh(destRadius))-
+                         (sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
     }
-
-    int
-    LinkStateRoutingTableCalculator::isNotExplored(int *Q,
-            int u,int start, int element)
+    else
     {
-        int ret=0;
-        for(int i=start; i< element; i++)
-        {
-            if ( Q[i] == u )
-            {
-                ret=1;
-                break;
-            }
-        }
-        return ret;
+      distance = -1;
     }
+    return distance;
+  }
 
-    void
-    LinkStateRoutingTableCalculator::allocateParent()
-    {
-        parent=new int[numOfRouter];
-    }
+  void
+  HypRoutingTableCalculator::allocateLinkFaces()
+  {
+    linkFaces=new int[vNoLink];
+  }
 
-    void
-    LinkStateRoutingTableCalculator::allocateDistance()
-    {
-        distance= new double[numOfRouter];
-    }
+  void
+  HypRoutingTableCalculator::allocateDistanceToNeighbor()
+  {
+    distanceToNeighbor=new double[vNoLink];
+  }
 
-    void
-    LinkStateRoutingTableCalculator::freeParent()
-    {
-        delete [] parent;
-    }
+  void
+  HypRoutingTableCalculator::allocateDistFromNbrToDest()
+  {
+    distFromNbrToDest=new double[vNoLink];
+  }
 
-    void LinkStateRoutingTableCalculator::freeDistance()
-    {
-        delete [] distance;
-    }
+  void
+  HypRoutingTableCalculator::freeLinkFaces()
+  {
+    delete [] linkFaces;
+  }
 
+  void
+  HypRoutingTableCalculator::freeDistanceToNeighbor()
+  {
+    delete [] distanceToNeighbor;
+  }
 
-
-    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;
-    }
+  void
+  HypRoutingTableCalculator::freeDistFromNbrToDest()
+  {
+    delete [] distFromNbrToDest;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
index 987686e..730612c 100644
--- a/src/route/nlsr_rtc.hpp
+++ b/src/route/nlsr_rtc.hpp
@@ -7,138 +7,138 @@
 namespace nlsr
 {
 
-    class Map;
-    class RoutingTable;
-    class Nlsr;
+  class Map;
+  class RoutingTable;
+  class Nlsr;
 
 
-    using namespace std;
+  using namespace std;
 
-    class RoutingTableCalculator
+  class RoutingTableCalculator
+  {
+  public:
+    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
+    }
+    RoutingTableCalculator(int rn)
     {
-    public:
-        LinkStateRoutingTableCalculator(int rn)
-            : EMPTY_PARENT(-12345)
-            , INF_DISTANCE(2147483647)
-            , NO_MAPPING_NUM(-1)
-            , NO_NEXT_HOP(-12345)
-        {
-            numOfRouter=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 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
+    void setNoLink(int nl)
     {
-    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;
-        }
+      vNoLink=nl;
+    }
 
-        void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+  protected:
+    double ** adjMatrix;
+    int numOfRouter;
 
-    private:
-        void allocateLinkFaces();
-        void allocateDistanceToNeighbor();
-        void allocateDistFromNbrToDest();
-        void freeLinkFaces();
-        void freeDistanceToNeighbor();
-        void freeDistFromNbrToDest();
+    int vNoLink;
+    int *links;
+    double *linkCosts;
+  };
 
-        double getHyperbolicDistance(Nlsr& pnlsr,Map& pMap, int src, int dest);
-        void addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
-                                          RoutingTable& rt, int noFaces,int dest);
+  class LinkStateRoutingTableCalculator: public RoutingTableCalculator
+  {
+  public:
+    LinkStateRoutingTableCalculator(int rn)
+      : EMPTY_PARENT(-12345)
+      , INF_DISTANCE(2147483647)
+      , NO_MAPPING_NUM(-1)
+      , NO_NEXT_HOP(-12345)
+    {
+      numOfRouter=rn;
+    }
 
-    private:
-        int isDryRun;
 
-        int *linkFaces;
-        double *distanceToNeighbor;
-        double *distFromNbrToDest;
+    void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
 
-        const double MATH_PI;
 
-    };
+  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
 
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
index f96da11..129ab8a 100644
--- a/src/route/nlsr_rte.cpp
+++ b/src/route/nlsr_rte.cpp
@@ -6,21 +6,21 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    ostream&
-    operator<<(ostream& os, RoutingTableEntry &rte)
+  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<<"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;
+      os <<"  Nexthop "<<i<<": "<<(*it)<<endl;
     }
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
index 27d3601..736909b 100644
--- a/src/route/nlsr_rte.hpp
+++ b/src/route/nlsr_rte.hpp
@@ -8,44 +8,44 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class RoutingTableEntry
+  class RoutingTableEntry
+  {
+  public:
+    RoutingTableEntry()
+      : destination()
+      , nhl()
     {
-    public:
-        RoutingTableEntry()
-            : destination()
-            , nhl()
-        {
-        }
+    }
 
-        ~RoutingTableEntry()
-        {
-        }
+    ~RoutingTableEntry()
+    {
+    }
 
-        RoutingTableEntry(string dest)
-            : nhl()
-        {
-            destination=dest;
-        }
+    RoutingTableEntry(string dest)
+      : nhl()
+    {
+      destination=dest;
+    }
 
-        string getDestination()
-        {
-            return destination;
-        }
+    string getDestination()
+    {
+      return destination;
+    }
 
-        Nhl& getNhl()
-        {
-            return nhl;
-        }
+    Nhl& getNhl()
+    {
+      return nhl;
+    }
 
-    private:
-        string destination;
-        Nhl nhl;
-    };
+  private:
+    string destination;
+    Nhl nhl;
+  };
 
-    ostream&
-    operator<<(ostream& os, RoutingTableEntry &rte);
+  ostream&
+  operator<<(ostream& os, RoutingTableEntry &rte);
 
 }
 
diff --git a/src/security/nlsr_cert_store.cpp b/src/security/nlsr_cert_store.cpp
index 108d0c6..d1e821a 100644
--- a/src/security/nlsr_cert_store.cpp
+++ b/src/security/nlsr_cert_store.cpp
@@ -2,138 +2,129 @@
 
 namespace nlsr
 {
-    static bool
-    nlsrCertificateStoreEntryCompare(NlsrCertificateStoreEntry& ncse1,
-                                               NlsrCertificateStoreEntry& ncse2)
-    
+  static bool
+  nlsrCertificateStoreEntryCompare(NlsrCertificateStoreEntry& ncse1,
+                                   NlsrCertificateStoreEntry& ncse2)
+
+  {
+    return ncse1.getCert()->getName().toUri() ==
+           ncse2.getCert()->getName().toUri() ;
+  }
+
+  static bool
+  nlsrCertificateStoreEntryCompareByName(NlsrCertificateStoreEntry& ncse1,
+                                         std::string compCertName)
+
+  {
+    ndn::Name ccn(compCertName);
+    return ( ncse1.getCert()->getName().toUri() == compCertName ||
+             ccn.isPrefixOf(ncse1.getCert()->getName()) );
+  }
+
+  bool
+  NlsrCertificateStore::addCertificate(NlsrCertificateStoreEntry & ncse)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompare, _1, ncse));
+    if(it == certTable.end())
     {
-        return ncse1.getCert()->getName().toUri() == 
-                                          ncse2.getCert()->getName().toUri() ;
+      certTable.push_back(ncse);
+      return true;
     }
-    
-    static bool
-    nlsrCertificateStoreEntryCompareByName(NlsrCertificateStoreEntry& ncse1,
-                                               std::string compCertName)
-    
+    if( it !=  certTable.end() )
     {
-        return ncse1.getCert()->getName().toUri() == compCertName ;
-    }
-    
-    bool
-    NlsrCertificateStore::addCertificate(NlsrCertificateStoreEntry & ncse)
-    {
-        std::list<NlsrCertificateStoreEntry>::iterator it = 
-                               std::find_if( certTable.begin(), certTable.end(),
-                             bind(&nlsrCertificateStoreEntryCompare, _1, ncse));
-        if(it == certTable.end())
-        {
-            certTable.push_back(ncse);
-            return true;
-        }
-        
-        if( it !=  certTable.end() )
-        {
-            if ( (*it).getCertSeqNum() < ncse.getCertSeqNum() )
-            {
-                certTable.erase(it);
-                certTable.push_back(ncse);
-                return true;
-            }
-        }
-        
-        return false;
-    }
-    
-    bool
-    NlsrCertificateStore::addCertificate(
-        ndn::shared_ptr<ndn::IdentityCertificate> pcert, uint32_t csn, bool isv)
-    {
-        NlsrCertificateStoreEntry ncse(pcert, csn, isv);
-        return addCertificate(ncse);
-    }
-    
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    NlsrCertificateStore::getCertificateFromStore(const std::string certName)
-    {
-        std::list<NlsrCertificateStoreEntry>::iterator it = 
-                               std::find_if( certTable.begin(), certTable.end(),
-                   bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-        if(it == certTable.end())
-        {
-            ndn::shared_ptr<ndn::IdentityCertificate> cert=
-                                   ndn::make_shared<ndn::IdentityCertificate>();
-                                   
-            return std::make_pair(cert,false);
-        }
-        
-        return std::make_pair((*it).getCert(),true);
-    }
-    
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    NlsrCertificateStore::getCertificateFromStore(
-                                    const std::string certName, int checkSeqNum)
-    {
-        std::list<NlsrCertificateStoreEntry>::iterator it = 
-                               std::find_if( certTable.begin(), certTable.end(),
-                   bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-        if(it == certTable.end())
-        {
-            ndn::shared_ptr<ndn::IdentityCertificate> cert=
-                                   ndn::make_shared<ndn::IdentityCertificate>();
-                                   
-            return std::make_pair(cert,false);
-        }
-        else
-        {
-            if( (*it).getCertSeqNum() == checkSeqNum )
-            {
-                return std::make_pair((*it).getCert(),true);
-            }
-        }
-           
-        return std::make_pair((*it).getCert(),false);
-        
-    }
-    
-    bool 
-    NlsrCertificateStore::isCertificateNewInStore(const std::string certName,
-                                                            int checkSeqNo)
-    {
-        std::list<NlsrCertificateStoreEntry>::iterator it = 
-                               std::find_if( certTable.begin(), certTable.end(),
-                   bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-        if(it != certTable.end())
-        {
-            return (*it).getCertSeqNum() < checkSeqNo ;
-        }
-        
+      if ( (*it).getCertSeqNum() < ncse.getCertSeqNum() )
+      {
+        certTable.erase(it);
+        certTable.push_back(ncse);
         return true;
-        
+      }
     }
-    
-    bool
-    NlsrCertificateStore::removeCertificateFromStroe(const std::string certName)
+    return false;
+  }
+
+  bool
+  NlsrCertificateStore::addCertificate(
+    ndn::shared_ptr<ndn::IdentityCertificate> pcert, uint32_t csn, bool isv)
+  {
+    NlsrCertificateStoreEntry ncse(pcert, csn, isv);
+    return addCertificate(ncse);
+  }
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  NlsrCertificateStore::getCertificateFromStore(const std::string certName)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it == certTable.end())
     {
-        std::list<NlsrCertificateStoreEntry>::iterator it = 
-                               std::find_if( certTable.begin(), certTable.end(),
-                   bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
-        if(it != certTable.end())
-        {
-            certTable.erase(it);
-            return true;
-        }
-        
-        return false;
+      ndn::shared_ptr<ndn::IdentityCertificate> cert=
+        ndn::make_shared<ndn::IdentityCertificate>();
+      return std::make_pair(cert,false);
     }
-    
-    void 
-    NlsrCertificateStore::printCertStore()
+    return std::make_pair((*it).getCert(),true);
+  }
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  NlsrCertificateStore::getCertificateFromStore(
+    const std::string certName, int checkSeqNum)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it == certTable.end())
     {
-        std::list<NlsrCertificateStoreEntry>::iterator it;
-        for(it=certTable.begin(); it!=certTable.end(); ++it)
-        {
-            std::cout<<(*it)<<std::endl;
-        }
-        
+      ndn::shared_ptr<ndn::IdentityCertificate> cert=
+        ndn::make_shared<ndn::IdentityCertificate>();
+      return std::make_pair(cert,false);
     }
+    else
+    {
+      if( (*it).getCertSeqNum() == checkSeqNum )
+      {
+        return std::make_pair((*it).getCert(),true);
+      }
+    }
+    return std::make_pair((*it).getCert(),false);
+  }
+
+  bool
+  NlsrCertificateStore::isCertificateNewInStore(const std::string certName,
+      int checkSeqNo)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it != certTable.end())
+    {
+      return (*it).getCertSeqNum() < checkSeqNo ;
+    }
+    return true;
+  }
+
+  bool
+  NlsrCertificateStore::removeCertificateFromStroe(const std::string certName)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it != certTable.end())
+    {
+      certTable.erase(it);
+      return true;
+    }
+    return false;
+  }
+
+  void
+  NlsrCertificateStore::printCertStore()
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it;
+    for(it=certTable.begin(); it!=certTable.end(); ++it)
+    {
+      std::cout<<(*it)<<std::endl;
+    }
+  }
 }
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
index 9bd7ca8..5c9cabb 100644
--- a/src/security/nlsr_cert_store.hpp
+++ b/src/security/nlsr_cert_store.hpp
@@ -7,25 +7,25 @@
 
 namespace nlsr
 {
-    class NlsrCertificateStore
-    {
-        public:
-            NlsrCertificateStore()
-            {}
-            
-            bool addCertificate(NlsrCertificateStoreEntry & ncse);
-            bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                                                      , uint32_t csn, bool isv);
-            std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-            getCertificateFromStore(const std::string certName);
-            std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-            getCertificateFromStore(const std::string certName, int checkSeqNum);
-            bool removeCertificateFromStroe(const std::string certName);
-            bool isCertificateNewInStore(const std::string certName, int checkSeqNo);
-            void printCertStore();
-        private:
-            std::list<NlsrCertificateStoreEntry> certTable;
-    };
+  class NlsrCertificateStore
+  {
+  public:
+    NlsrCertificateStore()
+    {}
+
+    bool addCertificate(NlsrCertificateStoreEntry & ncse);
+    bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                        , uint32_t csn, bool isv);
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+    getCertificateFromStore(const std::string certName);
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+    getCertificateFromStore(const std::string certName, int checkSeqNum);
+    bool removeCertificateFromStroe(const std::string certName);
+    bool isCertificateNewInStore(const std::string certName, int checkSeqNo);
+    void printCertStore();
+  private:
+    std::list<NlsrCertificateStoreEntry> certTable;
+  };
 }
 
 #endif
diff --git a/src/security/nlsr_cse.cpp b/src/security/nlsr_cse.cpp
index f52fdc9..f2f5f06 100644
--- a/src/security/nlsr_cse.cpp
+++ b/src/security/nlsr_cse.cpp
@@ -3,16 +3,16 @@
 
 namespace nlsr
 {
-    std::ostream&
-    operator <<(std::ostream& os, const NlsrCertificateStoreEntry& ncse)
-    {
-        os<<"------Certificate Entry---------------"<<std::endl;
-        os<<*(ncse.getCert())<<std::endl;
-        ndn::SignatureSha256WithRsa sig(ncse.getCert()->getSignature());
-        ndn::Name keyName=sig.getKeyLocator().getName();
-        os<<"Signee : "<<keyName.toUri()<<std::endl;
-        os<<"Cert Seq Num: "<<ncse.getCertSeqNum()<<std::endl;
-        os<<"Is Signer Verified: "<<ncse.getIsSignerVerified()<<std::endl;
-        return os;
-    }
+  std::ostream&
+  operator <<(std::ostream& os, const NlsrCertificateStoreEntry& ncse)
+  {
+    os<<"------Certificate Entry---------------"<<std::endl;
+    os<<*(ncse.getCert())<<std::endl;
+    ndn::SignatureSha256WithRsa sig(ncse.getCert()->getSignature());
+    ndn::Name keyName=sig.getKeyLocator().getName();
+    os<<"Signee : "<<keyName.toUri()<<std::endl;
+    os<<"Cert Seq Num: "<<ncse.getCertSeqNum()<<std::endl;
+    os<<"Is Signer Verified: "<<ncse.getIsSignerVerified()<<std::endl;
+    return os;
+  }
 }
diff --git a/src/security/nlsr_cse.hpp b/src/security/nlsr_cse.hpp
index 27b992a..f91e9e2 100644
--- a/src/security/nlsr_cse.hpp
+++ b/src/security/nlsr_cse.hpp
@@ -7,60 +7,60 @@
 
 namespace nlsr
 {
-    class NlsrCertificateStoreEntry
+  class NlsrCertificateStoreEntry
+  {
+  public:
+    NlsrCertificateStoreEntry()
+      : cert(ndn::make_shared<ndn::IdentityCertificate>())
+      , certSeqNum(0)
+      , isSignerVerified(false)
+    {}
+
+    NlsrCertificateStoreEntry(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                              , uint32_t csn, bool isv)
+      : cert(pcert)
+      , certSeqNum(csn)
+      , isSignerVerified(isv)
+    {}
+
+    ndn::shared_ptr<ndn::IdentityCertificate> getCert() const
     {
-      public:
-        NlsrCertificateStoreEntry()
-            : cert(ndn::make_shared<ndn::IdentityCertificate>())
-            , certSeqNum(0)
-            , isSignerVerified(false)
-        {}
-        
-        NlsrCertificateStoreEntry(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                                                       , uint32_t csn, bool isv)
-            : cert(pcert)
-            , certSeqNum(csn)
-            , isSignerVerified(isv)
-        {}
-        
-        ndn::shared_ptr<ndn::IdentityCertificate> getCert() const
-        {
-            return cert;
-        }
-        
-        void setCert(ndn::shared_ptr<ndn::IdentityCertificate> pcert)
-        {
-            cert=pcert;
-        }
-        
-        uint32_t getCertSeqNum() const
-        {
-            return certSeqNum;
-        }
-        
-        void setCertSeqNum(uint32_t csn)
-        {
-            certSeqNum=csn;
-        }
-        
-        bool getIsSignerVerified() const
-        {
-            return isSignerVerified;
-        }
-        
-        void setIsSignerVerified(bool isv)
-        {
-            isSignerVerified=isv;
-        }
-        
-      private:
-        ndn::shared_ptr<ndn::IdentityCertificate> cert;
-        uint32_t certSeqNum;
-        bool isSignerVerified;
-    };
-    /* Debugging Purpose */
-    std::ostream&
-    operator <<(std::ostream& os, const NlsrCertificateStoreEntry& ncse);
+      return cert;
+    }
+
+    void setCert(ndn::shared_ptr<ndn::IdentityCertificate> pcert)
+    {
+      cert=pcert;
+    }
+
+    uint32_t getCertSeqNum() const
+    {
+      return certSeqNum;
+    }
+
+    void setCertSeqNum(uint32_t csn)
+    {
+      certSeqNum=csn;
+    }
+
+    bool getIsSignerVerified() const
+    {
+      return isSignerVerified;
+    }
+
+    void setIsSignerVerified(bool isv)
+    {
+      isSignerVerified=isv;
+    }
+
+  private:
+    ndn::shared_ptr<ndn::IdentityCertificate> cert;
+    uint32_t certSeqNum;
+    bool isSignerVerified;
+  };
+  /* Debugging Purpose */
+  std::ostream&
+  operator <<(std::ostream& os, const NlsrCertificateStoreEntry& ncse);
 }
 
 #endif
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
index e97bbfe..8838878 100644
--- a/src/security/nlsr_km.cpp
+++ b/src/security/nlsr_km.cpp
@@ -7,306 +7,299 @@
 
 namespace nlsr
 {
-    bool
-    KeyManager::initKeyManager(ConfParameter &cp)
+  bool
+  KeyManager::initKeyManager(ConfParameter &cp)
+  {
+    initCertSeqFromFile(cp.getSeqFileDir());
+    if( !loadAllCertificates(cp.getCertDir()) )
     {
-        initCertSeqFromFile(cp.getSeqFileDir());
-        if( !loadAllCertificates(cp.getCertDir()) )
-        {
-            return false;
-        }
-        nlsrRootKeyPrefix=cp.getRootKeyPrefix();
-        string processIdentityName(cp.getRootKeyPrefix());
-        processIdentityName += "/";
-        processIdentityName += cp.getSiteName();
-        processIdentityName += "/";
-        processIdentityName += "R.Start";
-        processIdentityName += "/";
-        processIdentityName += cp.getRouterName();
-        ndn::Name ri(processIdentityName);
-        std::cout<<"Router Identity: "<<ri.toUri()<<std::endl;
-        routerIdentity=ri;
-        processIdentityName += "/";
-        processIdentityName += "nlsr";
-        cout<<"Proces Identity Name: "<<processIdentityName<<endl;
-        ndn::Name identityName(processIdentityName);
-        processIdentity=identityName;
-        ndn::KeyChain::deleteIdentity(processIdentity);
-        processCertName = ndn::KeyChain::createIdentity(processIdentity);
-        cout<<"Certificate Name: "<<processCertName.toUri()<<endl;
-        processKeyName=
-            ndn::IdentityCertificate::certificateNameToPublicKeyName(processCertName);
-        cout<<"Key Name: "<<processKeyName.toUri()<<endl;
-        ndn::shared_ptr<ndn::IdentityCertificate> cert=getCertificate(processCertName);
-        signByIdentity(*(cert),routerIdentity);
-        //initCertSeqFromFile(cp.getSeqFileDir());
-        certStore.addCertificate(cert, certSeqNo, true);
-        certStore.printCertStore();
-        
-        return true;
+      return false;
     }
-    
-    bool 
-    KeyManager::loadAllCertificates(std::string certDirPath)
-    {
-        std::string filePath=certDirPath;
-        if(filePath.empty())
-        {
-            SequencingManager sm;
-            filePath=sm.getUserHomeDirectory();
-            filePath+="/nlsrCertDir";
-        }
-        
-        return loadCertificate(filePath+"/root.cert", KEY_TYPE_ROOT) 
-               && loadCertificate(filePath+"/site.cert", KEY_TYPE_SITE)
-               && loadCertificate(filePath+"/operator.cert", KEY_TYPE_OPERATOR)
-               && loadCertificate(filePath+"/router.cert", KEY_TYPE_ROUTER) ;
-    }
-    
-    bool 
-    KeyManager::loadCertificate(std::string inputFile, nlsrKeyType keyType)
-    {
-        try
-        {
-            ndn::shared_ptr<ndn::IdentityCertificate> cert = 
-             ndn::io::load<ndn::IdentityCertificate>(inputFile, ndn::io::BASE_64);
-            ndn::Name certName=cert->getName();
-            //certStore.addCertificate(cert, 10, true);
-            switch(keyType)
-            {
-                case KEY_TYPE_ROOT:
-                    certStore.addCertificate(cert, 10, true);
-                    rootCertName=certName;
-                    break;
-                case KEY_TYPE_SITE:
-                    certStore.addCertificate(cert, 10, true);
-                    siteCertName=certName;
-                    break;
-                case KEY_TYPE_OPERATOR:
-                    certStore.addCertificate(cert, 10, true);
-                    opCertName=certName;
-                    break;
-                case KEY_TYPE_ROUTER:
-                    certStore.addCertificate(cert, certSeqNo, true);
-                    routerCertName=certName;
-                    break;
-                case KEY_TYPE_PROCESS:
-                    certStore.addCertificate(cert, certSeqNo, true);
-                    processCertName=certName;
-                    break;
-                default:
-                    break;
-            }
-            return true;
-        }
-        catch(std::exception& e)
-        {
-            return false;
-        }
-        
-        return false;
-    }
+    nlsrRootKeyPrefix=cp.getRootKeyPrefix();
+    string processIdentityName(cp.getRootKeyPrefix());
+    processIdentityName += "/";
+    processIdentityName += cp.getSiteName();
+    processIdentityName += "/";
+    processIdentityName += "R.Start";
+    processIdentityName += "/";
+    processIdentityName += cp.getRouterName();
+    ndn::Name ri(processIdentityName);
+    std::cout<<"Router Identity: "<<ri.toUri()<<std::endl;
+    routerIdentity=ri;
+    processIdentityName += "/";
+    processIdentityName += "nlsr";
+    cout<<"Proces Identity Name: "<<processIdentityName<<endl;
+    ndn::Name identityName(processIdentityName);
+    processIdentity=identityName;
+    ndn::KeyChain::deleteIdentity(processIdentity);
+    processCertName = ndn::KeyChain::createIdentity(processIdentity);
+    cout<<"Certificate Name: "<<processCertName.toUri()<<endl;
+    processKeyName=
+      ndn::IdentityCertificate::certificateNameToPublicKeyName(processCertName);
+    cout<<"Key Name: "<<processKeyName.toUri()<<endl;
+    ndn::shared_ptr<ndn::IdentityCertificate> cert=getCertificate(processCertName);
+    signByIdentity(*(cert),routerIdentity);
+    certStore.addCertificate(cert, certSeqNo, true);
+    //certStore.printCertStore();
+    return true;
+  }
 
-    ndn::Name
-    KeyManager::getProcessCertName()
+  bool
+  KeyManager::loadAllCertificates(std::string certDirPath)
+  {
+    std::string filePath=certDirPath;
+    if(filePath.empty())
     {
-        return processCertName;
+      SequencingManager sm;
+      filePath=sm.getUserHomeDirectory();
+      filePath+="/nlsrCertDir";
     }
-    
-    ndn::Name 
-    KeyManager::getRouterCertName()
-    {
-        return routerCertName;
-    }
-    
-    ndn::Name 
-    KeyManager::getOperatorCertName()
-    {
-        return opCertName;
-    }
-    
-    ndn::Name 
-    KeyManager::getSiteCertName()
-    {
-        return siteCertName;
-    }
-    
-    ndn::Name 
-    KeyManager::getRootCertName()
-    {
-        return rootCertName;
-    }
+    return loadCertificate(filePath+"/root.cert", KEY_TYPE_ROOT)
+           && loadCertificate(filePath+"/site.cert", KEY_TYPE_SITE)
+           && loadCertificate(filePath+"/operator.cert", KEY_TYPE_OPERATOR)
+           && loadCertificate(filePath+"/router.cert", KEY_TYPE_ROUTER) ;
+  }
 
-    uint32_t
-    KeyManager::getCertSeqNo()
+  bool
+  KeyManager::loadCertificate(std::string inputFile, nlsrKeyType keyType)
+  {
+    try
     {
-        return certSeqNo;
+      ndn::shared_ptr<ndn::IdentityCertificate> cert =
+        ndn::io::load<ndn::IdentityCertificate>(inputFile, ndn::io::BASE_64);
+      ndn::Name certName=cert->getName();
+      switch(keyType)
+      {
+        case KEY_TYPE_ROOT:
+          certStore.addCertificate(cert, 10, true);
+          rootCertName=certName;
+          break;
+        case KEY_TYPE_SITE:
+          certStore.addCertificate(cert, 10, true);
+          siteCertName=certName;
+          break;
+        case KEY_TYPE_OPERATOR:
+          certStore.addCertificate(cert, 10, true);
+          opCertName=certName;
+          break;
+        case KEY_TYPE_ROUTER:
+          certStore.addCertificate(cert, certSeqNo, true);
+          routerCertName=certName;
+          break;
+        case KEY_TYPE_PROCESS:
+          certStore.addCertificate(cert, certSeqNo, true);
+          processCertName=certName;
+          break;
+        default:
+          break;
+      }
+      return true;
     }
+    catch(std::exception& e)
+    {
+      return false;
+    }
+    return false;
+  }
 
-    void
-    KeyManager::setCerSeqNo(uint32_t csn)
-    {
-        certSeqNo=csn;
-    }
+  ndn::Name
+  KeyManager::getProcessCertName()
+  {
+    return processCertName;
+  }
 
-    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();
-    }
+  ndn::Name
+  KeyManager::getRouterCertName()
+  {
+    return routerCertName;
+  }
 
-    void
-    KeyManager::writeCertSeqToFile()
+  ndn::Name
+  KeyManager::getOperatorCertName()
+  {
+    return opCertName;
+  }
+
+  ndn::Name
+  KeyManager::getSiteCertName()
+  {
+    return siteCertName;
+  }
+
+  ndn::Name
+  KeyManager::getRootCertName()
+  {
+    return rootCertName;
+  }
+
+  uint32_t
+  KeyManager::getCertSeqNo()
+  {
+    return certSeqNo;
+  }
+
+  void
+  KeyManager::setCerSeqNo(uint32_t csn)
+  {
+    certSeqNo=csn;
+  }
+
+  void
+  KeyManager::initCertSeqFromFile(string certSeqFileDir)
+  {
+    certSeqFileNameWithPath=certSeqFileDir;
+    if( certSeqFileNameWithPath.empty() )
     {
-        std::ofstream outputFile(certSeqFileNameWithPath.c_str(),ios::binary);
-        outputFile<<certSeqNo;
-        outputFile.close();
+      SequencingManager sm;
+      certSeqFileNameWithPath=sm.getUserHomeDirectory();
     }
-    
-    bool 
-    KeyManager::isNewCertificate(std::string certName, int checkSeqNum)
+    certSeqFileNameWithPath += "/nlsrCertSeqNo.txt";
+    cout<<"Key Seq File Name: "<< certSeqFileNameWithPath<<endl;
+    std::ifstream inputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+    if ( inputFile.good() )
     {
-        return certStore.isCertificateNewInStore(certName,checkSeqNum);
+      inputFile>>certSeqNo;
+      certSeqNo++;
     }
-    
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    KeyManager::getCertificateFromStore(const std::string certName, int checkSeqNum)
+    else
     {
-        return certStore.getCertificateFromStore(certName, checkSeqNum);
+      certSeqNo=1;
     }
-    
-    bool 
-    KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                                                      , uint32_t csn, bool isv)
+    writeCertSeqToFile();
+  }
+
+  void
+  KeyManager::writeCertSeqToFile()
+  {
+    std::ofstream outputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+    outputFile<<certSeqNo;
+    outputFile.close();
+  }
+
+  bool
+  KeyManager::isNewCertificate(std::string certName, int checkSeqNum)
+  {
+    return certStore.isCertificateNewInStore(certName,checkSeqNum);
+  }
+
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  KeyManager::getCertificateFromStore(const std::string certName, int checkSeqNum)
+  {
+    return certStore.getCertificateFromStore(certName, checkSeqNum);
+  }
+
+  bool
+  KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                             , uint32_t csn, bool isv)
+  {
+    return certStore.addCertificate(pcert, csn, isv);
+  }
+
+  nlsrKeyType
+  KeyManager::getKeyTypeFromName(const std::string keyName)
+  {
+    nlsrTokenizer nt(keyName,"/");
+    std::string KEY("KEY");
+    std::string opHandle("O.Start");
+    std::string routerHandle("R.Start");
+    std::string processHandle("nlsr");
+    if ( nt.getTokenString(0,nt.getTokenPosition(KEY)-1) == nlsrRootKeyPrefix)
     {
-        return certStore.addCertificate(pcert, csn, isv);
+      return KEY_TYPE_ROOT;
     }
-    
-    nlsrKeyType 
-    KeyManager::getKeyTypeFromName(const std::string keyName)
+    else if ( nt.doesTokenExist(opHandle) )
     {
-        nlsrTokenizer nt(keyName,"/");
-        std::string KEY("KEY");
-        std::string opHandle("O.Start");
-        std::string routerHandle("R.Start");
-        std::string processHandle("nlsr");
-        if ( nt.getTokenString(0,nt.getTokenPosition(KEY)-1) == nlsrRootKeyPrefix)
-        {
-            return KEY_TYPE_ROOT;
-        }
-        else if ( nt.doesTokenExist(opHandle) )
-        {
-            return KEY_TYPE_OPERATOR;
-        }
-        else if ( nt.doesTokenExist(routerHandle) && 
-                                             nt.doesTokenExist(processHandle))
-        {
-            return KEY_TYPE_PROCESS;
-        }
-        else if ( nt.doesTokenExist(routerHandle) && 
-                                             !nt.doesTokenExist(processHandle))
-        {
-            return KEY_TYPE_ROUTER;
-        }
-        else
-        {
-            return KEY_TYPE_SITE;
-        }
+      return KEY_TYPE_OPERATOR;
     }
-    
-    std::string 
-    KeyManager::getRouterName(const std::string name)
+    else if ( nt.doesTokenExist(routerHandle) &&
+              nt.doesTokenExist(processHandle))
     {
-        std::string routerName;
-        std::string rkp(nlsrRootKeyPrefix);
-        nlsrTokenizer ntRkp(rkp,"/");
-        nlsrTokenizer nt(name,"/");
-        std::string KEY("KEY");
-        std::string opHandle("O.Start");
-        std::string routerHandle("R.Start");
-        std::string processHandle("nlsr");
-        std::string infoHandle("info");
-        std::string lsaHandle("LSA");
-        
-        if ( nt.doesTokenExist(processHandle) && nt.doesTokenExist(routerHandle))
-        {
-            routerName="/ndn" + 
-                        nt.getTokenString(ntRkp.getTokenNumber(), 
-                                          nt.getTokenPosition(routerHandle)-1) +
-                        nt.getTokenString(nt.getTokenPosition(routerHandle)+1, 
-                                          nt.getTokenPosition(processHandle)-1);
-        }
-        else if(nt.doesTokenExist(routerHandle) && !nt.doesTokenExist(infoHandle)
-                                                && !nt.doesTokenExist(lsaHandle))
-        {
-            routerName="/ndn" + 
-                        nt.getTokenString(ntRkp.getTokenNumber(), 
-                                          nt.getTokenPosition(routerHandle)-1) +
-                        nt.getTokenString(nt.getTokenPosition(routerHandle)+1,
-                                                    nt.getTokenPosition(KEY)-1);
-        }
-        else
-        {
-            if (nt.doesTokenExist(infoHandle) )
-            {
-               routerName=nt.getTokenString(0,nt.getTokenPosition(infoHandle)-1);
-            }
-            else
-            {
-                routerName=nt.getTokenString(nt.getTokenPosition(lsaHandle)+1,
-                                             nt.getTokenNumber()-3);
-            } 
-        }
-        return routerName;
+      return KEY_TYPE_PROCESS;
     }
-        
-    std::string 
-    KeyManager::getSiteName(const std::string name)
+    else if ( nt.doesTokenExist(routerHandle) &&
+              !nt.doesTokenExist(processHandle))
     {
-        std::string siteName;
-        std::string routerName;
-        std::string rkp(nlsrRootKeyPrefix);
-        nlsrTokenizer ntRkp(rkp,"/");
-        nlsrTokenizer nt(name,"/");
-        std::string KEY("KEY");
-        std::string opHandle("O.Start");
-        std::string routerHandle("R.Start");
-        
-        if ( nt.doesTokenExist(routerHandle) )
-        {
-            siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(), 
-                                          nt.getTokenPosition(routerHandle) -1); 
-        }
-        else if ( nt.doesTokenExist(opHandle) )
-        {
-            siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(), 
+      return KEY_TYPE_ROUTER;
+    }
+    else
+    {
+      return KEY_TYPE_SITE;
+    }
+  }
+
+  std::string
+  KeyManager::getRouterName(const std::string name)
+  {
+    std::string routerName;
+    std::string rkp(nlsrRootKeyPrefix);
+    nlsrTokenizer ntRkp(rkp,"/");
+    nlsrTokenizer nt(name,"/");
+    std::string KEY("KEY");
+    std::string opHandle("O.Start");
+    std::string routerHandle("R.Start");
+    std::string processHandle("nlsr");
+    std::string infoHandle("info");
+    std::string lsaHandle("LSA");
+    if ( nt.doesTokenExist(processHandle) && nt.doesTokenExist(routerHandle))
+    {
+      routerName="/ndn" +
+                 nt.getTokenString(ntRkp.getTokenNumber(),
+                                   nt.getTokenPosition(routerHandle)-1) +
+                 nt.getTokenString(nt.getTokenPosition(routerHandle)+1,
+                                   nt.getTokenPosition(processHandle)-1);
+    }
+    else if(nt.doesTokenExist(routerHandle) && !nt.doesTokenExist(infoHandle)
+            && !nt.doesTokenExist(lsaHandle))
+    {
+      routerName="/ndn" +
+                 nt.getTokenString(ntRkp.getTokenNumber(),
+                                   nt.getTokenPosition(routerHandle)-1) +
+                 nt.getTokenString(nt.getTokenPosition(routerHandle)+1,
+                                   nt.getTokenPosition(KEY)-1);
+    }
+    else
+    {
+      if (nt.doesTokenExist(infoHandle) )
+      {
+        routerName=nt.getTokenString(0,nt.getTokenPosition(infoHandle)-1);
+      }
+      else
+      {
+        routerName=nt.getTokenString(nt.getTokenPosition(lsaHandle)+1,
+                                     nt.getTokenNumber()-4);
+      }
+    }
+    return routerName;
+  }
+
+  std::string
+  KeyManager::getSiteName(const std::string name)
+  {
+    std::string siteName;
+    std::string routerName;
+    std::string rkp(nlsrRootKeyPrefix);
+    nlsrTokenizer ntRkp(rkp,"/");
+    nlsrTokenizer nt(name,"/");
+    std::string KEY("KEY");
+    std::string opHandle("O.Start");
+    std::string routerHandle("R.Start");
+    if ( nt.doesTokenExist(routerHandle) )
+    {
+      siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
+                                          nt.getTokenPosition(routerHandle) -1);
+    }
+    else if ( nt.doesTokenExist(opHandle) )
+    {
+      siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
                                           nt.getTokenPosition(opHandle) -1);
-        }
-        else
-        {
-           siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(), 
-                                          nt.getTokenPosition(KEY) -1); 
-        }
-        return siteName;
     }
+    else
+    {
+      siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(),
+                                          nt.getTokenPosition(KEY) -1);
+    }
+    return siteName;
+  }
 }
 
 
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
index 5fa7ec6..c141fcf 100644
--- a/src/security/nlsr_km.hpp
+++ b/src/security/nlsr_km.hpp
@@ -14,259 +14,239 @@
 
 namespace nlsr
 {
-    enum nlsrKeyType
+  enum nlsrKeyType
+  {
+    KEY_TYPE_ROOT,
+    KEY_TYPE_SITE,
+    KEY_TYPE_OPERATOR,
+    KEY_TYPE_ROUTER,
+    KEY_TYPE_PROCESS,
+    KEY_TYPE_UNKNOWN
+  };
+
+  enum nlsrContentType
+  {
+    CONTENT_TYPE_DATA,
+    CONTENT_TYPE_CERT
+  };
+
+  class KeyManager: public ndn::KeyChain, public ndn::Validator
+  {
+    typedef SecPublicInfo::Error InfoError;
+    typedef SecTpm::Error TpmError;
+  public:
+    KeyManager()
+      : certSeqNo(1)
+      , certStore()
+      , nlsrRootKeyPrefix()
     {
-        KEY_TYPE_ROOT,
-        KEY_TYPE_SITE,
-        KEY_TYPE_OPERATOR,
-        KEY_TYPE_ROUTER,
-        KEY_TYPE_PROCESS,
-        KEY_TYPE_UNKNOWN
-    };
-    
-    enum nlsrContentType
+    }
+
+    bool 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)
     {
-        CONTENT_TYPE_DATA,
-        CONTENT_TYPE_CERT
-    };
+      ndn::KeyChain::signByIdentity(data,processIdentity);
+    }
 
-    class KeyManager: public ndn::KeyChain, public ndn::Validator
+    template<typename T>
+    void signByIdentity(T& packet, ndn::Name signeeIdentity)
     {
-        typedef SecPublicInfo::Error InfoError;
-        typedef SecTpm::Error TpmError;
-    public:
-        KeyManager()
-            : certSeqNo(1)
-            , certStore()
-            , nlsrRootKeyPrefix()
-        {
-        }
+      ndn::KeyChain::signByIdentity(packet,signeeIdentity);
+    }
 
-        bool initKeyManager(ConfParameter &cp);
-        
-        
+    ndn::shared_ptr<ndn::IdentityCertificate>
+    getCertificate(ndn::Name certificateName)
+    {
+      return ndn::KeyChain::getCertificate(certificateName);
+    }
 
-        void
-        checkPolicy (const ndn::Data& data,
-                     int stepCount,
-                     const ndn::OnDataValidated &onValidated,
-                     const ndn::OnDataValidationFailed &onValidationFailed,
-                     std::vector<ndn::shared_ptr<ndn::ValidationRequest> > &nextSteps)
-        {}
+    ndn::shared_ptr<ndn::IdentityCertificate>
+    getCertificate()
+    {
+      return getCertificate(processCertName);
+    }
 
-        void
-        checkPolicy (const ndn::Interest& interest,
-                     int stepCount,
-                     const ndn::OnInterestValidated &onValidated,
-                     const ndn::OnInterestValidationFailed &onValidationFailed,
-                     std::vector<ndn::shared_ptr<ndn::ValidationRequest> > &nextSteps)
-        {}
+    ndn::Name
+    createIdentity(const ndn::Name identityName)
+    {
+      return ndn::KeyChain::createIdentity(identityName);
+    }
 
-        void signData(ndn::Data& data)
+    ndn::Name
+    createIdentity(const ndn::Name identityName, const ndn::Name signee)
+    {
+      ndn::KeyChain::addIdentity(identityName);
+      ndn::Name keyName;
+      try
+      {
+        keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
+      }
+      catch(InfoError& e)
+      {
+        keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
+      }
+      ndn::shared_ptr<ndn::PublicKey> pubKey;
+      try
+      {
+        pubKey = ndn::KeyChain::getPublicKey(keyName);
+      }
+      catch(InfoError& e)
+      {
+        return identityName;
+      }
+      ndn::Name certName;
+      try
+      {
+        certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
+      }
+      catch(InfoError& e)
+      {
+        ndn::shared_ptr<ndn::IdentityCertificate> certificate =
+          ndn::make_shared<ndn::IdentityCertificate>();
+        ndn::Name certificateName = keyName.getPrefix(-1);
+        certificateName.append("KEY").append(
+          keyName.get(-1)).append("ID-CERT").appendVersion();
+        certificate->setName(certificateName);
+        certificate->setNotBefore(ndn::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(data,processIdentity);
+          ndn::KeyChain::signByIdentity(*certificate,signee);
         }
-        
-        template<typename T>
-        void signByIdentity(T& packet, ndn::Name signeeIdentity)
+        catch(InfoError& e)
         {
-            ndn::KeyChain::signByIdentity(packet,signeeIdentity);
+          try
+          {
+            ndn::KeyChain::deleteIdentity(identityName);
+          }
+          catch(InfoError& e)
+          {
+          }
+          return identityName;
         }
-        
-        ndn::shared_ptr<ndn::IdentityCertificate>
-        getCertificate(ndn::Name certificateName)
-        {
-            return ndn::KeyChain::getCertificate(certificateName);
-        }
-        
-        ndn::shared_ptr<ndn::IdentityCertificate>
-        getCertificate()
-        {
-            return getCertificate(processCertName);
-        }
-        
-        ndn::Name
-        createIdentity(const ndn::Name identityName)
-        {
-            return ndn::KeyChain::createIdentity(identityName);
-        }
+        certName=certificate->getName();
+      }
+      return certName;
+    }
 
-        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;
-        }
-        
-        void printCertStore()
-        {
-            certStore.printCertStore();
-        }
-        
-    private:
-        bool
-        verifyDataPacket(ndn::Data packet)
-        {
-            ndn::SignatureSha256WithRsa signature(packet.getSignature());
-            std::string signingCertName=signature.getKeyLocator().getName().toUri();
-            std::string packetName=packet.getName().toUri();
-            
-            std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
-                             certStore.getCertificateFromStore(signingCertName);
-            if( signee.second )
-            {
-                return ( getRouterName(signingCertName)== getRouterName(packetName)
-                       && verifySignature(packet, signee.first->getPublicKeyInfo()));
-            }
-            
-            return false; 
-        }
-        
-        bool 
-        verifyCertPacket(ndn::IdentityCertificate packet)
-        {
-            return true;
-        }
-        
-        template<typename T>
-        bool 
-        verify(T& packet , nlsrContentType contentType,
-                                                     nlsrKeyType signingKeyType)
-        {
-            switch(contentType)
-            {
-                case CONTENT_TYPE_DATA:
-                    return verifyDataPacket(packet);
-                    break;
-                case CONTENT_TYPE_CERT:
-                    return verifyCertPacket(packet);
-                    break;
-            }
-            
-            return false;
-        }
-        
-    public:
-        template<typename T>
-        bool 
-        verify(T& packet )
-        {
-            ndn::SignatureSha256WithRsa signature(packet.getSignature());
-            std::string signingKeyName=signature.getKeyLocator().getName().toUri();
-            std::string packetName=packet.getName().toUri();
-            nlsrTokenizer nt(packetName,"/");
-            std::string keyHandle("keys");
-            if ( nt.doesTokenExist(keyHandle) )
-            {
-                return verify(packet, CONTENT_TYPE_CERT, 
-                                            getKeyTypeFromName(signingKeyName));
-            }
-            else
-            {
-                return verify(packet, CONTENT_TYPE_DATA, 
-                                            getKeyTypeFromName(signingKeyName));
-            }
-            
-            return false;
-        }
+    void printCertStore()
+    {
+      certStore.printCertStore();
+    }
 
-        ndn::Name getProcessCertName();
-        ndn::Name getRouterCertName();
-        ndn::Name getOperatorCertName();
-        ndn::Name getSiteCertName();
-        ndn::Name getRootCertName();
+  private:
+    bool
+    verifyDataPacket(ndn::Data packet)
+    {
+      std::cout<<"KeyManager::verifyDataPacket Called"<<std::endl;
+      ndn::SignatureSha256WithRsa signature(packet.getSignature());
+      std::string signingCertName=signature.getKeyLocator().getName().toUri();
+      std::string packetName=packet.getName().toUri();
+      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
+        certStore.getCertificateFromStore(signingCertName);
+      if( signee.second )
+      {
+        std::string routerNameFromPacketName=getRouterName(packetName);
+        std::string routerNameFromCertName=getRouterName(signingCertName);
+        return ( (routerNameFromPacketName== routerNameFromCertName) &&
+                 verifySignature(packet, signee.first->getPublicKeyInfo()));
+      }
+      return false;
+    }
 
-        uint32_t getCertSeqNo();
-        void setCerSeqNo(uint32_t csn);
-        void initCertSeqFromFile(string certSeqFileDir);
-        void writeCertSeqToFile();
-        bool isNewCertificate(std::string certName, int checkSeqNum);
-        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-        getCertificateFromStore(const std::string certName, int checkSeqNum);
-        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-        getCertificateFromStore(const std::string certName);
-        bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
-                                                      , uint32_t csn, bool isv);
-        
-        
-    private:
-        bool loadAllCertificates(std::string certDirPath);
-        bool loadCertificate(std::string inputFile, nlsrKeyType keyType);
-        nlsrKeyType getKeyTypeFromName(const std::string keyName);
-        std::string getRouterName(const std::string name);
-        std::string getSiteName(const std::string name);
+    bool
+    verifyCertPacket(ndn::IdentityCertificate packet)
+    {
+      std::cout<<"KeyManager::verifyCertPacket Called"<<std::endl;
+      return true;
+    }
 
-    private:
-        ndn::Name processIdentity;
-        ndn::Name routerIdentity;
-        ndn::Name processCertName;
-        ndn::Name routerCertName;
-        ndn::Name opCertName;
-        ndn::Name siteCertName;
-        ndn::Name rootCertName;
-        ndn::Name processKeyName;
-        uint32_t certSeqNo;
-        string certSeqFileNameWithPath;
-        string nlsrRootKeyPrefix;
-        NlsrCertificateStore certStore;
 
-    };
+  public:
+    template<typename T>
+    bool
+    verify(T& packet )
+    {
+      std::cout<<"KeyManager::verify Called"<<std::endl;
+      std::string packetName=packet.getName().toUri();
+      nlsrTokenizer nt(packetName,"/");
+      std::string keyHandle("keys");
+      if ( nt.doesTokenExist(keyHandle) )
+      {
+        return verifyCertPacket(packet);
+      }
+      else
+      {
+        return verifyDataPacket(packet);
+      }
+      return false;
+    }
+
+    ndn::Name getProcessCertName();
+    ndn::Name getRouterCertName();
+    ndn::Name getOperatorCertName();
+    ndn::Name getSiteCertName();
+    ndn::Name getRootCertName();
+
+    uint32_t getCertSeqNo();
+    void setCerSeqNo(uint32_t csn);
+    void initCertSeqFromFile(string certSeqFileDir);
+    void writeCertSeqToFile();
+    bool isNewCertificate(std::string certName, int checkSeqNum);
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+    getCertificateFromStore(const std::string certName, int checkSeqNum);
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+    getCertificateFromStore(const std::string certName);
+    bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                        , uint32_t csn, bool isv);
+
+
+  private:
+    bool loadAllCertificates(std::string certDirPath);
+    bool loadCertificate(std::string inputFile, nlsrKeyType keyType);
+    nlsrKeyType getKeyTypeFromName(const std::string keyName);
+    std::string getRouterName(const std::string name);
+    std::string getSiteName(const std::string name);
+
+  private:
+    ndn::Name processIdentity;
+    ndn::Name routerIdentity;
+    ndn::Name processCertName;
+    ndn::Name routerCertName;
+    ndn::Name opCertName;
+    ndn::Name siteCertName;
+    ndn::Name rootCertName;
+    ndn::Name processKeyName;
+    uint32_t certSeqNo;
+    string certSeqFileNameWithPath;
+    string nlsrRootKeyPrefix;
+    NlsrCertificateStore certStore;
+
+  };
 }
 
 #endif
diff --git a/src/utility/nlsr_logger.cpp b/src/utility/nlsr_logger.cpp
index 804ef98..82b6e75 100644
--- a/src/utility/nlsr_logger.cpp
+++ b/src/utility/nlsr_logger.cpp
@@ -3,57 +3,57 @@
 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::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
+  NlsrLogger::getUserHomeDirectory()
+  {
+    string homeDirPath(getpwuid(getuid())->pw_dir);
+    if( homeDirPath.empty() )
     {
-        string homeDirPath(getpwuid(getuid())->pw_dir);
-        if( homeDirPath.empty() )
-        {
-            homeDirPath = getenv("HOME");
-        }
-        return homeDirPath;
+      homeDirPath = getenv("HOME");
     }
+    return homeDirPath;
+  }
 
-    void
-    NlsrLogger::initNlsrLogger(std::string dirPath)
+  void
+  NlsrLogger::initNlsrLogger(std::string dirPath)
+  {
+    string logDirPath(dirPath);
+    if( dirPath.empty() )
     {
-        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);
+      logDirPath=getUserHomeDirectory()+"/nlsrLog";
     }
+    cout<<"Log Dir Path: "<< logDirPath<<endl;
+    typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
+    shared_ptr< file_sink > sink(new file_sink(
+                                   keywords::file_name = logDirPath
+                                       +"/NLSR%Y%m%d%H%M%S_%3N.log",
+                                   keywords::rotation_size = 16 * 1024 * 1024,
+                                   keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0),
+                                   keywords::auto_flush = true
+                                 ));
+    sink->locked_backend()->set_file_collector(sinks::file::make_collector(
+          keywords::target = logDirPath,
+          //keywords::max_size =  512 * 1024 * 1024,
+          keywords::min_free_space = 64 * 1024 * 1024
+        ));
+    sink->set_formatter(
+      expr::format("%1%: %2%")
+      % getEpochTime()
+      % expr::smessage
+    );
+    logging::core::get()->add_sink(sink);
+  }
 
 }//namespace nlsr
diff --git a/src/utility/nlsr_logger.hpp b/src/utility/nlsr_logger.hpp
index 222ac52..129fe30 100644
--- a/src/utility/nlsr_logger.hpp
+++ b/src/utility/nlsr_logger.hpp
@@ -25,38 +25,38 @@
 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;
+  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;
+  using boost::shared_ptr;
+  using namespace std;
 
 
-    class NlsrLogger
+  class NlsrLogger
+  {
+  public:
+    NlsrLogger()
     {
-    public:
-        NlsrLogger()
-        {
-        }
+    }
 
-        void initNlsrLogger(std::string dirPath);
+    void initNlsrLogger(std::string dirPath);
 
-        src::logger& getLogger()
-        {
-            return mLogger;
-        }
+    src::logger& getLogger()
+    {
+      return mLogger;
+    }
 
-    private:
-        string getEpochTime();
-        string getUserHomeDirectory();
+  private:
+    string getEpochTime();
+    string getUserHomeDirectory();
 
-    private:
-        src::logger mLogger;
-    };
+  private:
+    src::logger mLogger;
+  };
 
 }//namespace nlsr
 #endif
diff --git a/src/utility/nlsr_tokenizer.cpp b/src/utility/nlsr_tokenizer.cpp
index 809e395..35d6625 100644
--- a/src/utility/nlsr_tokenizer.cpp
+++ b/src/utility/nlsr_tokenizer.cpp
@@ -9,102 +9,102 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace boost;
+  using namespace std;
+  using namespace boost;
 
-    void
-    nlsrTokenizer::makeToken()
+  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)
     {
-        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();
+      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);
-    }
+  void
+  nlsrTokenizer::insertToken(const string& token)
+  {
+    tokenList.push_back(token);
+    vTokenList.push_back(token);
+  }
 
-    int
-    nlsrTokenizer::getTokenPosition(string& token)
+  int
+  nlsrTokenizer::getTokenPosition(string& token)
+  {
+    int pos=-1;
+    int i=0;
+    for(std::list<string>::iterator it=tokenList.begin();
+        it!=tokenList.end(); it++)
     {
-        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;
+      if( (*it) == token )
+      {
+        break;
+      }
+      i++;
     }
+    if( i < tokenList.size() )
+    {
+      pos=i;
+    }
+    return pos;
+  }
 
-    string
-    nlsrTokenizer::getTokenString(int from , int to)
+  string
+  nlsrTokenizer::getTokenString(int from , int to)
+  {
+    string returnString="";
+    if((from>=0 && to<tokenList.size()) &&
+        (to>=from && to <tokenList.size()))
     {
-        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;
+      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);
-    }
+  string
+  nlsrTokenizer::getTokenString(int from)
+  {
+    return getTokenString(from,tokenList.size()-1);
+  }
 
-    static bool
-    tokenCompare(string& s1, string& s2)
-    {
-        return s1==s2;
-    }
+  static bool
+  tokenCompare(string& s1, string& s2)
+  {
+    return s1==s2;
+  }
 
-    void
-    nlsrTokenizer::makeRestOfTheLine()
-    {
-        restOfTheLine=getTokenString(1);
-    }
+  void
+  nlsrTokenizer::makeRestOfTheLine()
+  {
+    restOfTheLine=getTokenString(1);
+  }
 
-    bool
-    nlsrTokenizer::doesTokenExist(string token)
+  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() )
     {
-        std::list<string >::iterator it = std::find_if( tokenList.begin(),
-                                          tokenList.end(),
-                                          bind(&tokenCompare, _1 , token));
-        if( it != tokenList.end() )
-        {
-            return true;
-        }
-        return false;
+      return true;
     }
+    return false;
+  }
 
 }//namespace nlsr
diff --git a/src/utility/nlsr_tokenizer.hpp b/src/utility/nlsr_tokenizer.hpp
index 6cd97e0..4b84d8b 100644
--- a/src/utility/nlsr_tokenizer.hpp
+++ b/src/utility/nlsr_tokenizer.hpp
@@ -12,93 +12,93 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace boost;
+  using namespace std;
+  using namespace boost;
 
-    class nlsrTokenizer
+  class nlsrTokenizer
+  {
+  public:
+    nlsrTokenizer(const string& inputString)
+      : firstToken()
+      , restOfTheLine()
+      , currentPosition(0)
     {
-    public:
-        nlsrTokenizer(const string& inputString)
-            : firstToken()
-            , restOfTheLine()
-            , currentPosition(0)
-        {
-            seps = " ";
-            originalString = inputString;
-            makeToken();
-        }
+      seps = " ";
+      originalString = inputString;
+      makeToken();
+    }
 
-        nlsrTokenizer(const string& inputString, const string& separator)
-            : firstToken()
-            , restOfTheLine()
-            , currentPosition(0)
-        {
-            seps = separator;
-            originalString = inputString;
-            makeToken();
-        }
+    nlsrTokenizer(const string& inputString, const string& separator)
+      : firstToken()
+      , restOfTheLine()
+      , currentPosition(0)
+    {
+      seps = separator;
+      originalString = inputString;
+      makeToken();
+    }
 
-        string getFirstToken()
-        {
-            return firstToken;
-        }
+    string getFirstToken()
+    {
+      return firstToken;
+    }
 
-        string getRestOfLine()
-        {
-            return restOfTheLine;
-        }
+    string getRestOfLine()
+    {
+      return restOfTheLine;
+    }
 
-        void resetCurrentPosition(uint32_t cp=0)
-        {
-            if( cp >=0 && cp <= vTokenList.size() )
-            {
-                currentPosition=cp;
-            }
-        }
+    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 "";
-        }
+    string getNextToken()
+    {
+      if(currentPosition >= 0 && currentPosition <= (vTokenList.size()-1))
+      {
+        return vTokenList[currentPosition++];
+      }
+      return "";
+    }
 
-        uint32_t getTokenNumber()
-        {
-            return tokenList.size();
-        }
+    uint32_t getTokenNumber()
+    {
+      return tokenList.size();
+    }
 
-        string getToken(int position)
-        {
-            if( position >=0 && position <vTokenList.size() )
-            {
-                return vTokenList[position];
-            }
-            return "";
-        }
+    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);
+    int getTokenPosition(string& token);
+    string getTokenString(int from , int to);
+    string getTokenString(int from);
+    bool doesTokenExist(string token);
 
 
-    private:
+  private:
 
-        void makeToken();
-        void insertToken(const string& token);
-        void makeRestOfTheLine();
+    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;
-    };
+    string seps;
+    string originalString;
+    string firstToken;
+    string restOfTheLine;
+    std::list<string> tokenList;
+    std::vector<string> vTokenList;
+    uint32_t currentPosition;
+  };
 
 }//namespace nlsr
 #endif
