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
