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
