diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index 761365d..49886e0 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -12,40 +12,41 @@
 #include "nlsr_lsdb.hpp"
 #include "nlsr_logger.hpp"
 //test purpose of NLSR
-#include "nlsr_test.hpp" 
+#include "nlsr_test.hpp"
 
-namespace nlsr {
-
-using namespace ndn;
-using namespace std;
-
-void
-Nlsr::nlsrRegistrationFailed(const ndn::Name& name)
+namespace nlsr
 {
-  cerr << "ERROR: Failed to register prefix in local hub's daemon" << endl;
-  getNlsrFace().shutdown();
-}
+
+    using namespace ndn;
+    using namespace std;
+
+    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::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::startEventLoop()
-{
-	getNlsrFace().processEvents();
-}
+    void
+    Nlsr::startEventLoop()
+    {
+        getNlsrFace().processEvents();
+    }
 
-int 
-Nlsr::usage(const string& progname)
-{
+    int
+    Nlsr::usage(const string& progname)
+    {
 
         cout << "Usage: " << progname << " [OPTIONS...]"<<endl;
         cout << "   NDN routing...." << endl;
@@ -55,88 +56,95 @@
         cout << "       -h, --help          Display this help message" << endl;
 
         exit(EXIT_FAILURE);
-}
+    }
 
 
 } // namespace nlsr
 
 using namespace nlsr;
 
-int 
-main(int argc, char **argv){
-	nlsr::Nlsr nlsr_;
-	string programName(argv[0]);
-	nlsr_.setConfFileName("nlsr.conf");
+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) {
-    switch (opt) {
-    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;
+    int opt;
+    while ((opt = getopt(argc, argv, "df:p:h")) != -1)
+    {
+        switch (opt)
+        {
+            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;
+        }
     }
-  }
-	
-	
-	ConfFileProcessor cfp(nlsr_.getConfFileName());
-	int res=cfp.processConfFile(nlsr_);
-	if ( res < 0 )
-	{
-		return EXIT_FAILURE;
-	}
-	
-	nlsr_.getConfParameter().buildRouterPrefix();
-	nlsr_.getNlsrLogger().initNlsrLogger(nlsr_.getConfParameter().getLogDir());
-	//src::logger lg;
-	//BOOST_LOG(lg) << "Some log record from nlsr.cpp";
-	//for(int j=0; j< 1000; j++)
-	//{
-	//	BOOST_LOG(lg) << "Some log record from nlsr.cpp "<<j;
-	//}
-	nlsr_.getLsdb().setLsaRefreshTime(nlsr_.getConfParameter().getLsaRefreshTime());
-	nlsr_.getFib().setFibEntryRefreshTime(2*nlsr_.getConfParameter().getLsaRefreshTime());
-	nlsr_.getLsdb().setThisRouterPrefix(nlsr_.getConfParameter().getRouterPrefix());
 
-	/* debugging purpose start */
-	cout <<	nlsr_.getConfParameter();
-	nlsr_.getAdl().printAdl();
-	nlsr_.getNpl().printNpl();
-  /* debugging purpose end */
 
-	nlsr_.getLsdb().buildAndInstallOwnNameLsa(nlsr_);
-	nlsr_.getLsdb().buildAndInstallOwnCorLsa(nlsr_);
+    ConfFileProcessor cfp(nlsr_.getConfFileName());
+    int res=cfp.processConfFile(nlsr_);
+    if ( res < 0 )
+    {
+        return EXIT_FAILURE;
+    }
 
-	
-	
+    nlsr_.getConfParameter().buildRouterPrefix();
+    nlsr_.getNlsrLogger().initNlsrLogger(nlsr_.getConfParameter().getLogDir());
+    //src::logger lg;
+    //BOOST_LOG(lg) << "Some log record from nlsr.cpp";
+    //for(int j=0; j< 1000; j++)
+    //{
+    //	BOOST_LOG(lg) << "Some log record from nlsr.cpp "<<j;
+    //}
+    nlsr_.getLsdb().setLsaRefreshTime(nlsr_.getConfParameter().getLsaRefreshTime());
+    nlsr_.getFib().setFibEntryRefreshTime(
+        2*nlsr_.getConfParameter().getLsaRefreshTime());
+    nlsr_.getLsdb().setThisRouterPrefix(nlsr_.getConfParameter().getRouterPrefix());
 
-	nlsr_.setInterestFilterNlsr(nlsr_.getConfParameter().getRouterPrefix());
-	nlsr_.getIm().scheduleInfoInterest(nlsr_,1);
-	//testing purpose
-	nlsr_.getNlsrTesting().schedlueAddingLsas(nlsr_);
+    /* debugging purpose start */
+    cout <<	nlsr_.getConfParameter();
+    nlsr_.getAdl().printAdl();
+    nlsr_.getNpl().printNpl();
+    /* debugging purpose end */
 
-	
-	
+    nlsr_.getLsdb().buildAndInstallOwnNameLsa(nlsr_);
+    nlsr_.getLsdb().buildAndInstallOwnCorLsa(nlsr_);
 
-	try{
-		nlsr_.startEventLoop();
-	}catch(std::exception &e) {
-    		std::cerr << "ERROR: " << e.what() << std::endl;
-	}
 
-	return EXIT_SUCCESS;
+
+
+    nlsr_.setInterestFilterNlsr(nlsr_.getConfParameter().getRouterPrefix());
+    nlsr_.getIm().scheduleInfoInterest(nlsr_,1);
+    //testing purpose
+    nlsr_.getNlsrTesting().schedlueAddingLsas(nlsr_);
+
+
+
+
+    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 8f569c4..2f2ee61 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -19,221 +19,233 @@
 //testing
 #include "nlsr_test.hpp"
 
-namespace nlsr {
-
-using namespace ndn;
-using namespace std;
-
-class Nlsr
+namespace nlsr
 {
-public:
-	Nlsr()
-		: io(ndn::make_shared<boost::asio::io_service>())
-		, nlsrFace(io)
-		, scheduler(*io)
-		, configFileName()	
-		, confParam()
-		, adl()
-		, npl()
-    , im()
-    , dm()
-    , sm()
-    , nlsrLsdb()
-    , adjBuildCount(0)
-    , isBuildAdjLsaSheduled(0)
-    , isRouteCalculationScheduled(0)
-    , isRoutingTableCalculating(0)
-    , routingTable()
-    , npt()
-    , fib()
-    , nlsrLogger()
-    , nlsrTesting()
-	{
-		isDaemonProcess=false;
-		configFileName="nlsr.conf";	
-	}
 
-	void nlsrRegistrationFailed(const ndn::Name& name);
+    using namespace ndn;
+    using namespace std;
 
-	void setInterestFilterNlsr(const string& name);
-	void startEventLoop();
-	
-	int usage(const string& progname);
+    class Nlsr
+    {
+    public:
+        Nlsr()
+            : io(ndn::make_shared<boost::asio::io_service>())
+            , nlsrFace(io)
+            , scheduler(*io)
+            , configFileName()
+            , confParam()
+            , adl()
+            , npl()
+            , im()
+            , dm()
+            , sm()
+            , nlsrLsdb()
+            , adjBuildCount(0)
+            , isBuildAdjLsaSheduled(0)
+            , isRouteCalculationScheduled(0)
+            , isRoutingTableCalculating(0)
+            , routingTable()
+            , npt()
+            , fib()
+            , nlsrLogger()
+            , nlsrTesting()
+        {
+            isDaemonProcess=false;
+            configFileName="nlsr.conf";
+        }
 
-	string getConfFileName()
-  {
-		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::Face& getNlsrFace(){
-		return nlsrFace;
-	}
+        Npl& getNpl()
+        {
+            return npl;
+        }
 
-	ndn::KeyChain& getKeyChain(){
-		return kChain;
-	}
+        ndn::shared_ptr<boost::asio::io_service>& getIo()
+        {
+            return io;
+        }
 
-	interestManager& getIm(){
-		return im;
-	}
+        ndn::Scheduler& getScheduler()
+        {
+            return scheduler;
+        }
 
-	DataManager& getDm(){
-		return dm;
-	}
+        ndn::Face& getNlsrFace()
+        {
+            return nlsrFace;
+        }
 
-	SequencingManager& getSm(){
-	 return sm;
-	}
+        ndn::KeyChain& getKeyChain()
+        {
+            return kChain;
+        }
 
-	Lsdb& getLsdb(){
-		return nlsrLsdb;
-	}
+        interestManager& getIm()
+        {
+            return im;
+        }
 
-	RoutingTable& getRoutingTable(){
-		return routingTable;
-	}
+        DataManager& getDm()
+        {
+            return dm;
+        }
 
-	Npt& getNpt()
-	{
-		return npt;
-	}
+        SequencingManager& getSm()
+        {
+            return sm;
+        }
 
-	Fib& getFib()
-	{
-		return fib;
-	}
+        Lsdb& getLsdb()
+        {
+            return nlsrLsdb;
+        }
 
-	long int getAdjBuildCount()
-	{
-		return adjBuildCount;
-	}
+        RoutingTable& getRoutingTable()
+        {
+            return routingTable;
+        }
 
-	void incrementAdjBuildCount()
-	{
-		adjBuildCount++;
-	}
+        Npt& getNpt()
+        {
+            return npt;
+        }
 
-	void setAdjBuildCount(long int abc)
-	{
-		adjBuildCount=abc;
-	}
+        Fib& getFib()
+        {
+            return fib;
+        }
 
-	int getIsBuildAdjLsaSheduled()
-	{
-		return isBuildAdjLsaSheduled;
-	}
+        long int getAdjBuildCount()
+        {
+            return adjBuildCount;
+        }
 
-	void setIsBuildAdjLsaSheduled(int iabls)
-	{
-		isBuildAdjLsaSheduled=iabls;
-	}
+        void incrementAdjBuildCount()
+        {
+            adjBuildCount++;
+        }
 
-	NlsrTest& getNlsrTesting()
-	{
-		return nlsrTesting;
-	}
+        void setAdjBuildCount(long int abc)
+        {
+            adjBuildCount=abc;
+        }
 
-	void setApiPort(int ap)
-	{
-		apiPort=ap;
-	}
+        int getIsBuildAdjLsaSheduled()
+        {
+            return isBuildAdjLsaSheduled;
+        }
 
-	int getApiPort()
-	{
-		return apiPort;
-	}
+        void setIsBuildAdjLsaSheduled(int iabls)
+        {
+            isBuildAdjLsaSheduled=iabls;
+        }
 
-	int getIsRoutingTableCalculating()
-	{
-		return isRoutingTableCalculating;
-	}
+        NlsrTest& getNlsrTesting()
+        {
+            return nlsrTesting;
+        }
 
-	void setIsRoutingTableCalculating(int irtc)
-	{
-		isRoutingTableCalculating=irtc;
-	}
+        void setApiPort(int ap)
+        {
+            apiPort=ap;
+        }
 
-	int getIsRouteCalculationScheduled()
-	{
-		return isRouteCalculationScheduled;
-	}
+        int getApiPort()
+        {
+            return apiPort;
+        }
 
-	void setIsRouteCalculationScheduled(int ircs)
-	{
-		isRouteCalculationScheduled=ircs;
-	}
+        int getIsRoutingTableCalculating()
+        {
+            return isRoutingTableCalculating;
+        }
 
-	NlsrLogger& getNlsrLogger()
-	{
-		return nlsrLogger;
-	}
-	
-private:
-	ConfParameter confParam;
-	Adl adl;
-	Npl npl;
-	ndn::shared_ptr<boost::asio::io_service> io;
-	ndn::Scheduler scheduler;
-	ndn::Face nlsrFace;
-	ndn::KeyChain kChain;
-	interestManager im;
-	DataManager dm;
-	SequencingManager sm;
-	bool isDaemonProcess;
-	string configFileName;
-	int apiPort;
-	
-	Lsdb nlsrLsdb;
-	RoutingTable routingTable;
-	Npt npt;
-	Fib fib;
-	NlsrLogger nlsrLogger;
+        void setIsRoutingTableCalculating(int irtc)
+        {
+            isRoutingTableCalculating=irtc;
+        }
 
-	long int adjBuildCount;
-	int isBuildAdjLsaSheduled;
-	int isRouteCalculationScheduled;
-	int isRoutingTableCalculating;
+        int getIsRouteCalculationScheduled()
+        {
+            return isRouteCalculationScheduled;
+        }
 
-	NlsrTest nlsrTesting;
-	
+        void setIsRouteCalculationScheduled(int ircs)
+        {
+            isRouteCalculationScheduled=ircs;
+        }
 
-};
+        NlsrLogger& getNlsrLogger()
+        {
+            return nlsrLogger;
+        }
+
+    private:
+        ConfParameter confParam;
+        Adl adl;
+        Npl npl;
+        ndn::shared_ptr<boost::asio::io_service> io;
+        ndn::Scheduler scheduler;
+        ndn::Face nlsrFace;
+        ndn::KeyChain kChain;
+        interestManager im;
+        DataManager dm;
+        SequencingManager sm;
+        bool isDaemonProcess;
+        string configFileName;
+        int apiPort;
+
+        Lsdb nlsrLsdb;
+        RoutingTable routingTable;
+        Npt npt;
+        Fib fib;
+        NlsrLogger nlsrLogger;
+
+        long int adjBuildCount;
+        int isBuildAdjLsaSheduled;
+        int isRouteCalculationScheduled;
+        int isRoutingTableCalculating;
+
+        NlsrTest nlsrTesting;
+
+
+    };
 
 } //namespace nlsr
 
diff --git a/src/nlsr_adjacent.cpp b/src/nlsr_adjacent.cpp
index 6b0b1c0..6cc4db0 100644
--- a/src/nlsr_adjacent.cpp
+++ b/src/nlsr_adjacent.cpp
@@ -5,35 +5,38 @@
 
 #include "nlsr_adjacent.hpp"
 
-namespace nlsr {
-
-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;
-}
-
-bool 
-Adjacent::isAdjacentEqual(Adjacent& adj)
+namespace nlsr
 {
-	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;
-}
+    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;
+    }
+
+    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;
+    }
 
 } //namespace nlsr
diff --git a/src/nlsr_adjacent.hpp b/src/nlsr_adjacent.hpp
index 86a6cf5..8d97db6 100644
--- a/src/nlsr_adjacent.hpp
+++ b/src/nlsr_adjacent.hpp
@@ -1,84 +1,96 @@
 #ifndef ADJACENT_HPP
 #define ADJACENT_HPP
 
-namespace nlsr {
+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;
-		}
-		 
-		void setConnectingFace(int cf){
-			connectingFace=cf;
-		}
+        int getConnectingFace()
+        {
+            return connectingFace;
+        }
 
-		double getLinkCost(){
-			return linkCost;
-		}
+        void setConnectingFace(int cf)
+        {
+            connectingFace=cf;
+        }
 
-		void setLinkCost(double lc){
-			linkCost=lc;
-		}
+        double getLinkCost()
+        {
+            return linkCost;
+        }
 
-		int getStatus(){
-			return status;
-		}
+        void setLinkCost(double lc)
+        {
+            linkCost=lc;
+        }
 
-		void setStatus(int s){
-			status=s;
-		}
+        int getStatus()
+        {
+            return status;
+        }
 
-		int getInterestTimedOutNo(){
-			return interestTimedOutNo;
-		}
+        void setStatus(int s)
+        {
+            status=s;
+        }
 
-		void setInterestTimedOutNo(int iton){
-			interestTimedOutNo=iton;
-		}
+        int getInterestTimedOutNo()
+        {
+            return interestTimedOutNo;
+        }
 
-		bool isAdjacentEqual(Adjacent& adj);
-	private:
-		string adjacentName;
-		int connectingFace;
-		double linkCost;
-		int status;
-		int interestTimedOutNo;
-};
+        void setInterestTimedOutNo(int iton)
+        {
+            interestTimedOutNo=iton;
+        }
 
-std::ostream&
-operator << (std::ostream &os, Adjacent &adj);
+        bool isAdjacentEqual(Adjacent& adj);
+    private:
+        string adjacentName;
+        int connectingFace;
+        double linkCost;
+        int status;
+        int interestTimedOutNo;
+    };
+
+    std::ostream&
+    operator << (std::ostream &os, Adjacent &adj);
 
 } // namespace nlsr
 
diff --git a/src/nlsr_adl.cpp b/src/nlsr_adl.cpp
index 49a77f2..64976d7 100644
--- a/src/nlsr_adl.cpp
+++ b/src/nlsr_adl.cpp
@@ -5,264 +5,288 @@
 #include "nlsr_adjacent.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
-
-Adl::Adl(){
-}
-
-Adl::~Adl(){
-
-}
-
-static bool
-adjacent_compare(Adjacent& adj1, Adjacent& adj2){
-	return adj1.getAdjacentName()==adj2.getAdjacentName();
-}
-
-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() ){
-		return -1;
-	}
-	adjList.push_back(adj);
-	return 0;
-}
-
-void 
-Adl::addAdjacentsFromAdl(Adl& adl)
+namespace nlsr
 {
-	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));
+    Adl::Adl()
+    {
+    }
 
-	if( it == adjList.end()){
-		return -1;
-	}
+    Adl::~Adl()
+    {
 
-	(*it).setStatus(s);
-	return 0;
-	
+    }
 
-}
+    static bool
+    adjacent_compare(Adjacent& adj1, Adjacent& adj2)
+    {
+        return adj1.getAdjacentName()==adj2.getAdjacentName();
+    }
 
-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));
+    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() )
+        {
+            return -1;
+        }
+        adjList.push_back(adj);
+        return 0;
+    }
 
-	if( it != adjList.end()){
-		return (*it);
-	}
+    void
+    Adl::addAdjacentsFromAdl(Adl& adl)
+    {
+        for(std::list<Adjacent >::iterator it=adl.getAdjList().begin();
+                it!=adl.getAdjList().end(); ++it)
+        {
+            insert((*it));
+        }
+    }
 
-	return adj;
-}
+    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;
 
 
-bool 
-Adl::isAdlEqual(Adl &adl)
-{
-	if ( getAdlSize() != adl.getAdlSize() )
-	{
-		return false;
-	}
+    }
 
-	adjList.sort(adjacent_compare);	
-	adl.getAdjList().sort(adjacent_compare);
-	int equalAdjCount=0;
+    Adjacent
+    Adl::getAdjacent(string adjName)
+    {
+        Adjacent adj(adjName);
 
-	std::list< Adjacent > adjList2=adl.getAdjList();
+        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                            adjList.end(),
+                                            bind(&adjacent_compare, _1, adj));
 
-	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++;
-	}
+        if( it != adjList.end())
+        {
+            return (*it);
+        }
 
-	return equalAdjCount==getAdlSize();
-}
+        return adj;
+    }
 
 
-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));
+    bool
+    Adl::isAdlEqual(Adl &adl)
+    {
+        if ( getAdlSize() != adl.getAdlSize() )
+        {
+            return false;
+        }
 
-	if( it == adjList.end()){
-		return -1;
-	}
+        adjList.sort(adjacent_compare);
+        adl.getAdjList().sort(adjacent_compare);
+        int equalAdjCount=0;
 
-	(*it).setLinkCost(lc);
-	return 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++;
+        }
 
-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));
+        return equalAdjCount==getAdlSize();
+    }
 
-	if( it == adjList.end()){
-		return false;
-	}
 
-	return true;
-}
+    int
+    Adl::updateAdjacentLinkCost(string adjName, double lc)
+    {
+        Adjacent adj(adjName);
 
-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));
+        std::list<Adjacent >::iterator it = std::find_if( adjList.begin(),
+                                            adjList.end(),
+                                            bind(&adjacent_compare, _1, adj));
 
-	if( it == adjList.end()){
-		return ;
-	}
+        if( it == adjList.end())
+        {
+            return -1;
+        }
 
-	(*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
+        (*it).setLinkCost(lc);
+        return 0;
 
-}
+    }
 
-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));
+    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()){
-		(*it).setInterestTimedOutNo(count);
-	}
-}
+        if( it == adjList.end())
+        {
+            return false;
+        }
 
-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));
+        return true;
+    }
 
-	if( it == adjList.end()){
-		return -1;
-	}
+    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));
 
-	return (*it).getInterestTimedOutNo();
-}
+        if( it == adjList.end())
+        {
+            return ;
+        }
 
-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));
+        (*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
 
-	if( it == adjList.end()){
-		return -1;
-	}
+    }
 
-	return (*it).getStatus();
-}
+    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));
 
-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).setInterestTimedOutNo(count);
+        }
+    }
 
-	if( it != adjList.end()){
-		(*it).setStatus(status);
-	}
-}
+    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));
 
-std::list<Adjacent>& 
-Adl::getAdjList(){
-	return adjList;
-}
+        if( it == adjList.end())
+        {
+            return -1;
+        }
 
-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++;
-			}
-		} 
-	}
+        return (*it).getInterestTimedOutNo();
+    }
 
-	if( nbrCount == adjList.size())
-	{
-		return true;
-	}
+    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));
 
-	return false;
-}
+        if( it == adjList.end())
+        {
+            return -1;
+        }
 
-int 
-Adl::getNumOfActiveNeighbor()
-{
-	int actNbrCount=0;
-	for( std::list<Adjacent>::iterator it=adjList.begin(); 
-	                                                   it!= adjList.end() ; it++)
-	{
-		if ( ((*it).getStatus() == 1 ) )
-		{
-			actNbrCount++;
-		}
-	}
+        return (*it).getStatus();
+    }
 
-	return actNbrCount;
-}
+    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;
+    }
 
 // used for debugging purpose
-void
-Adl::printAdl(){
-	for( std::list<Adjacent>::iterator it=adjList.begin(); it!= adjList.end() ; it++){
-		cout<< (*it) <<endl;
-	}
-}
+    void
+    Adl::printAdl()
+    {
+        for( std::list<Adjacent>::iterator it=adjList.begin(); it!= adjList.end() ;
+                it++)
+        {
+            cout<< (*it) <<endl;
+        }
+    }
 
 } //namespace nlsr
diff --git a/src/nlsr_adl.hpp b/src/nlsr_adl.hpp
index 0169a5f..4c44993 100644
--- a/src/nlsr_adl.hpp
+++ b/src/nlsr_adl.hpp
@@ -5,53 +5,55 @@
 #include "nlsr_adjacent.hpp"
 #include<list>
 
-namespace nlsr {
+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);
+    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 isAdjLsaBuildable(Nlsr& pnlsr);
+        int getNumOfActiveNeighbor();
+        Adjacent getAdjacent(string adjName);
 
-	bool isAdlEqual(Adl &adl);
+        bool isAdlEqual(Adl &adl);
 
-	int getAdlSize()
-	{
-		return adjList.size();
-	}
+        int getAdlSize()
+        {
+            return adjList.size();
+        }
 
-	void resetAdl()
-	{
-		if( adjList.size() > 0 )
-		{
-			adjList.clear();
-		}
-	}
+        void resetAdl()
+        {
+            if( adjList.size() > 0 )
+            {
+                adjList.clear();
+            }
+        }
 
-	void printAdl();
+        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 1e2fc64..d307b83 100644
--- a/src/nlsr_conf_param.cpp
+++ b/src/nlsr_conf_param.cpp
@@ -1,31 +1,33 @@
 #include<iostream>
 #include "nlsr_conf_param.hpp"
 
-namespace nlsr {
+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;
+    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;
-}
+        return os;
+    }
 
 } //namespace nlsr
diff --git a/src/nlsr_conf_param.hpp b/src/nlsr_conf_param.hpp
index 941dbe7..61b7e42 100644
--- a/src/nlsr_conf_param.hpp
+++ b/src/nlsr_conf_param.hpp
@@ -3,210 +3,248 @@
 
 #include<iostream>
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-class ConfParameter{
-	
-public:
-	ConfParameter()
-		:chronosyncSyncPrefix("ndn/nlsr/sync")
-		,chronosyncLsaPrefix("/ndn/nlsr/LSA")
-		{
-      isStrictHierchicalKeyCheck=0;
+    class ConfParameter
+    {
 
-			interestRetryNumber=3;
-			interestResendTime=5;
-			infoInterestInterval=60;
-			lsaRefreshTime=1800;
-			routerDeadInterval=3600;
-			maxFacesPerPrefix=0;
-			tunnelType=0;
-			detailedLogging=0;
-      debugging=0;
-			isHyperbolicCalc=0;	
-		}
+    public:
+        ConfParameter()
+            :chronosyncSyncPrefix("ndn/nlsr/sync")
+            ,chronosyncLsaPrefix("/ndn/nlsr/LSA")
+        {
+            isStrictHierchicalKeyCheck=0;
 
-		void setRouterName(const string& rn){  
-			routerName=rn;
-		}
+            interestRetryNumber=3;
+            interestResendTime=5;
+            infoInterestInterval=60;
+            lsaRefreshTime=1800;
+            routerDeadInterval=3600;
+            maxFacesPerPrefix=0;
+            tunnelType=0;
+            detailedLogging=0;
+            debugging=0;
+            isHyperbolicCalc=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 getRouterPrefix(){
-			return routerPrefix;
-		}
+        string getNetwork()
+        {
+            return network;
+        }
 
-		void setInterestRetryNumber(int irn){
-			interestRetryNumber=irn;
-		}
+        void buildRouterPrefix()
+        {
+            routerPrefix="/"+network+"/"+siteName+"/"+routerName;
+        }
 
-		int getInterestRetryNumber(){
-			return interestRetryNumber;
-		}
+        string getRouterPrefix()
+        {
+            return routerPrefix;
+        }
 
-		void setInterestResendTime(int irt){
-			interestResendTime=irt;
-		}
+        void setInterestRetryNumber(int irn)
+        {
+            interestRetryNumber=irn;
+        }
 
-		int getInterestResendTime(){
-			return interestResendTime;
-		}
+        int getInterestRetryNumber()
+        {
+            return interestRetryNumber;
+        }
 
-		void setLsaRefreshTime(int lrt){
-			lsaRefreshTime=lrt;
-			routerDeadInterval=2*lsaRefreshTime;
-		}
+        void setInterestResendTime(int irt)
+        {
+            interestResendTime=irt;
+        }
 
-		int getLsaRefreshTime(){
-			return lsaRefreshTime;
-		}
+        int getInterestResendTime()
+        {
+            return interestResendTime;
+        }
 
-		void setRouterDeadInterval(int rdt){
-			routerDeadInterval=rdt;
-		}
+        void setLsaRefreshTime(int lrt)
+        {
+            lsaRefreshTime=lrt;
+            routerDeadInterval=2*lsaRefreshTime;
+        }
 
-		long int getRouterDeadInterval(){
-			return routerDeadInterval;
-		}
+        int getLsaRefreshTime()
+        {
+            return lsaRefreshTime;
+        }
 
-		void setMaxFacesPerPrefix(int mfpp){
-			maxFacesPerPrefix=mfpp;
-		}
+        void setRouterDeadInterval(int rdt)
+        {
+            routerDeadInterval=rdt;
+        }
 
-		int getMaxFacesPerPrefix(){
-			return maxFacesPerPrefix;
-		}
+        long int getRouterDeadInterval()
+        {
+            return routerDeadInterval;
+        }
 
-		void setLogDir(string ld){
-			logDir=ld;
-		}
-		
-		string getLogDir(){
-			return logDir;
-		}
+        void setMaxFacesPerPrefix(int mfpp)
+        {
+            maxFacesPerPrefix=mfpp;
+        }
 
-		void setDetailedLogging(int dl){
-			detailedLogging=dl;		
-		}
+        int getMaxFacesPerPrefix()
+        {
+            return maxFacesPerPrefix;
+        }
 
-		int getDetailedLogging(){
-			return detailedLogging;
-		}
+        void setLogDir(string ld)
+        {
+            logDir=ld;
+        }
 
-		void setDebugging(int d){
-			debugging=d;
-		}
-		
-		int getDebugging(){
-			return debugging;
-		}
+        string getLogDir()
+        {
+            return logDir;
+        }
 
-		void setIsHyperbolicCalc(int ihc){
-			isHyperbolicCalc=ihc;
-		}
+        void setDetailedLogging(int dl)
+        {
+            detailedLogging=dl;
+        }
 
-		int getIsHyperbolicCalc(){
-			return isHyperbolicCalc;
-		}
+        int getDetailedLogging()
+        {
+            return detailedLogging;
+        }
 
-		void setCorR(double cr){
-			corR=cr;
-		}
+        void setDebugging(int d)
+        {
+            debugging=d;
+        }
 
-		double getCorR(){
-			return corR;
-		}
+        int getDebugging()
+        {
+            return debugging;
+        }
 
-		void setCorTheta(double ct){
-			corTheta=ct;
-		}
+        void setIsHyperbolicCalc(int ihc)
+        {
+            isHyperbolicCalc=ihc;
+        }
 
-		double getCorTheta(){
-			return corTheta;
-		}
+        int getIsHyperbolicCalc()
+        {
+            return isHyperbolicCalc;
+        }
 
-		void setTunnelType(int tt){
-			tunnelType=tt;
-		}
+        void setCorR(double cr)
+        {
+            corR=cr;
+        }
 
-		int getTunnelType(){
-			return tunnelType;
-		}
+        double getCorR()
+        {
+            return corR;
+        }
 
-		void setChronosyncSyncPrefix(const string& csp){
-			chronosyncSyncPrefix=csp;
-		} 
+        void setCorTheta(double ct)
+        {
+            corTheta=ct;
+        }
 
-		string getChronosyncSyncPrefix(){
-			return chronosyncSyncPrefix;
-		}
+        double getCorTheta()
+        {
+            return corTheta;
+        }
 
-		int getInfoInterestInterval(){
-			return infoInterestInterval;
-		}
+        void setTunnelType(int tt)
+        {
+            tunnelType=tt;
+        }
 
-		void setInfoInterestInterval(int iii){
-			infoInterestInterval=iii;
-		}
+        int getTunnelType()
+        {
+            return tunnelType;
+        }
 
-private:
-	string routerName;
-	string siteName;
-	string network;
+        void setChronosyncSyncPrefix(const string& csp)
+        {
+            chronosyncSyncPrefix=csp;
+        }
 
-	string routerPrefix;
-	string lsaRouterPrefix;
+        string getChronosyncSyncPrefix()
+        {
+            return chronosyncSyncPrefix;
+        }
 
-	string chronosyncSyncPrefix;
-	string chronosyncLsaPrefix;             
+        int getInfoInterestInterval()
+        {
+            return infoInterestInterval;
+        }
 
-	int interestRetryNumber;
-	int interestResendTime;
-	int infoInterestInterval;
-	int lsaRefreshTime;
-	int routerDeadInterval;
-        
-	int maxFacesPerPrefix;
-	string logDir;
-	string logFile;
-	int detailedLogging;
-	int debugging;
+        void setInfoInterestInterval(int iii)
+        {
+            infoInterestInterval=iii;
+        }
 
-	int isHyperbolicCalc;
-	double corR;
-	double corTheta;
+    private:
+        string routerName;
+        string siteName;
+        string network;
 
-	int tunnelType;
-	int isStrictHierchicalKeyCheck;
+        string routerPrefix;
+        string lsaRouterPrefix;
 
-};
+        string chronosyncSyncPrefix;
+        string chronosyncLsaPrefix;
 
-std::ostream&
-operator << (std::ostream &os, ConfParameter &cfp);
+        int interestRetryNumber;
+        int interestResendTime;
+        int infoInterestInterval;
+        int lsaRefreshTime;
+        int routerDeadInterval;
+
+        int maxFacesPerPrefix;
+        string logDir;
+        string logFile;
+        int detailedLogging;
+        int debugging;
+
+        int isHyperbolicCalc;
+        double corR;
+        double corTheta;
+
+        int tunnelType;
+        int isStrictHierchicalKeyCheck;
+
+    };
+
+    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 e25192e..8fc7419 100644
--- a/src/nlsr_conf_processor.cpp
+++ b/src/nlsr_conf_processor.cpp
@@ -10,380 +10,511 @@
 #include "nlsr_adjacent.hpp"
 
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-int 
-ConfFileProcessor::processConfFile(Nlsr& pnlsr){
-	int ret=0;
+    int
+    ConfFileProcessor::processConfFile(Nlsr& pnlsr)
+    {
+        int ret=0;
 
-	if ( !confFileName.empty()){
-		std::ifstream inputFile(confFileName.c_str());
-		if ( inputFile.is_open()){
-			for( string line; getline( inputFile, line ); ){
-    				if (!line.empty() ){
-					if(line[0]!= '#' && line[0]!='!'){
-						ret=processConfCommand(pnlsr, line);	
-						if( ret == -1 ){
-							break;
-						}
-					}
-				}
-			}
-		}
-		else{
-			std::cerr <<"Configuration file: ("<<confFileName<<") does not exist :(";
-			std::cerr <<endl;
-			ret=-1;
-		}
-	}
+        if ( !confFileName.empty())
+        {
+            std::ifstream inputFile(confFileName.c_str());
+            if ( inputFile.is_open())
+            {
+                for( string line; getline( inputFile, line ); )
+                {
+                    if (!line.empty() )
+                    {
+                        if(line[0]!= '#' && line[0]!='!')
+                        {
+                            ret=processConfCommand(pnlsr, line);
+                            if( ret == -1 )
+                            {
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                std::cerr <<"Configuration file: ("<<confFileName<<") does not exist :(";
+                std::cerr <<endl;
+                ret=-1;
+            }
+        }
 
-	return ret;
-}
-
-
-int 
-ConfFileProcessor::processConfCommand(Nlsr& pnlsr, string command){
-	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() == "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() == "logdir")){
-    		processConfCommandLogDir(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;
     }
 
-	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::processConfCommand(Nlsr& pnlsr, string command)
+    {
+        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() == "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() == "logdir"))
+        {
+            processConfCommandLogDir(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;
+        }
 
-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;
-}
+        return ret;
+    }
 
-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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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;
-}
+    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;
+    }
 
 } //namespace nlsr
 
diff --git a/src/nlsr_conf_processor.hpp b/src/nlsr_conf_processor.hpp
index 5568010..c49e3c2 100644
--- a/src/nlsr_conf_processor.hpp
+++ b/src/nlsr_conf_processor.hpp
@@ -1,49 +1,52 @@
 #ifndef CONF_PROCESSOR_HPP
 #define CONF_PROCESSOR_HPP
 
-#include "nlsr.hpp" 
+#include "nlsr.hpp"
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-class ConfFileProcessor{
-	public:
-		ConfFileProcessor()
-			:confFileName()
-		{
-		}
-		ConfFileProcessor(const string& cfile){ 
-			confFileName=cfile;
-		}
+    class ConfFileProcessor
+    {
+    public:
+        ConfFileProcessor()
+            :confFileName()
+        {
+        }
+        ConfFileProcessor(const string& cfile)
+        {
+            confFileName=cfile;
+        }
 
-		int processConfFile(Nlsr& pnlsr);
-		int processConfCommand(Nlsr& pnlsr, string command);
-		int processConfCommandNetwork(Nlsr& pnlsr, string command);
-		int processConfCommandSiteName(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 processConfCommand(Nlsr& pnlsr, string command);
+        int processConfCommandNetwork(Nlsr& pnlsr, string command);
+        int processConfCommandSiteName(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 processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
-		int processConfCommandLogDir(Nlsr& pnlsr, string command);
-		int processConfCommandDebugging(Nlsr& pnlsr, string command);
-		int processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
-		int processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
+        int processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
+        int processConfCommandLogDir(Nlsr& pnlsr, string command);
+        int processConfCommandDebugging(Nlsr& pnlsr, string command);
+        int processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
+        int processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
 
-		int processConfCommandHyperbolicCordinate(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);
-		
+        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_dm.cpp b/src/nlsr_dm.cpp
index 1f3beab..8252423 100644
--- a/src/nlsr_dm.cpp
+++ b/src/nlsr_dm.cpp
@@ -6,76 +6,78 @@
 #include "nlsr_tokenizer.hpp"
 #include "nlsr_lsdb.hpp"
 
-namespace nlsr {
-
-using namespace std;
-using namespace ndn;
-
-void
-DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
-								               const ndn::Data & data)
+namespace nlsr
 {
 
-	cout << "I: " << interest.toUri() << endl;
+    using namespace std;
+    using namespace ndn;
 
-	string dataName(data.getName().toUri());
-	string dataContent((char *)data.getContent().value());
-	
-  	cout << "D: " << dataName << endl;
-	cout << "Data Content: " << dataContent << endl;
+    void
+    DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                                const ndn::Data & data)
+    {
 
-	nlsrTokenizer nt(dataName,"/");
-	string chkString("info");
-	if( nt.doesTokenExist(chkString) ){
-		processContentInfo(pnlsr,dataName,dataContent);
-	}
+        cout << "I: " << interest.toUri() << endl;
 
-}
+        string dataName(data.getName().toUri());
+        string dataContent((char *)data.getContent().value());
 
-void
-DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
-                                                           string& dataContent)
-{
-	nlsrTokenizer nt(dataName,"/");
-	string chkString("info");
-	string neighbor="/" + nt.getFirstToken()
-							+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
+        cout << "D: " << dataName << endl;
+        cout << "Data Content: " << dataContent << endl;
 
-	pnlsr.getAdl().setStatusOfNeighbor(neighbor,1);
-	pnlsr.getAdl().setTimedOutInterestCount(neighbor,0);
+        nlsrTokenizer nt(dataName,"/");
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            processContentInfo(pnlsr,dataName,dataContent);
+        }
 
-	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
+    void
+    DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
+                                    string& dataContent)
+    {
+        nlsrTokenizer nt(dataName,"/");
+        string chkString("info");
+        string neighbor="/" + nt.getFirstToken()
+                        +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
 
-	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.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)));
+            }
+
+        }
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_dm.hpp b/src/nlsr_dm.hpp
index 2a8958b..64b9006 100644
--- a/src/nlsr_dm.hpp
+++ b/src/nlsr_dm.hpp
@@ -5,23 +5,24 @@
 #include <ndn-cpp-dev/security/key-chain.hpp>
 #include <ndn-cpp-dev/util/scheduler.hpp>
 
-namespace nlsr {
-
-using namespace ndn;
-using namespace std;
-
-class Nlsr;
-
-class DataManager
+namespace nlsr
 {
-public:
-  void processContent(Nlsr& pnlsr, const ndn::Interest &interest,
-								               const ndn::Data& data);
-	void processContentInfo(Nlsr& pnlsr, string& dataName,
-                                                           string& dataContent);
-private:
-  
-};
+
+    using namespace ndn;
+    using namespace std;
+
+    class Nlsr;
+
+    class DataManager
+    {
+    public:
+        void processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                            const ndn::Data& data);
+        void processContentInfo(Nlsr& pnlsr, string& dataName,
+                                string& dataContent);
+    private:
+
+    };
 
 }//namespace nlsr
 #endif
diff --git a/src/nlsr_fe.cpp b/src/nlsr_fe.cpp
index bbffd96..f0f9d06 100644
--- a/src/nlsr_fe.cpp
+++ b/src/nlsr_fe.cpp
@@ -2,48 +2,49 @@
 #include "nlsr_fe.hpp"
 #include "nlsr_nexthop.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-bool 
-FibEntry::isEqualNextHops(Nhl &nhlOther)
+namespace nlsr
 {
-	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() )
-			{
-				(*it1).setRouteCost((*it2).getRouteCost());
-				nhCount++;
-			}
-			else
-			{
-				break;
-			}
-		}
+    using namespace std;
 
-		return nhCount == nhl.getNhlSize();
-	}
-}
+    bool
+    FibEntry::isEqualNextHops(Nhl &nhlOther)
+    {
+        if ( nhl.getNhlSize() != nhlOther.getNhlSize() )
+        {
+            return false;
+        }
+        else
+        {
+            int nhCount=0;
+            std::list<NextHop>::iterator it1, it2;
 
-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;
-}
+            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();
+        }
+    }
+
+    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/nlsr_fe.hpp b/src/nlsr_fe.hpp
index fde32c8..c85e045 100644
--- a/src/nlsr_fe.hpp
+++ b/src/nlsr_fe.hpp
@@ -8,76 +8,77 @@
 #include "nlsr_nexthop.hpp"
 #include "nlsr_nhl.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-class FibEntry
+namespace nlsr
 {
-public:
-	FibEntry()
-		: name()
-		, timeToRefresh(0)
-		, feSeqNo(0)
-	{
-	}
 
-	FibEntry(string n)
-	{
-		name=n;
-	}	
+    using namespace std;
 
-	string getName()
-	{
-		return name;
-	}
+    class FibEntry
+    {
+    public:
+        FibEntry()
+            : name()
+            , timeToRefresh(0)
+            , feSeqNo(0)
+        {
+        }
 
-	Nhl& getNhl()
-	{
-		return nhl;
-	}
+        FibEntry(string n)
+        {
+            name=n;
+        }
 
-	int getTimeToRefresh()
-	{
-		return timeToRefresh;
-	}
+        string getName()
+        {
+            return name;
+        }
 
-	void setTimeToRefresh(int ttr)
-	{
-		timeToRefresh=ttr;
-	}
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
 
-	void setFeExpiringEventId(ndn::EventId feid)
-	{
-		feExpiringEventId=feid;
-	}
+        int getTimeToRefresh()
+        {
+            return timeToRefresh;
+        }
 
-	ndn::EventId getFeExpiringEventId()
-	{
-		return feExpiringEventId;
-	}
+        void setTimeToRefresh(int ttr)
+        {
+            timeToRefresh=ttr;
+        }
 
-	void setFeSeqNo(int fsn)
-	{
-		feSeqNo=fsn;
-	}
+        void setFeExpiringEventId(ndn::EventId feid)
+        {
+            feExpiringEventId=feid;
+        }
 
-	int getFeSeqNo()
-	{
-		return feSeqNo;
-	}	
+        ndn::EventId getFeExpiringEventId()
+        {
+            return feExpiringEventId;
+        }
 
-	bool isEqualNextHops(Nhl &nhlOther);
-	
-private:
-	string name;
-	int timeToRefresh;
-	ndn::EventId feExpiringEventId;
-	int feSeqNo;
-	Nhl nhl;
-};
+        void setFeSeqNo(int fsn)
+        {
+            feSeqNo=fsn;
+        }
 
-ostream& operator<<(ostream& os, FibEntry& fe);
+        int getFeSeqNo()
+        {
+            return feSeqNo;
+        }
+
+        bool isEqualNextHops(Nhl &nhlOther);
+
+    private:
+        string name;
+        int timeToRefresh;
+        ndn::EventId feExpiringEventId;
+        int feSeqNo;
+        Nhl nhl;
+    };
+
+    ostream& operator<<(ostream& os, FibEntry& fe);
 
 } //namespace nlsr
 
diff --git a/src/nlsr_fib.cpp b/src/nlsr_fib.cpp
index 54b6834..4ff49b2 100644
--- a/src/nlsr_fib.cpp
+++ b/src/nlsr_fib.cpp
@@ -4,169 +4,171 @@
 #include "nlsr_nhl.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
-
-using namespace std;
-using namespace ndn;
-
-static bool
-fibEntryNameCompare(FibEntry& fe, string name)
+namespace nlsr
 {
-	return fe.getName() == name ;
-}
 
-void 
-Fib::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
-{
-	pnlsr.getScheduler().cancelEvent(eid);
-}
+    using namespace std;
+    using namespace ndn;
+
+    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));
-}
+    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::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() )
-  {
-  		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::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() )
+        {
+            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::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
-{
-	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() )
-  {
-  		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));
-  			}
+    void
+    Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        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() )
+        {
+            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
-  }
-  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);	
+                (*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
+        }
+        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
-  }
-}
+            //cancelScheduledFeExpiringEvent(pnlsr, newEntry().getFeExpiringEventId());
+
+            //Update NDN-FIB
+        }
+    }
 
 
 
-void Fib::cleanFib(Nlsr& pnlsr)
-{
-	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
-  		}
-	}
+    void Fib::cleanFib(Nlsr& pnlsr)
+    {
+        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();
-	}
-}
+        if ( fibTable.size() > 0 )
+        {
+            fibTable.clear();
+        }
+    }
 
 
-void 
-Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
-{
-	for( std::list<NextHop >::iterator it=nl.getNextHopList().begin(); 
-	                                      it != nl.getNextHopList().end();   ++it)
-	{
-		if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
-		{
-			nl.getNextHopList().erase(it);
-		}
-	}
-}
+    void
+    Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
+    {
+        for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
+                it != nl.getNextHopList().end();   ++it)
+        {
+            if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
+            {
+                nl.getNextHopList().erase(it);
+            }
+        }
+    }
 
 
-int 
-Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
-{
-	int endFace=0;
-  	if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
-  	{
-  		return nextHopList.getNhlSize();
-  	}
-  	else
-  	{
-  		return maxFacesPerPrefix;
-  	}
+    int
+    Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        int endFace=0;
+        if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
+        {
+            return nextHopList.getNhlSize();
+        }
+        else
+        {
+            return maxFacesPerPrefix;
+        }
 
-  	return endFace;
-}
+        return endFace;
+    }
 
-void
-Fib::printFib()
-{
-	cout<<"-------------------FIB-----------------------------"<<endl;
-	for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
-	                                                                         ++it)
-	{
-		cout<<(*it);
-	}
-}
+    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/nlsr_fib.hpp b/src/nlsr_fib.hpp
index 99fd845..d93d972 100644
--- a/src/nlsr_fib.hpp
+++ b/src/nlsr_fib.hpp
@@ -4,42 +4,45 @@
 #include <list>
 #include "nlsr_fe.hpp"
 
-namespace nlsr {
-
-class Nlsr;
-
-using namespace std;
-using namespace ndn;
-
-class Fib
+namespace nlsr
 {
-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 printFib();
+    class Nlsr;
 
-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:
-	std::list<FibEntry> fibTable;	
-	int fibEntryRefreshTime;
-};
+    using namespace std;
+    using namespace ndn;
+
+    class Fib
+    {
+    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 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:
+        std::list<FibEntry> fibTable;
+        int fibEntryRefreshTime;
+    };
 
 }//namespace nlsr
 #endif
diff --git a/src/nlsr_im.cpp b/src/nlsr_im.cpp
index 4e77f39..29c0fcd 100644
--- a/src/nlsr_im.cpp
+++ b/src/nlsr_im.cpp
@@ -9,150 +9,154 @@
 #include "nlsr_tokenizer.hpp"
 #include "nlsr_lsdb.hpp"
 
-namespace nlsr {
-
-using namespace std;
-using namespace ndn;
-
-void 
-interestManager::processInterest( Nlsr& pnlsr,
-                                  const ndn::Name &name, 
-                                  const ndn::Interest &interest)
+namespace nlsr
 {
 
-	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);
-	}
-	
-  //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);
-}
+    using namespace std;
+    using namespace ndn;
 
-void 
-interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
-							                                    const ndn::Interest &interest)
-{
-	if ( pnlsr.getAdl().isNeighbor(neighbor) )
-	{
-		Data data(ndn::Name(interest.getName()).appendVersion());
-  		data.setFreshnessPeriod(1000); // 10 sec
-  		data.setContent((const uint8_t*)"info", sizeof("info"));
-  		pnlsr.getKeyChain().sign(data);
-  		cout << ">> D: " << data << endl;
-  		pnlsr.getNlsrFace().put(data);
+    void
+    interestManager::processInterest( Nlsr& pnlsr,
+                                      const ndn::Name &name,
+                                      const ndn::Interest &interest)
+    {
 
-  		int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
-  		if ( status == 0 )
-  		{
-			string intName=neighbor +"/"+"info"+
-                                     pnlsr.getConfParameter().getRouterPrefix();
-    		expressInterest(	pnlsr,intName,2,
-                              pnlsr.getConfParameter().getInterestResendTime());
-  		}
-	}
-}
+        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);
+        }
 
-void 
-interestManager::processInterestTimedOut(Nlsr& pnlsr,
-                                                  const ndn::Interest &interest)
-{
-  	cout << "Timed out interest : " << interest.getName().toUri() << endl;
-	string intName=	interest.getName().toUri();
-	nlsrTokenizer nt(intName,"/");
-	string chkString("info");
-	if( nt.doesTokenExist(chkString) ){
-		string nbr="/" + nt.getFirstToken()
-							+nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
-		processInterestTimedOutInfo( pnlsr , nbr , interest);
-	}
+        //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
+        //data.setFreshnessPeriod(1000); // 10 sec
+        //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
+        //pnlsr.getKeyChain().sign(data);
+        //cout << ">> D: " << data << endl;
+        //pnlsr.getNlsrFace().put(data);
+    }
 
-}
+    void
+    interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                         const ndn::Interest &interest)
+    {
+        if ( pnlsr.getAdl().isNeighbor(neighbor) )
+        {
+            Data data(ndn::Name(interest.getName()).appendVersion());
+            data.setFreshnessPeriod(1000); // 10 sec
+            data.setContent((const uint8_t*)"info", sizeof("info"));
+            pnlsr.getKeyChain().sign(data);
+            cout << ">> D: " << data << endl;
+            pnlsr.getNlsrFace().put(data);
 
-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;
+            int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+            if ( status == 0 )
+            {
+                string intName=neighbor +"/"+"info"+
+                               pnlsr.getConfParameter().getRouterPrefix();
+                expressInterest(	pnlsr,intName,2,
+                                    pnlsr.getConfParameter().getInterestResendTime());
+            }
+        }
+    }
 
-	if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
-	{
-		string intName=neighbor +"/"+"info"+
-                                     pnlsr.getConfParameter().getRouterPrefix();
-    expressInterest(	pnlsr,intName,2,
-                              pnlsr.getConfParameter().getInterestResendTime());
-	}
-	else if ( (status == 1) && 
-	  (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
-	{
-		pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
-		pnlsr.incrementAdjBuildCount();
-		if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
-		{
-			pnlsr.setIsBuildAdjLsaSheduled(1);
-			// event here
-			pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
-							ndn::bind(&Lsdb::scheduledAdjLsaBuild,pnlsr.getLsdb(), 
-																									boost::ref(pnlsr)));
-		}
-	}
-	
-}
+    void
+    interestManager::processInterestTimedOut(Nlsr& pnlsr,
+            const ndn::Interest &interest)
+    {
+        cout << "Timed out interest : " << interest.getName().toUri() << endl;
+        string intName=	interest.getName().toUri();
+        nlsrTokenizer nt(intName,"/");
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string nbr="/" + nt.getFirstToken()
+                       +nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+            processInterestTimedOutInfo( pnlsr , nbr , interest);
+        }
 
-void 
-interestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix, 
-                                  											int scope, int seconds)
-{
-	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),
-                  ndn::func_lib::bind(&interestManager::processInterestTimedOut,
+    void
+    interestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+            const ndn::Interest &interest)
+    {
+        pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
+        int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        cout<<"Neighbor: "<< neighbor << endl;
+        cout<<"Status: "<< status << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+
+        if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
+        {
+            string intName=neighbor +"/"+"info"+
+                           pnlsr.getConfParameter().getRouterPrefix();
+            expressInterest(	pnlsr,intName,2,
+                                pnlsr.getConfParameter().getInterestResendTime());
+        }
+        else if ( (status == 1) &&
+                  (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
+        {
+            pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
+            pnlsr.incrementAdjBuildCount();
+            if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+            {
+                pnlsr.setIsBuildAdjLsaSheduled(1);
+                // event here
+                pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                                   ndn::bind(&Lsdb::scheduledAdjLsaBuild,pnlsr.getLsdb(),
+                                                           boost::ref(pnlsr)));
+            }
+        }
+
+    }
+
+    void
+    interestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
+                                     int scope, int seconds)
+    {
+        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),
+                                            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());
-	}
+    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());
+        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));
-}
+    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/nlsr_im.hpp b/src/nlsr_im.hpp
index 6c09eb0..ccfe78f 100644
--- a/src/nlsr_im.hpp
+++ b/src/nlsr_im.hpp
@@ -5,34 +5,36 @@
 #include <ndn-cpp-dev/security/key-chain.hpp>
 #include <ndn-cpp-dev/util/scheduler.hpp>
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace ndn;
-using namespace std;
+    using namespace ndn;
+    using namespace std;
 
-class Nlsr;
+    class Nlsr;
 
-class interestManager{
-public:	
-	interestManager()
-	{
-	}
-  void processInterest(Nlsr& pnlsr, const ndn::Name &name, 
-							                                   const ndn::Interest &interest);
-	void processInterestInfo(Nlsr& pnlsr, string& neighbor, 
-							                                   const ndn::Interest &interest);
-  void processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest &interest);
-  void processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
-                                                 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);
+    class interestManager
+    {
+    public:
+        interestManager()
+        {
+        }
+        void processInterest(Nlsr& pnlsr, const ndn::Name &name,
+                             const ndn::Interest &interest);
+        void processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                 const ndn::Interest &interest);
+        void processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest &interest);
+        void processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+                                         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/nlsr_logger.cpp b/src/nlsr_logger.cpp
index 0f003a0..5b97ac4 100644
--- a/src/nlsr_logger.cpp
+++ b/src/nlsr_logger.cpp
@@ -1,63 +1,63 @@
 #include "nlsr_logger.hpp"
 
-namespace nlsr {
-
-string 
-NlsrLogger::getEpochTime()
+namespace nlsr
 {
-	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 homeDirPath(getpwuid(getuid())->pw_dir);
-	if( homeDirPath.empty() )
-	{
-		homeDirPath = getenv("HOME");
-	}
+    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();
+    }
 
-	return homeDirPath;
-}
+    string
+    NlsrLogger::getUserHomeDirectory()
+    {
+        string homeDirPath(getpwuid(getuid())->pw_dir);
+        if( homeDirPath.empty() )
+        {
+            homeDirPath = getenv("HOME");
+        }
 
-void 
-NlsrLogger::initNlsrLogger(std::string dirPath)
-{
-	string logDirPath(dirPath);
-	if( dirPath.empty() )
-	{
-		logDirPath=getUserHomeDirectory()+"/nlsrLog";
-	}
-	cout<<"Log Dir Path: "<< logDirPath<<endl;
+        return homeDirPath;
+    }
 
-	//Create a text file sink
-	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", // file name pattern
-		keywords::rotation_size = 128 * 1024 * 1024 ,         // rotation size, in characters
-		keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0),
-		keywords::auto_flush = true 
-		));
-	//Set up where the rotated files will be stored
-	sink->locked_backend()->set_file_collector(sinks::file::make_collector(
-		keywords::target = logDirPath,                // where to store rotated files
-		keywords::max_size = 16 * 1024 * 1024 * 1024, // maximum total size of the stored files, in bytes
-		keywords::min_free_space = 128 * 1024 * 1024  // minimum free space on the drive, in bytes
-		));
+    void
+    NlsrLogger::initNlsrLogger(std::string dirPath)
+    {
+        string logDirPath(dirPath);
+        if( dirPath.empty() )
+        {
+            logDirPath=getUserHomeDirectory()+"/nlsrLog";
+        }
+        cout<<"Log Dir Path: "<< logDirPath<<endl;
 
-	sink->set_formatter(
-		expr::format("%1%: %2%")
-				% getEpochTime()
-				% expr::smessage
-		);
+        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
+                ));
 
-	// Add it to the core
-	logging::core::get()->add_sink(sink);
-}
+        sink->set_formatter(
+            expr::format("%1%: %2%")
+            % getEpochTime()
+            % expr::smessage
+        );
+
+        logging::core::get()->add_sink(sink);
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_logger.hpp b/src/nlsr_logger.hpp
index 74470e5..222ac52 100644
--- a/src/nlsr_logger.hpp
+++ b/src/nlsr_logger.hpp
@@ -22,40 +22,41 @@
 #include <boost/log/sinks/sync_frontend.hpp>
 #include <boost/log/sinks/text_file_backend.hpp>
 
-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;
-
-using boost::shared_ptr;
-using namespace std;
-
-
-class NlsrLogger
+namespace nlsr
 {
-public:
-	NlsrLogger()
-	{
-	}
 
-	void initNlsrLogger(std::string dirPath);
+    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;
 
-  src::logger& getLogger()
-	{
-		return mLogger;
-	}		
+    using boost::shared_ptr;
+    using namespace std;
 
-private:
-	string getEpochTime();
-	string getUserHomeDirectory();
 
-private:
-	src::logger mLogger;
-};
+    class NlsrLogger
+    {
+    public:
+        NlsrLogger()
+        {
+        }
+
+        void initNlsrLogger(std::string dirPath);
+
+        src::logger& getLogger()
+        {
+            return mLogger;
+        }
+
+    private:
+        string getEpochTime();
+        string getUserHomeDirectory();
+
+    private:
+        src::logger mLogger;
+    };
 
 }//namespace nlsr
 #endif
diff --git a/src/nlsr_lsa.cpp b/src/nlsr_lsa.cpp
index 9900069..5adb854 100644
--- a/src/nlsr_lsa.cpp
+++ b/src/nlsr_lsa.cpp
@@ -9,234 +9,236 @@
 #include "nlsr_adjacent.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-
-string
-NameLsa::getNameLsaKey()
+namespace nlsr
 {
-	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;
+    using namespace std;
 
-	std::list<string> nl=npl.getNameList();
-	for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-	{
-		addNameToLsa((*it));
-	}
 
-	
-}
+    string
+    NameLsa::getNameLsaKey()
+    {
+        string key;
+        key=origRouter + "/" + boost::lexical_cast<std::string>(1);
+        return key;
+    }
 
-string
-NameLsa::getNameLsaData()
-{
-	string nameLsaData;
-	nameLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|" 
-	    + boost::lexical_cast<std::string>(lsSeqNo) + "|" 
-	    + boost::lexical_cast<std::string>(lifeTime);
-	nameLsaData+="|";
-	nameLsaData+=boost::lexical_cast<std::string>(npl.getNplSize());
+    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++)
-	{
-		nameLsaData+="|";
-		nameLsaData+=(*it);
-	}
-	
-	return nameLsaData;
-}
+        std::list<string> nl=npl.getNameList();
+        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
+        {
+            addNameToLsa((*it));
+        }
 
-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++)
-	{
-		os<<"    Name "<<i<<": "<<(*it)<<endl;
-	}
 
-	return os;  
-}
+    }
+
+    string
+    NameLsa::getNameLsaData()
+    {
+        string nameLsaData;
+        nameLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|"
+                    + 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;
+    }
+
+    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++)
+        {
+            os<<"    Name "<<i<<": "<<(*it)<<endl;
+        }
+
+        return os;
+    }
 
 
 
-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;
-}
+    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;
-}
+    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());
-}
+    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>(lsType) + "|");
-	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) + "|");
+    string
+    CorLsa::getCorLsaData()
+    {
+        string corLsaData;
+        corLsaData=origRouter + "|";
+        corLsaData+=(boost::lexical_cast<std::string>(lsType) + "|");
+        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;
-}
+        return corLsaData;
+    }
 
-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;
+    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;
-}
+        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;
+    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++)
-	{
-		if((*it).getStatus()==1)
-		{
-				addAdjacentToLsa((*it));
-		}
-	}
-}
+        std::list<Adjacent> al=padl.getAdjList();
+        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
+        {
+            if((*it).getStatus()==1)
+            {
+                addAdjacentToLsa((*it));
+            }
+        }
+    }
 
-string
-AdjLsa::getAdjLsaKey()
-{
-	string key;
-	key=origRouter + "/" + boost::lexical_cast<std::string>(2);
-	return key;
-}
+    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());
-}
+    bool
+    AdjLsa::isLsaContentEqual(AdjLsa& alsa)
+    {
+        return adl.isAdlEqual(alsa.getAdl());
+    }
 
 
-string 
-AdjLsa::getAdjLsaData(){
-	string adjLsaData;
-	adjLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|" 
-	    + boost::lexical_cast<std::string>(lsSeqNo) + "|" 
-	    + boost::lexical_cast<std::string>(lifeTime);
-	adjLsaData+="|";
-	adjLsaData+=boost::lexical_cast<std::string>(adl.getAdlSize());
+    string
+    AdjLsa::getAdjLsaData()
+    {
+        string adjLsaData;
+        adjLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|"
+                   + 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;
-}
+        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;
+    }
 
 
-void 
-AdjLsa::addNptEntriesForAdjLsa(Nlsr& pnlsr)
-{
-	if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-	{
-		pnlsr.getNpt().addNpte(getOrigRouter(), getOrigRouter(),pnlsr);
-	}
+    void
+    AdjLsa::addNptEntriesForAdjLsa(Nlsr& pnlsr)
+    {
+        if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+        {
+            pnlsr.getNpt().addNpte(getOrigRouter(), getOrigRouter(),pnlsr);
+        }
 
-}
+    }
 
 
-void 
-AdjLsa::removeNptEntriesForAdjLsa(Nlsr& pnlsr)
-{
-	if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-	{
-		pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(),pnlsr);
-	}
-}
+    void
+    AdjLsa::removeNptEntriesForAdjLsa(Nlsr& pnlsr)
+    {
+        if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+        {
+            pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(),pnlsr);
+        }
+    }
 
 
 
-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<<"    Adjacent "<<i<<": "<<endl;
-		os<<"      Adjacent Name: "<<(*it).getAdjacentName()<<endl;
-		os<<"      Connecting Face: "<<(*it).getConnectingFace()<<endl;
-		os<<"      Link Cost: "<<(*it).getLinkCost()<<endl;
-	}
-	
-	return os;  
-}
+    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<<"    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 e7ab561..24bf73d 100644
--- a/src/nlsr_lsa.hpp
+++ b/src/nlsr_lsa.hpp
@@ -6,204 +6,212 @@
 #include "nlsr_npl.hpp"
 #include "nlsr_adl.hpp"
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
-using namespace ndn;
+    using namespace std;
+    using namespace ndn;
 
-class Lsa{
-public:
-	Lsa()
-		: origRouter()
-		, lsSeqNo()
-		, lifeTime()
-		, lsaExpiringEventId()
-	{
-	}	
+    class Lsa
+    {
+    public:
+        Lsa()
+            : origRouter()
+            , lsSeqNo()
+            , lifeTime()
+            , lsaExpiringEventId()
+        {
+        }
 
 
-	void setLsType(uint8_t lst)
-	{
-		lsType=lst;
-	}
+        void setLsType(uint8_t lst)
+        {
+            lsType=lst;
+        }
 
-	uint8_t getLsType()
-	{
-		return lsType;
-	}
+        uint8_t getLsType()
+        {
+            return lsType;
+        }
 
-	void setLsSeqNo(uint32_t lsn)
-	{
-		lsSeqNo=lsn;
-	}
+        void setLsSeqNo(uint32_t lsn)
+        {
+            lsSeqNo=lsn;
+        }
 
-	uint32_t getLsSeqNo()
-	{
-		return lsSeqNo;
-	}
+        uint32_t getLsSeqNo()
+        {
+            return lsSeqNo;
+        }
 
-	string& getOrigRouter()
-	{
-		return origRouter;
-	}
+        string& getOrigRouter()
+        {
+            return origRouter;
+        }
 
-	void setOrigRouter(string& org)
-	{
-		origRouter=org;
-	}
+        void setOrigRouter(string& org)
+        {
+            origRouter=org;
+        }
 
-	uint32_t getLifeTime()
-	{
-		return lifeTime;
-	}
+        uint32_t getLifeTime()
+        {
+            return lifeTime;
+        }
 
-	void setLifeTime(uint32_t lt)
-	{
-		lifeTime=lt;
-	}
+        void setLifeTime(uint32_t lt)
+        {
+            lifeTime=lt;
+        }
 
-	void setLsaExpiringEventId(ndn::EventId leei)
-	{
-		lsaExpiringEventId=leei;
-	}
+        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;
-};
+        ndn::EventId getLsaExpiringEventId()
+        {
+            return 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);
+    protected:
+        string origRouter;
+        uint8_t lsType;
+        uint32_t lsSeqNo;
+        uint32_t lifeTime;
+        ndn::EventId lsaExpiringEventId;
+    };
 
-	Npl& getNpl(){
-		return npl;
-	}
+    class NameLsa:public Lsa
+    {
+    public:
+        NameLsa()
+            : Lsa()
+            , npl()
+        {
+            setLsType(1);
+        }
 
-	void addNameToLsa(string& name)
-	{
-		npl.insertIntoNpl(name);
-	}
+        NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
 
-	void removeNameFromLsa(string& name)
-	{
-		npl.removeFromNpl(name);
-	}
+        Npl& getNpl()
+        {
+            return npl;
+        }
 
-	string getNameLsaKey();
+        void addNameToLsa(string& name)
+        {
+            npl.insertIntoNpl(name);
+        }
 
-	string getNameLsaData();
-	
-private:
-	Npl npl;
-	
-};
+        void removeNameFromLsa(string& name)
+        {
+            npl.removeFromNpl(name);
+        }
 
-std::ostream& 
-operator<<(std::ostream& os, NameLsa& nLsa);
+        string getNameLsaKey();
 
-class AdjLsa: public Lsa{
-public:
-	AdjLsa()
-		: Lsa()
-		, adl()
-	{
-		setLsType(2);
-	}
+        string getNameLsaData();
 
-	AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, 
-	                                                        uint32_t nl ,Adl padl);
-	Adl& getAdl(){
-		return adl;
-	}
+    private:
+        Npl npl;
 
-	void addAdjacentToLsa(Adjacent adj)
-	{
-		adl.insert(adj);
-	}
-	string getAdjLsaKey();
-	string getAdjLsaData();
-	uint32_t getNoLink()
-	{
-		return noLink;
-	}
+    };
 
-	bool isLsaContentEqual(AdjLsa& alsa);
-	void addNptEntriesForAdjLsa(Nlsr& pnlsr);
-	void removeNptEntriesForAdjLsa(Nlsr& pnlsr);
+    std::ostream&
+    operator<<(std::ostream& os, NameLsa& nLsa);
 
-private:
-	uint32_t noLink;
-	Adl adl;
-};
+    class AdjLsa: public Lsa
+    {
+    public:
+        AdjLsa()
+            : Lsa()
+            , adl()
+        {
+            setLsType(2);
+        }
 
-std::ostream& 
-operator<<(std::ostream& os, AdjLsa& aLsa);
+        AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
+               uint32_t nl ,Adl padl);
+        Adl& getAdl()
+        {
+            return adl;
+        }
 
-class CorLsa:public Lsa{
-public:
-	CorLsa()
-		:Lsa()
-	{
-		setLsType(3);
-	}
+        void addAdjacentToLsa(Adjacent adj)
+        {
+            adl.insert(adj);
+        }
+        string getAdjLsaKey();
+        string getAdjLsaData();
+        uint32_t getNoLink()
+        {
+            return noLink;
+        }
 
-	CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
-	      																							, double r, double theta);
-	string getCorLsaKey();
-	string getCorLsaData();
-	
-	double getCorRadius()
-	{
-		if ( corRad >= 0 )
-		{	
-			return corRad;
-		}
-		else 
-		{
-			return -1;
-		}
-	}
-	
-	void setCorRadius(double cr)
-	{
-		corRad=cr;
-	}
+        bool isLsaContentEqual(AdjLsa& alsa);
+        void addNptEntriesForAdjLsa(Nlsr& pnlsr);
+        void removeNptEntriesForAdjLsa(Nlsr& pnlsr);
 
-	double getCorTheta()
-	{
-		return corTheta;
-	}
+    private:
+        uint32_t noLink;
+        Adl adl;
+    };
 
-	void setCorTheta(double ct){
-		corTheta=ct;
-	}
+    std::ostream&
+    operator<<(std::ostream& os, AdjLsa& aLsa);
 
-	bool isLsaContentEqual(CorLsa& clsa);
-private:
-	double corRad;
-	double corTheta;
+    class CorLsa:public Lsa
+    {
+    public:
+        CorLsa()
+            :Lsa()
+        {
+            setLsType(3);
+        }
 
-};
+        CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
+               , double r, double theta);
+        string getCorLsaKey();
+        string getCorLsaData();
 
-std::ostream& 
-operator<<(std::ostream& os, CorLsa& cLsa);
+        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 28301f4..dbe5b86 100644
--- a/src/nlsr_lsdb.cpp
+++ b/src/nlsr_lsdb.cpp
@@ -3,699 +3,710 @@
 #include "nlsr_lsdb.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-void 
-Lsdb::cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid)
+namespace nlsr
 {
-	pnlsr.getScheduler().cancelEvent(eid);
-}
 
-static bool
-nameLsaCompareByKey(NameLsa& nlsa1, string& key){
-	return nlsa1.getNameLsaKey()==key;
-}
+    using namespace std;
+
+    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);
+    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));
+    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);
-	}
+        if( it != nameLsdb.end())
+        {
+            return std::make_pair(boost::ref((*it)),true);
+        }
 
-	NameLsa nlsa;
-	return std::make_pair(boost::ref(nlsa),false);
+        NameLsa nlsa;
+        return std::make_pair(boost::ref(nlsa),false);
 
-}
+    }
 
 
-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));
-}
+    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);
-				}
-			}
-		}
+    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());
+            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();
+                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);
-      			}
-      		}
-      } 
+                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);
+                        }
+                    }
+                }
 
-			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;
-}
+                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);
+                        }
+                    }
+                }
 
-bool 
-Lsdb::addNameLsa(NameLsa &nlsa)
-{
-	std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(), 
-					 nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getNameLsaKey()));
+                if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+                {
+                    timeToExpire=nlsa.getLifeTime();
+                }
+                cancelScheduleLsaExpiringEvent(pnlsr,
+                                               chkNameLsa.first.getLsaExpiringEventId());
+                chkNameLsa.first.setLsaExpiringEventId(scheduleNameLsaExpiration( pnlsr,
+                                                       nlsa.getNameLsaKey(), nlsa.getLsSeqNo(), timeToExpire));
+            }
+        }
 
-	if( it == nameLsdb.end())
-	{
-		nameLsdb.push_back(nlsa);
-		return true;
-	}
-	return false;
-}
+        return true;
+    }
 
-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::addNameLsa(NameLsa &nlsa)
+    {
+        std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(),
+                                           nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getNameLsaKey()));
 
-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())
+        {
+            nameLsdb.push_back(nlsa);
+            return true;
+        }
+        return false;
+    }
 
-	if( it == nameLsdb.end()){
-		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);
+                    }
+                }
 
-	return true;
-}
+            }
+            nameLsdb.erase(it);
+            return true;
+        }
+        return false;
+    }
 
-void 
-Lsdb::printNameLsdb()
-{
-	cout<<"---------------Name LSDB-------------------"<<endl;
-	for( std::list<NameLsa>::iterator it=nameLsdb.begin(); 
-	                                                 it!= nameLsdb.end() ; it++)
-	{
-		cout<< (*it) <<endl;
-	}
-}
+    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){
-	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);
+    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;
-}
+        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));
+    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);
-	}
+        if( it != corLsdb.end())
+        {
+            return std::make_pair(boost::ref((*it)), true);
+        }
 
-	CorLsa clsa;
-	return std::make_pair(boost::ref(clsa),false);
-}
+        CorLsa clsa;
+        return std::make_pair(boost::ref(clsa),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));
-}
+    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);	
-		}
+    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(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+            {
+                timeToExpire=clsa.getLifeTime();
+            }
+            scheduleCorLsaExpiration(pnlsr,clsa.getCorLsaKey(),
+                                     clsa.getLsSeqNo(), timeToExpire);
 
-				if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-				{
-					pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);	
-				}
-				
-			}
+        }
+        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(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;
-}
+                    if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
+                    {
+                        pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+                    }
 
-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;
-	}
-	return false;
-}
+                if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+                {
+                    timeToExpire=clsa.getLifeTime();
+                }
+                cancelScheduleLsaExpiringEvent(pnlsr,
+                                               chkCorLsa.first.getLsaExpiringEventId());
+                chkCorLsa.first.setLsaExpiringEventId(scheduleCorLsaExpiration(pnlsr,
+                                                      clsa.getCorLsaKey(),
+                                                      clsa.getLsSeqNo(), timeToExpire));
+            }
 
-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;
+        }
 
-}
+        return true;
+    }
 
-bool 
-Lsdb::doesCorLsaExist(string key)
-{
-	std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(), 
-																		corLsdb.end(),	
-   																	bind(corLsaCompareByKey, _1, key));
+    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()){
-		return false;
-	}
+        if( it == corLsdb.end())
+        {
+            corLsdb.push_back(clsa);
+            return true;
+        }
+        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;
 
-void 
-Lsdb::printCorLsdb() //debugging
-{
-	cout<<"---------------Cor LSDB-------------------"<<endl;
-	for( std::list<CorLsa>::iterator it=corLsdb.begin(); 
-	                                                 it!= corLsdb.end() ; it++)
-	{
-		cout<< (*it) <<endl;
-	}
-}
+    }
+
+    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)
-{
-	cout<<"scheduledAdjLsaBuild Called"<<endl;
-	pnlsr.setIsBuildAdjLsaSheduled(0);
+    void
+    Lsdb::scheduledAdjLsaBuild(Nlsr& 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)
-			{
-				buildAndInstallOwnAdjLsa(pnlsr);
-			}
-			else
-			{
-				string key=pnlsr.getConfParameter().getRouterPrefix()+"/2";
-				removeAdjLsa(pnlsr,key);
-				pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
-			}
-			pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount()-adjBuildCount);
-		}		
-	}
-	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)));
-	}
+        if( pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
+        {
+            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);
+            }
+        }
+        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)));
+        }
 
-}
+    }
 
 
-bool 
-Lsdb::addAdjLsa(AdjLsa &alsa)
-{
-	std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(), 
-																		adjLsdb.end(),	
-   														bind(adjLsaCompareByKey, _1, alsa.getAdjLsaKey()));
+    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()){
-		adjLsdb.push_back(alsa);
-		return true;
-	}
-	return false;
-	
-}
+        if( it == adjLsdb.end())
+        {
+            adjLsdb.push_back(alsa);
+            return true;
+        }
+        return false;
 
-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()){
-		return std::make_pair(boost::ref((*it)),true);
-	}
+    std::pair<AdjLsa& , bool>
+    Lsdb::getAdjLsa(string key)
+    {
+        std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
+                                          adjLsdb.end(),
+                                          bind(adjLsaCompareByKey, _1, key));
 
-	AdjLsa alsa;
-	return std::make_pair(boost::ref(alsa),false);
-}
+        if( it != adjLsdb.end())
+        {
+            return std::make_pair(boost::ref((*it)),true);
+        }
+
+        AdjLsa alsa;
+        return std::make_pair(boost::ref(alsa),false);
+    }
 
 
 
-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));
-}
+    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 )
-	{
-		addAdjLsa(alsa);
-		alsa.addNptEntriesForAdjLsa(pnlsr);
-		pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+    bool
+    Lsdb::installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa)
+    {
+        int timeToExpire=lsaRefreshTime;
+        std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
+        if ( !chkAdjLsa.second )
+        {
+            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);
-		
-	}
-	else
-	{
-		if ( chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo() )
-		{
-			chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
-			chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
+            if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+            {
+                timeToExpire=alsa.getLifeTime();
+            }
+            scheduleAdjLsaExpiration(pnlsr,alsa.getAdjLsaKey(),
+                                     alsa.getLsSeqNo(),timeToExpire);
 
-			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));
-		}
-		
-	}
+        }
+        else
+        {
+            if ( chkAdjLsa.first.getLsSeqNo() < alsa.getLsSeqNo() )
+            {
+                chkAdjLsa.first.setLsSeqNo(alsa.getLsSeqNo());
+                chkAdjLsa.first.setLifeTime(alsa.getLifeTime());
 
-	printAdjLsdb();
-	
-	return true;
-}
+                if ( !	chkAdjLsa.first.isLsaContentEqual(alsa))
+                {
+                    chkAdjLsa.first.getAdl().resetAdl();
+                    chkAdjLsa.first.getAdl().addAdjacentsFromAdl(alsa.getAdl());
+                    pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+                }
 
-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);
-	return installAdjLsa(pnlsr, adjLsa);
-}
+                if(alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+                {
+                    timeToExpire=alsa.getLifeTime();
+                }
+                cancelScheduleLsaExpiringEvent(pnlsr,
+                                               chkAdjLsa.first.getLsaExpiringEventId());
+                chkAdjLsa.first.setLsaExpiringEventId(scheduleAdjLsaExpiration(pnlsr,
+                                                      alsa.getAdjLsaKey(), alsa.getLsSeqNo(),timeToExpire));
+            }
 
-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));
+        printAdjLsdb();
 
-	if( it == adjLsdb.end()){
-		return false;
-	}
+        return true;
+    }
 
-	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);
+        return installAdjLsa(pnlsr, adjLsa);
+    }
 
-std::list<AdjLsa>& 
-Lsdb::getAdjLsdb()
-{
-		return adjLsdb;
-}
+    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;
 
-void 
-Lsdb::setLsaRefreshTime(int lrt)
-{
-	lsaRefreshTime=lrt;
-}
+    }
 
-void 
-Lsdb::setThisRouterPrefix(string trp)
-{
-	thisRouterPrefix=trp;
-}
+    bool
+    Lsdb::doesAdjLsaExist(string key)
+    {
+        std::list< AdjLsa >::iterator it = std::find_if( adjLsdb.begin(),
+                                           adjLsdb.end(),
+                                           bind(adjLsaCompareByKey, _1, key));
 
-void 
-Lsdb::exprireOrRefreshNameLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-{
-	cout<<"Lsdb::exprireOrRefreshNameLsa Called "<<endl;
-	cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<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
-			}
-			else
-			{
-				cout<<"Other's Name LSA, so removing form LSDB"<<endl;
-				removeNameLsa(pnlsr, lsaKey);
-			}
-		}
-	}
-}
+        if( it == adjLsdb.end())
+        {
+            return false;
+        }
 
-void 
-Lsdb::exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-{
-	cout<<"Lsdb::exprireOrRefreshAdjLsa Called "<<endl;
-	cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
-	std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(lsaKey);
-	if( chkAdjLsa.second )
-	{
-		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
-			}
-			else
-			{
-				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()
+    {
+        return adjLsdb;
+    }
 
-void 
-Lsdb::exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
-{
-	cout<<"Lsdb::exprireOrRefreshCorLsa Called "<<endl;
-	cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
-	std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(lsaKey);
-	if( chkCorLsa.second )
-	{
-		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
-			}
-			else
-			{
-				cout<<"Other's Cor LSA, so removing form LSDB"<<endl;
-				removeCorLsa(pnlsr, lsaKey);
-			}
+    void
+    Lsdb::setLsaRefreshTime(int lrt)
+    {
+        lsaRefreshTime=lrt;
+    }
 
-			if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-			{
-				pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);	
-			}
-		}
-	}
-}
+    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: "<<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
+                }
+                else
+                {
+                    cout<<"Other's Name LSA, so removing form LSDB"<<endl;
+                    removeNameLsa(pnlsr, lsaKey);
+                }
+            }
+        }
+    }
+
+    void
+    Lsdb::exprireOrRefreshAdjLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
+    {
+        cout<<"Lsdb::exprireOrRefreshAdjLsa Called "<<endl;
+        cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
+        std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(lsaKey);
+        if( chkAdjLsa.second )
+        {
+            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
+                }
+                else
+                {
+                    cout<<"Other's Adj LSA, so removing form LSDB"<<endl;
+                    removeAdjLsa(pnlsr, lsaKey);
+                }
+
+                // schedule Routing table calculaiton
+                pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+            }
+        }
+    }
+
+    void
+    Lsdb::exprireOrRefreshCorLsa(Nlsr& pnlsr, string lsaKey, int seqNo)
+    {
+        cout<<"Lsdb::exprireOrRefreshCorLsa Called "<<endl;
+        cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<endl;
+        std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(lsaKey);
+        if( chkCorLsa.second )
+        {
+            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
+                }
+                else
+                {
+                    cout<<"Other's Cor LSA, so removing form LSDB"<<endl;
+                    removeCorLsa(pnlsr, lsaKey);
+                }
+
+                if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
+                {
+                    pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);
+                }
+            }
+        }
+    }
 
 
-void 
-Lsdb::printAdjLsdb()
-{
-	cout<<"---------------Adj LSDB-------------------"<<endl;
-	for( std::list<AdjLsa>::iterator it=adjLsdb.begin(); 
-	                                                 it!= adjLsdb.end() ; it++)
-	{
-		cout<< (*it) <<endl;
-	}
-}
+    void
+    Lsdb::printAdjLsdb()
+    {
+        cout<<"---------------Adj LSDB-------------------"<<endl;
+        for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+                it!= adjLsdb.end() ; it++)
+        {
+            cout<< (*it) <<endl;
+        }
+    }
 
 //-----utility function -----
-bool 
-Lsdb::doesLsaExist(string key, int lsType)
-{
-	if ( lsType == 1)
-	{
-		return doesNameLsaExist(key);
-	}
-	else if ( lsType == 2)
-	{
-		return doesAdjLsaExist(key);
-	}
-	else if ( lsType == 3)
-	{
-		return doesCorLsaExist(key);
-	}
-	
-	return false;	
-}
+    bool
+    Lsdb::doesLsaExist(string key, int lsType)
+    {
+        if ( lsType == 1)
+        {
+            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 24b489d..93b2f10 100644
--- a/src/nlsr_lsdb.hpp
+++ b/src/nlsr_lsdb.hpp
@@ -4,81 +4,83 @@
 #include <utility>
 #include "nlsr_lsa.hpp"
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-class Nlsr;
+    class Nlsr;
 
-class Lsdb{
-public:
-	Lsdb()
-		: lsaRefreshTime(0)
-	{
-	}
+    class Lsdb
+    {
+    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);
-	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);
-	void printCorLsdb(); //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);
+        void printNameLsdb(); //debugging
 
-	//function related to Adj LSDB
-	void scheduledAdjLsaBuild(Nlsr& pnlsr);
-	bool buildAndInstallOwnAdjLsa(Nlsr& pnlsr);
-	bool removeAdjLsa(Nlsr& pnlsr, string& key);
-	bool installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa);
-	std::pair<AdjLsa& , bool> getAdjLsa(string key);
-	std::list<AdjLsa>& getAdjLsdb();
-	void printAdjLsdb();
+        //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);
+        void printCorLsdb(); //debugging
 
-	//void scheduleRefreshLsdb(Nlsr& pnlsr, int interval);
-	void setLsaRefreshTime(int lrt);
-	void setThisRouterPrefix(string trp);
-	
-private:
-	bool addNameLsa(NameLsa &nlsa);
-	bool doesNameLsaExist(string key);
-	
-	
-	bool addCorLsa(CorLsa& clsa);
-	bool doesCorLsaExist(string key);
+        //function related to Adj LSDB
+        void scheduledAdjLsaBuild(Nlsr& pnlsr);
+        bool buildAndInstallOwnAdjLsa(Nlsr& pnlsr);
+        bool removeAdjLsa(Nlsr& pnlsr, string& key);
+        bool installAdjLsa(Nlsr& pnlsr, AdjLsa &alsa);
+        std::pair<AdjLsa& , bool> getAdjLsa(string key);
+        std::list<AdjLsa>& getAdjLsdb();
+        void printAdjLsdb();
 
-	bool addAdjLsa(AdjLsa &alsa);
-	bool doesAdjLsaExist(string key);
+        //void scheduleRefreshLsdb(Nlsr& pnlsr, int interval);
+        void setLsaRefreshTime(int lrt);
+        void setThisRouterPrefix(string trp);
 
-  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:
+        bool addNameLsa(NameLsa &nlsa);
+        bool doesNameLsaExist(string key);
 
-private:
-	void cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid);
 
-	std::list<NameLsa> nameLsdb;
-	std::list<AdjLsa> adjLsdb;
-	std::list<CorLsa> corLsdb;
+        bool addCorLsa(CorLsa& clsa);
+        bool doesCorLsaExist(string key);
 
-	int lsaRefreshTime;
-	string thisRouterPrefix;
+        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);
+
+
+    private:
+        void cancelScheduleLsaExpiringEvent(Nlsr& pnlsr, EventId eid);
+
+        std::list<NameLsa> nameLsdb;
+        std::list<AdjLsa> adjLsdb;
+        std::list<CorLsa> corLsdb;
+
+        int lsaRefreshTime;
+        string thisRouterPrefix;
+
+    };
 
 }//namespace nlsr
 
diff --git a/src/nlsr_map.cpp b/src/nlsr_map.cpp
index cf91f61..b879889 100644
--- a/src/nlsr_map.cpp
+++ b/src/nlsr_map.cpp
@@ -7,114 +7,121 @@
 #include "nlsr_lsdb.hpp"
 #include "nlsr_map.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-ostream&
-operator<<(ostream& os, MapEntry& mpe)
+namespace nlsr
 {
-	os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
-	os<<mpe.getMappingNumber()<<" )"<<endl;
 
-	return os;
-}
+    using namespace std;
 
-static bool
-mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName){
-	return mpe1.getRouter()==rtrName;
-}
+    ostream&
+    operator<<(ostream& os, MapEntry& mpe)
+    {
+        os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
+        os<<mpe.getMappingNumber()<<" )"<<endl;
 
-static bool
-mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo){
-	return mpe1.getMappingNumber()==mappingNo;
-}
+        return os;
+    }
 
-void 
-Map::addMapElement(string& rtrName)
-{
-	MapEntry me(rtrName,mappingIndex);
-	if (  addMapElement(me) )
-	{
-		mappingIndex++;
-	}
-}
+    static bool
+    mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
+    {
+        return mpe1.getRouter()==rtrName;
+    }
 
-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() ){
-		rMap.push_back(mpe);
-		return true;
-	}
-	return false;
-}
+    static bool
+    mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
+    {
+        return mpe1.getMappingNumber()==mappingNo;
+    }
 
-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() ){
-		return (*it).getRouter();
-	}
-	return "";
-}
+    void
+    Map::addMapElement(string& rtrName)
+    {
+        MapEntry me(rtrName,mappingIndex);
+        if (  addMapElement(me) )
+        {
+            mappingIndex++;
+        }
+    }
 
-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() ){
-		return (*it).getMappingNumber();
-	}
-	return -1;
-}
+    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() )
+        {
+            rMap.push_back(mpe);
+            return true;
+        }
+        return false;
+    }
 
-void 
-Map::createMapFromAdjLsdb(Nlsr& pnlsr)
-{
-	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
+    Map::getRouterNameByMappingNo(int mn)
+    {
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByMappingNo, _1, mn));
+        if ( it != rMap.end() )
+        {
+            return (*it).getRouter();
+        }
+        return "";
+    }
 
-void 
-Map::resetMap()
-{
-	rMap.clear();
-	mappingIndex=0;
-}
+    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() )
+        {
+            return (*it).getMappingNumber();
+        }
+        return -1;
+    }
 
-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<< (*it);
-	}
+    void
+    Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+    {
+        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);
+            }
 
-	return os;
-}
+        }
+    }
+
+    void
+    Map::resetMap()
+    {
+        rMap.clear();
+        mappingIndex=0;
+    }
+
+    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<< (*it);
+        }
+
+        return os;
+    }
 
 } //namespace nlsr
diff --git a/src/nlsr_map.hpp b/src/nlsr_map.hpp
index 54edde6..0352d1d 100644
--- a/src/nlsr_map.hpp
+++ b/src/nlsr_map.hpp
@@ -6,82 +6,83 @@
 
 #include <ndn-cpp-dev/face.hpp>
 
-namespace nlsr {
-
-class Nlsr;
-
-using namespace std;
-
-class MapEntry
+namespace nlsr
 {
-public:
-	MapEntry()
-		: router()
-		, mappingNumber(-1)
-	{
-	}
 
-	~MapEntry()
-	{
-	}
-	
-	MapEntry(string rtr, int mn)
-	{
-		router=rtr;
-		mappingNumber=mn;
-	}
+    class Nlsr;
 
-	string getRouter()
-	{
-		return router;
-	}
+    using namespace std;
 
-	int getMappingNumber()
-	{
-		return mappingNumber;
-	}
-private:
-	string router;
-	int mappingNumber;
-};
+    class MapEntry
+    {
+    public:
+        MapEntry()
+            : router()
+            , mappingNumber(-1)
+        {
+        }
 
-ostream&
-operator<<(ostream& os, MapEntry& mpe);
+        ~MapEntry()
+        {
+        }
 
-class Map
-{
-public:
-	Map()
-		: mappingIndex(0)
-	{
-	}
+        MapEntry(string rtr, int mn)
+        {
+            router=rtr;
+            mappingNumber=mn;
+        }
 
-	
-	void addMapElement(string& rtrName);
-	void createMapFromAdjLsdb(Nlsr& pnlsr);
-	string getRouterNameByMappingNo(int mn);
-	int getMappingNoByRouterName(string& rName);
-	void resetMap();
-	std::list< MapEntry >& getMapList()
-	{
-		return rMap;
-	}
+        string getRouter()
+        {
+            return router;
+        }
 
-	int getMapSize()
-	{
-		return rMap.size();
-	}
+        int getMappingNumber()
+        {
+            return mappingNumber;
+        }
+    private:
+        string router;
+        int mappingNumber;
+    };
 
-	
-private:
-	bool addMapElement(MapEntry& mpe);
-	
-	int mappingIndex;
-	std::list< MapEntry > rMap;
-};
+    ostream&
+    operator<<(ostream& os, MapEntry& mpe);
 
-ostream&
-operator<<(ostream& os, Map& rMap);
+    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;
+        }
+
+        int getMapSize()
+        {
+            return rMap.size();
+        }
+
+
+    private:
+        bool addMapElement(MapEntry& mpe);
+
+        int mappingIndex;
+        std::list< MapEntry > rMap;
+    };
+
+    ostream&
+    operator<<(ostream& os, Map& rMap);
 
 } // namespace nlsr
 #endif
diff --git a/src/nlsr_nexthop.cpp b/src/nlsr_nexthop.cpp
index 7906142..e58b23c 100644
--- a/src/nlsr_nexthop.cpp
+++ b/src/nlsr_nexthop.cpp
@@ -1,12 +1,13 @@
 #include "nlsr_nexthop.hpp"
 
-namespace nlsr {
-
-ostream&
-operator<<(ostream& os, NextHop& nh)
+namespace nlsr
 {
-	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/nlsr_nexthop.hpp b/src/nlsr_nexthop.hpp
index b5d34f6..1361d52 100644
--- a/src/nlsr_nexthop.hpp
+++ b/src/nlsr_nexthop.hpp
@@ -3,52 +3,53 @@
 
 #include<iostream>
 
-namespace nlsr {
-
-using namespace std;
-
-class NextHop
+namespace nlsr
 {
-public:
-	NextHop()
-		: connectingFace(0)
-		, routeCost(0)
-	{
-	}
 
-	NextHop(int cf, double rc)
-	{
-		connectingFace=cf;
-		routeCost=rc;
-	}
+    using namespace std;
 
-	int getConnectingFace()
-	{
-		return connectingFace;
-	}	
+    class NextHop
+    {
+    public:
+        NextHop()
+            : connectingFace(0)
+            , routeCost(0)
+        {
+        }
 
-	void setConnectingFace(int cf)
-	{
-		connectingFace=cf;
-	}
+        NextHop(int cf, double rc)
+        {
+            connectingFace=cf;
+            routeCost=rc;
+        }
 
-	double getRouteCost()
-	{
-		return routeCost;
-	}
+        int getConnectingFace()
+        {
+            return connectingFace;
+        }
 
-	void setRouteCost(double rc)
-	{
-		routeCost=rc;
-	}
-private:
-	int connectingFace;
-	double routeCost;
-};
+        void setConnectingFace(int cf)
+        {
+            connectingFace=cf;
+        }
+
+        double getRouteCost()
+        {
+            return 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/nlsr_nhl.cpp b/src/nlsr_nhl.cpp
index c23cc04..2aaa2a6 100644
--- a/src/nlsr_nhl.cpp
+++ b/src/nlsr_nhl.cpp
@@ -3,83 +3,88 @@
 #include "nlsr_nhl.hpp"
 #include "nlsr_nexthop.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-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(NextHop& nh1, NextHop& nh2)
+namespace nlsr
 {
-	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
-*/
+    using namespace std;
 
-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() ){
-		nexthopList.push_back(nh);
-	}
-	if ( (*it).getRouteCost() > nh.getRouteCost() )
-	{
-		(*it).setRouteCost(nh.getRouteCost());
-	}
-}
+    static bool
+    nexthopCompare(NextHop& nh1, NextHop& nh2)
+    {
+        return nh1.getConnectingFace()==nh2.getConnectingFace();
+    }
 
-/**
-Remove a next hop only if both next hop face and route cost are same
+    static bool
+    nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+    {
+        return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
+                nh1.getRouteCost() == nh2.getRouteCost()) ;
+    }
 
-*/
+    static bool
+    nextHopSortingComparator(NextHop& nh1, NextHop& nh2)
+    {
+        return nh1.getRouteCost() < nh2.getRouteCost();
+    }
 
-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);
-	}
-}
+    /**
+    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)
+    {
+        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());
+        }
+    }
 
-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;
-}
+    /**
+    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;
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_nhl.hpp b/src/nlsr_nhl.hpp
index 9055b50..9f6bd76 100644
--- a/src/nlsr_nhl.hpp
+++ b/src/nlsr_nhl.hpp
@@ -8,45 +8,46 @@
 
 #include "nlsr_nexthop.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-class Nhl
+namespace nlsr
 {
-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;
-	}
+    using namespace std;
 
-private:
-	std::list< NextHop > nexthopList;
-};
+    class Nhl
+    {
+    public:
+        Nhl()
+        {
+        }
 
-ostream&
-operator<<(ostream& os, Nhl& 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;
+        }
+
+    private:
+        std::list< NextHop > nexthopList;
+    };
+
+    ostream&
+    operator<<(ostream& os, Nhl& nhl);
 
 }//namespace nlsr
 
diff --git a/src/nlsr_npl.cpp b/src/nlsr_npl.cpp
index 0bc0001..326b001 100644
--- a/src/nlsr_npl.cpp
+++ b/src/nlsr_npl.cpp
@@ -3,65 +3,75 @@
 
 #include "nlsr_npl.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-Npl::Npl(){
-
-}
-
-Npl::~Npl(){
-
-}
-
-static bool
-nameCompare(string& s1, string& s2){
-	return s1==s2;
-}
-
-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() ){
-		return -1;
-	}
-
-	nameList.push_back(name);
-	return 0;
-
-}
-
-int 
-Npl::removeFromNpl(string& name)
+namespace nlsr
 {
-	std::list<string >::iterator it = std::find_if( nameList.begin(), 
-								nameList.end(),	
-   								bind(&nameCompare, _1 , name));
 
-	if( it != nameList.end() ){
-		nameList.erase(it);
-	}
+    using namespace std;
 
-	return -1;
-}
+    Npl::Npl()
+    {
 
-void
-Npl::sortNpl()
-{
-	nameList.sort();
-}
+    }
 
-void
-Npl::printNpl(){
-	int i=1;
-	for( std::list<string>::iterator it=nameList.begin(); it != nameList.end(); it++){
-		cout<<"Name "<<i<<" : "<<(*it)<<endl;
-		i++;
-	}
-}
+    Npl::~Npl()
+    {
+
+    }
+
+    static bool
+    nameCompare(string& s1, string& s2)
+    {
+        return s1==s2;
+    }
+
+    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() )
+        {
+            return -1;
+        }
+
+        nameList.push_back(name);
+        return 0;
+
+    }
+
+    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() )
+        {
+            nameList.erase(it);
+        }
+
+        return -1;
+    }
+
+    void
+    Npl::sortNpl()
+    {
+        nameList.sort();
+    }
+
+    void
+    Npl::printNpl()
+    {
+        int i=1;
+        for( std::list<string>::iterator it=nameList.begin(); it != nameList.end();
+                it++)
+        {
+            cout<<"Name "<<i<<" : "<<(*it)<<endl;
+            i++;
+        }
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_npl.hpp b/src/nlsr_npl.hpp
index 47bb8f5..3fc3db9 100644
--- a/src/nlsr_npl.hpp
+++ b/src/nlsr_npl.hpp
@@ -5,33 +5,35 @@
 #include<string>
 #include <ndn-cpp-dev/face.hpp>
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-class Npl{
-	
-public:
-	Npl();
-	~Npl();
+    class 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_npt.cpp b/src/nlsr_npt.cpp
index 498b2ca..5f4ea43 100644
--- a/src/nlsr_npt.cpp
+++ b/src/nlsr_npt.cpp
@@ -6,139 +6,141 @@
 #include "nlsr_npte.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-static bool
-npteCompare(Npte& npte, string& name){
-	return npte.getNamePrefix()==name;
-}
+    static bool
+    npteCompare(Npte& npte, string& name)
+    {
+        return npte.getNamePrefix()==name;
+    }
 
 // Following two methods will update FIB with response to change in NPT
 
-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() )
-  {
-  		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());
-  }
-}
+    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));
 
-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() )
-  {
-  		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());
-  		}
-  }
-}
+        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());
+        }
+    }
+
+    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() )
+        {
+            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());
+            }
+        }
+    }
 
 
-void 
-Npt::addNpte(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::addNpte(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((*rteit).getDestination());
-	  		if(rteCheck.second)
-			{
-				addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
-			}
-			else
-			{
-				RoutingTableEntry rte((*rteit).getDestination());
-				addNpte((*it).getNamePrefix(), 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::printNpt()
-{
-	cout<<"----------------NPT----------------------"<<endl;
-	for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
-	{
-		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/nlsr_npt.hpp b/src/nlsr_npt.hpp
index 063f23b..f4ddbf9 100644
--- a/src/nlsr_npt.hpp
+++ b/src/nlsr_npt.hpp
@@ -5,28 +5,29 @@
 #include "nlsr_npte.hpp"
 #include "nlsr_rte.hpp"
 
-namespace nlsr{
-
-using namespace std;
-
-class Nlsr;
-
-class Npt
+namespace nlsr
 {
-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;
-};
+
+    using namespace std;
+
+    class Nlsr;
+
+    class 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;
+    };
 
 }//namespace nlsr
 
diff --git a/src/nlsr_npte.cpp b/src/nlsr_npte.cpp
index d9cb54f..d2d1d8a 100644
--- a/src/nlsr_npte.cpp
+++ b/src/nlsr_npte.cpp
@@ -4,79 +4,81 @@
 #include "nlsr_rte.hpp"
 #include "nlsr_nexthop.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-void
-Npte::generateNhlfromRteList()
+namespace nlsr
 {
-	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));
-		}
-	}
-}
+
+    using namespace std;
+
+    void
+    Npte::generateNhlfromRteList()
+    {
+        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));
+            }
+        }
+    }
 
 
 
-static bool
-rteCompare(RoutingTableEntry& rte, string& destRouter){
-	return rte.getDestination()==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() )
-  {
-  		rteList.erase(it);
-  }
-}
+    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() )
+        {
+            rteList.erase(it);
+        }
+    }
 
-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() )
-  {
-  		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));
-		}
-  }
-}
+    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() )
+        {
+            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));
+            }
+        }
+    }
 
 //debugging purpose
-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)
-	{
-		cout<<(*it);
-	}
-	os<<npte.getNhl();
+    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)
+        {
+            cout<<(*it);
+        }
+        os<<npte.getNhl();
 
-	return os;
-}
+        return os;
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_npte.hpp b/src/nlsr_npte.hpp
index 10ebb71..e64328c 100644
--- a/src/nlsr_npte.hpp
+++ b/src/nlsr_npte.hpp
@@ -5,55 +5,56 @@
 #include <utility>
 #include "nlsr_rte.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-class Npte
+namespace nlsr
 {
-public:
-	Npte()
-		: namePrefix()
-		, nhl()
-	{
-	}
-	Npte(string np)
-		: nhl()
-	{
-		namePrefix=np;
-	}
 
-	string getNamePrefix()
-	{
-		return namePrefix;
-	}
+    using namespace std;
 
-	std::list<RoutingTableEntry>& getRteList()
-	{
-		return rteList;
-	}
+    class Npte
+    {
+    public:
+        Npte()
+            : namePrefix()
+            , nhl()
+        {
+        }
+        Npte(string np)
+            : nhl()
+        {
+            namePrefix=np;
+        }
 
-	int getRteListSize()
-	{
-		return rteList.size();
-	}
+        string getNamePrefix()
+        {
+            return namePrefix;
+        }
 
-	Nhl& getNhl()
-	{
-		return nhl;
-	}
-	void generateNhlfromRteList();
-	void removeRoutingTableEntry(RoutingTableEntry& rte);
-	void addRoutingTableEntry(RoutingTableEntry &rte);
+        std::list<RoutingTableEntry>& getRteList()
+        {
+            return rteList;
+        }
 
-private:
-	string namePrefix;
-	std::list<RoutingTableEntry> rteList;
-	Nhl nhl;
-};
+        int getRteListSize()
+        {
+            return rteList.size();
+        }
 
-ostream&
-operator<<(ostream& os, Npte& npte);
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+        void generateNhlfromRteList();
+        void removeRoutingTableEntry(RoutingTableEntry& rte);
+        void addRoutingTableEntry(RoutingTableEntry &rte);
+
+    private:
+        string namePrefix;
+        std::list<RoutingTableEntry> rteList;
+        Nhl nhl;
+    };
+
+    ostream&
+    operator<<(ostream& os, Npte& npte);
 
 }//namespace nlsr
 
diff --git a/src/nlsr_rt.cpp b/src/nlsr_rt.cpp
index 5e15604..734a85e 100644
--- a/src/nlsr_rt.cpp
+++ b/src/nlsr_rt.cpp
@@ -9,225 +9,228 @@
 #include "nlsr_rte.hpp"
 #include "nlsr_npt.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-void
-RoutingTable::calculate(Nlsr& pnlsr)
+namespace nlsr
 {
-	//debugging purpose
-	pnlsr.getNpt().printNpt();
 
-	if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
-	{
-		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);
-				}
+    using namespace std;
 
-				//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
-		  pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
-		  //debugging purpose
-		  	printRoutingTable();
-			pnlsr.getNpt().printNpt();
-			pnlsr.getFib().printFib();
-			//debugging purpose end
-		}
+    void
+    RoutingTable::calculate(Nlsr& pnlsr)
+    {
+        //debugging purpose
+        pnlsr.getNpt().printNpt();
+
+        if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
+        {
+            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
+                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
-	}
-	else
-	{
-		scheduleRoutingTableCalculation(pnlsr);
-	}
+            pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
+            pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
+        }
+        else
+        {
+            scheduleRoutingTableCalculation(pnlsr);
+        }
 
-}
+    }
 
 
-void 
-RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
-{
-	cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
-	Map vMap;
-	vMap.createMapFromAdjLsdb(pnlsr);
-	int numOfRouter=vMap.getMapSize();
+    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);
-}
+        LinkStateRoutingTableCalculator lsrtc(numOfRouter);
+        lsrtc.calculatePath(vMap,boost::ref(*this),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::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::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 )
-	{
-		pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
-								ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
-		pnlsr.setIsRouteCalculationScheduled(1);
-	}
-}
+    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);
+        }
+    }
 
-static bool
-routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter){
-	return rte.getDestination()==destRouter;
-}
+    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)
-{
-	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);
-	}
-}
+    void
+    RoutingTable::addNextHop(string destRouter, NextHop& nh)
+    {
+        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);
+        }
+    }
 
-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() )
-  {
-  		return std::make_pair(boost::ref((*it)),true);
-  }
-  RoutingTableEntry rteEmpty;
-  return std::make_pair(boost::ref(rteEmpty),false);
-}
+    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() )
+        {
+            return std::make_pair(boost::ref((*it)),true);
+        }
+        RoutingTableEntry rteEmpty;
+        return std::make_pair(boost::ref(rteEmpty),false);
+    }
 
-void
-RoutingTable::printRoutingTable()
-{
-	cout<<"---------------Routing Table------------------"<<endl;
-	for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
-															                       it != rTable.end(); ++it)
-	{
-			cout<<(*it)<<endl;
-	}
-}
+    void
+    RoutingTable::printRoutingTable()
+    {
+        cout<<"---------------Routing Table------------------"<<endl;
+        for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
+                it != rTable.end(); ++it)
+        {
+            cout<<(*it)<<endl;
+        }
+    }
 
 
 //function related to manipulation of dry routing table
-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() ){
-		RoutingTableEntry rte(destRouter);
-		rte.getNhl().addNextHop(nh);
-		dryTable.push_back(rte);
-	}	
-	else
-	{
-		(*it).getNhl().addNextHop(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() )
+        {
+            RoutingTableEntry rte(destRouter);
+            rte.getNhl().addNextHop(nh);
+            dryTable.push_back(rte);
+        }
+        else
+        {
+            (*it).getNhl().addNextHop(nh);
+        }
 
-void
-RoutingTable::printDryRoutingTable()
-{
-	cout<<"--------Dry Run's Routing Table--------------"<<endl;
-	for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
-															                      it != dryTable.end(); ++it)
-	{
-		cout<<(*it)<<endl;
-	}
-}
+    }
+
+    void
+    RoutingTable::printDryRoutingTable()
+    {
+        cout<<"--------Dry Run's Routing Table--------------"<<endl;
+        for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
+                it != dryTable.end(); ++it)
+        {
+            cout<<(*it)<<endl;
+        }
+    }
 
 
-void 
-RoutingTable::clearRoutingTable()
-{
-	if( rTable.size() > 0 )
-	{
-		rTable.clear();
-	}
-}
+    void
+    RoutingTable::clearRoutingTable()
+    {
+        if( rTable.size() > 0 )
+        {
+            rTable.clear();
+        }
+    }
 
-void 
-RoutingTable::clearDryRoutingTable()
-{
-	if (dryTable.size()>0 )
-	{
-		dryTable.clear();
-	}
-}
+    void
+    RoutingTable::clearDryRoutingTable()
+    {
+        if (dryTable.size()>0 )
+        {
+            dryTable.clear();
+        }
+    }
 
 }//namespace nlsr
 
diff --git a/src/nlsr_rt.hpp b/src/nlsr_rt.hpp
index 22e3cfe..fb9a060 100644
--- a/src/nlsr_rt.hpp
+++ b/src/nlsr_rt.hpp
@@ -7,42 +7,43 @@
 
 #include "nlsr_rte.hpp"
 
-namespace nlsr {
-
-class Nlsr;
-class NextHop;
-
-using namespace std;
-
-class RoutingTable
+namespace nlsr
 {
-public:
-	RoutingTable()
-		: NO_NEXT_HOP(-12345)
-	{
-	}
-	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);
+    class Nlsr;
+    class NextHop;
 
-private:
-	void calculateLsRoutingTable(Nlsr& pnlsr);
-	void calculateHypRoutingTable(Nlsr& pnlsr);
-	void calculateHypDryRoutingTable(Nlsr&pnlsr);
-	
-	void clearRoutingTable();
-	void clearDryRoutingTable();
+    using namespace std;
 
-	const int NO_NEXT_HOP;
-	
-	std::list< RoutingTableEntry > rTable;
-	std::list< RoutingTableEntry > dryTable;
-};
+    class RoutingTable
+    {
+    public:
+        RoutingTable()
+            : NO_NEXT_HOP(-12345)
+        {
+        }
+        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);
+
+    private:
+        void calculateLsRoutingTable(Nlsr& pnlsr);
+        void calculateHypRoutingTable(Nlsr& pnlsr);
+        void calculateHypDryRoutingTable(Nlsr&pnlsr);
+
+        void clearRoutingTable();
+        void clearDryRoutingTable();
+
+        const int NO_NEXT_HOP;
+
+        std::list< RoutingTableEntry > rTable;
+        std::list< RoutingTableEntry > dryTable;
+    };
 
 }//namespace nlsr
 
diff --git a/src/nlsr_rtc.cpp b/src/nlsr_rtc.cpp
index 089808a..e594794 100644
--- a/src/nlsr_rtc.cpp
+++ b/src/nlsr_rtc.cpp
@@ -7,524 +7,532 @@
 #include "nlsr_nexthop.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-void 
-RoutingTableCalculator::allocateAdjMatrix()
+namespace nlsr
 {
-	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;
-	}
-}
+    using namespace std;
 
-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[row][col]=cost;
-			}
-		}
-		
-	}
-}
+    void
+    RoutingTableCalculator::allocateAdjMatrix()
+    {
+        adjMatrix = new double*[numOfRouter];
+        for(int i = 0; i < numOfRouter; ++i)
+        {
+            adjMatrix[i] = new double[numOfRouter];
+        }
+    }
 
-void
-RoutingTableCalculator::printAdjMatrix()
-{
-	for(int i=0;i<numOfRouter;i++)
-	{
-		for(int j=0;j<numOfRouter;j++)
-			printf("%f ",adjMatrix[i][j]);
-		printf("\n");
-	}
-}
+    void
+    RoutingTableCalculator::initMatrix()
+    {
+        for(int i=0; i<numOfRouter; i++)
+        {
+            for(int j=0; j<numOfRouter; j++)
+                adjMatrix[i][j]=0;
+        }
+    }
 
-void 
-RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
-{
-	for ( int i = 0; i < numOfRouter; i++ ){
-		if ( i == link ){
-			adjMatrix[source][i]=linkCost;
-		}
-		else{
-			adjMatrix[source][i]=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[row][col]=cost;
+                }
+            }
 
-int 
-RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
-{
-	int noLink=0;
-	for(int i=0;i<numOfRouter;i++)
-	{	
-		if ( adjMatrix[sRouter][i] > 0 )
-		{
-			noLink++;
-		}
-	}
-	return noLink;
-}
+        }
+    }
 
-void 
-RoutingTableCalculator::getLinksFromAdjMatrix(int *links, 
-                                                 double *linkCosts, int source)
-{
-	int j=0;
-	for (int i=0; i <numOfRouter; i++)
-	{
-		if ( adjMatrix[source][i] > 0 )
-		{
-			links[j]=i;
-			linkCosts[j]=adjMatrix[source][i];
-			j++;
-		}
-	}
-}
+    void
+    RoutingTableCalculator::printAdjMatrix()
+    {
+        for(int i=0; i<numOfRouter; i++)
+        {
+            for(int j=0; j<numOfRouter; j++)
+                printf("%f ",adjMatrix[i][j]);
+            printf("\n");
+        }
+    }
 
-void 
-RoutingTableCalculator::freeAdjMatrix()
-{
-	for(int i = 0; i < numOfRouter; ++i) 
-	{
-    	delete [] adjMatrix[i];
-	}
-	delete [] adjMatrix;
-}
+    void
+    RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+    {
+        for ( int i = 0; i < numOfRouter; i++ )
+        {
+            if ( i == link )
+            {
+                adjMatrix[source][i]=linkCost;
+            }
+            else
+            {
+                adjMatrix[source][i]=0;
+            }
+        }
+    }
+
+    int
+    RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+    {
+        int noLink=0;
+        for(int i=0; i<numOfRouter; i++)
+        {
+            if ( adjMatrix[sRouter][i] > 0 )
+            {
+                noLink++;
+            }
+        }
+        return noLink;
+    }
+
+    void
+    RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
+            double *linkCosts, int source)
+    {
+        int j=0;
+        for (int i=0; i <numOfRouter; i++)
+        {
+            if ( adjMatrix[source][i] > 0 )
+            {
+                links[j]=i;
+                linkCosts[j]=adjMatrix[source][i];
+                j++;
+            }
+        }
+    }
+
+    void
+    RoutingTableCalculator::freeAdjMatrix()
+    {
+        for(int i = 0; i < numOfRouter; ++i)
+        {
+            delete [] adjMatrix[i];
+        }
+        delete [] adjMatrix;
+    }
 
 
-void 
-RoutingTableCalculator::allocateLinks()
-{
-	links=new int[vNoLink];
-}
+    void
+    RoutingTableCalculator::allocateLinks()
+    {
+        links=new int[vNoLink];
+    }
 
-void RoutingTableCalculator::allocateLinkCosts()
-{
-	linkCosts=new double[vNoLink];
-}
+    void RoutingTableCalculator::allocateLinkCosts()
+    {
+        linkCosts=new double[vNoLink];
+    }
 
 
-void 
-RoutingTableCalculator::freeLinks()
-{
-	delete [] links;
-}
-void 
-RoutingTableCalculator::freeLinksCosts()
-{
-	delete [] linkCosts;
-}
+    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();
+    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 )
-	{
-		// 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();
+        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();
-	}
+            getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+            for (int i=0 ; i < vNoLink; i++)
+            {
 
-	freeParent();
-	freeDistance();
-	freeAdjMatrix();
-}
+                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);
+            }
 
-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++){
-		parent[i]=EMPTY_PARENT;
-		distance[i]=INF_DISTANCE;
-		Q[i]=i;
-	} 
+            freeLinks();
+            freeLinksCosts();
+        }
 
-	if ( sourceRouter != NO_MAPPING_NUM ){
-		distance[sourceRouter]=0;
-		sortQueueByDistance(Q,distance,head,numOfRouter);
+        freeParent();
+        freeDistance();
+        freeAdjMatrix();
+    }
 
-		while (head < numOfRouter )
-		{
-			u=Q[head];
-			if(distance[u] == INF_DISTANCE)
-			{
-				break;
-			}
+    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++)
+        {
+            parent[i]=EMPTY_PARENT;
+            distance[i]=INF_DISTANCE;
+            Q[i]=i;
+        }
 
-			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;
-						}	
+        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;
-}
+                    }
 
-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);
-			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];
+                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);
+                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);
 
-	if ( dest != source )
-	{
-		nextHop=NO_NEXT_HOP;	
-	}
+            }
+        }
+    }
 
-	return nextHop;
-}
+    int
+    LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+    {
+        int nextHop;
+        while ( parent[dest] != EMPTY_PARENT )
+        {
+            nextHop=dest;
+            dest=parent[dest];
 
-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;
-		}
-	}
-}
+        }
 
-void
-LinkStateRoutingTableCalculator::printLsPath(int destRouter)
-{
-	if (parent[destRouter] != EMPTY_PARENT )
-	{
-		printLsPath(parent[destRouter]);
-	}
+        if ( dest != source )
+        {
+            nextHop=NO_NEXT_HOP;
+        }
 
-	cout<<" "<<destRouter;
-}
+        return nextHop;
+    }
 
-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]])
-			{
-				int tempU=Q[j];
-				Q[j]=Q[i];
-				Q[i]=tempU;
-			}
-		}
-	}
+    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;
+            }
+        }
+    }
 
-}
+    void
+    LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+    {
+        if (parent[destRouter] != EMPTY_PARENT )
+        {
+            printLsPath(parent[destRouter]);
+        }
 
-int 
-LinkStateRoutingTableCalculator::isNotExplored(int *Q, 
-                                                   int u,int start, int element)
-{
-	int ret=0;
-	for(int i=start; i< element; i++)
-	{
-		if ( Q[i] == u )
-		{
-			ret=1;
-			break;
-		}
-	}
-	return ret;
-}
+        cout<<" "<<destRouter;
+    }
 
-void 
-LinkStateRoutingTableCalculator::allocateParent()
-{
-	parent=new int[numOfRouter];
-}
+    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]])
+                {
+                    int tempU=Q[j];
+                    Q[j]=Q[i];
+                    Q[i]=tempU;
+                }
+            }
+        }
 
-void 
-LinkStateRoutingTableCalculator::allocateDistance()
-{
-	distance= new double[numOfRouter];
-}
+    }
 
-void 
-LinkStateRoutingTableCalculator::freeParent()
-{
-	delete [] parent;
-}
+    int
+    LinkStateRoutingTableCalculator::isNotExplored(int *Q,
+            int u,int start, int element)
+    {
+        int ret=0;
+        for(int i=start; i< element; i++)
+        {
+            if ( Q[i] == u )
+            {
+                ret=1;
+                break;
+            }
+        }
+        return ret;
+    }
 
-void LinkStateRoutingTableCalculator::freeDistance()
-{
-	delete [] distance;
-}
+    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();
+    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);
+        getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
 
-	for(int i=0 ; i < numOfRouter ; ++i)
-	{
-			int k=0;
-			if ( i != sourceRouter)
-			{
-				allocateLinkFaces();
-				allocateDistanceToNeighbor();
-				allocateDistFromNbrToDest();
+        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++;
-					}
-				}
+                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);
+                addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
 
-				freeLinkFaces();
-				freeDistanceToNeighbor();
-				freeDistFromNbrToDest();	
-			}
-	}
+                freeLinkFaces();
+                freeDistanceToNeighbor();
+                freeDistFromNbrToDest();
+            }
+        }
 
-	freeLinks();
-	freeLinksCosts();
-	freeAdjMatrix();
-}
+        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);
-		}
-	}
-	
-} 
+    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
+    HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
+            Map& pMap, int src, int dest)
+    {
+        double distance=0.0;
 
-	double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
-	double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
+        string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
+        string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
 
-	double destRadius=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorRadius();
-	double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
+        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);
+        double diffTheta = fabs (srcTheta - destTheta);
 
-	if (diffTheta > MATH_PI)
-	{
-		diffTheta = 2 * MATH_PI - diffTheta; 	
-	}
+        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;
-	}
+        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;
-}
+        return distance;
+    }
 
-void 
-HypRoutingTableCalculator::allocateLinkFaces()
-{
-	linkFaces=new int[vNoLink];
-}
+    void
+    HypRoutingTableCalculator::allocateLinkFaces()
+    {
+        linkFaces=new int[vNoLink];
+    }
 
-void 
-HypRoutingTableCalculator::allocateDistanceToNeighbor()
-{
-	distanceToNeighbor=new double[vNoLink];
-}
+    void
+    HypRoutingTableCalculator::allocateDistanceToNeighbor()
+    {
+        distanceToNeighbor=new double[vNoLink];
+    }
 
-void 
-HypRoutingTableCalculator::allocateDistFromNbrToDest()
-{
-	distFromNbrToDest=new double[vNoLink];
-}
+    void
+    HypRoutingTableCalculator::allocateDistFromNbrToDest()
+    {
+        distFromNbrToDest=new double[vNoLink];
+    }
 
-void 
-HypRoutingTableCalculator::freeLinkFaces()
-{
-	delete [] linkFaces;
-}
+    void
+    HypRoutingTableCalculator::freeLinkFaces()
+    {
+        delete [] linkFaces;
+    }
 
-void 
-HypRoutingTableCalculator::freeDistanceToNeighbor()
-{
-	delete [] distanceToNeighbor;
-}
+    void
+    HypRoutingTableCalculator::freeDistanceToNeighbor()
+    {
+        delete [] distanceToNeighbor;
+    }
 
-void 
-HypRoutingTableCalculator::freeDistFromNbrToDest()
-{
-	delete [] distFromNbrToDest;
-}
+    void
+    HypRoutingTableCalculator::freeDistFromNbrToDest()
+    {
+        delete [] distFromNbrToDest;
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_rtc.hpp b/src/nlsr_rtc.hpp
index 0e391e6..987686e 100644
--- a/src/nlsr_rtc.hpp
+++ b/src/nlsr_rtc.hpp
@@ -4,140 +4,141 @@
 #include <list>
 #include <iostream>
 
-namespace nlsr {
-
-class Map;
-class RoutingTable;
-class Nlsr;
-
-
-using namespace std;
-
-class RoutingTableCalculator
+namespace nlsr
 {
-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
-{
-public:
-	LinkStateRoutingTableCalculator(int rn)
-		: EMPTY_PARENT(-12345)
-		, INF_DISTANCE(2147483647)
-		, NO_MAPPING_NUM(-1)
-		, NO_NEXT_HOP(-12345)
-	{
-		numOfRouter=rn;
-	}
-	
-
-	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();
+    class Map;
+    class RoutingTable;
+    class Nlsr;
 
 
-	
+    using namespace std;
 
-private:	
-	int *parent;
-	double *distance;
+    class 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);
 
-	
-	const int EMPTY_PARENT;
-	const double INF_DISTANCE;
-	const int NO_MAPPING_NUM;
-	const int NO_NEXT_HOP;
+        void allocateLinks();
+        void allocateLinkCosts();
+        void freeLinks();
+        void freeLinksCosts();
 
-};
+        void setNoLink(int nl)
+        {
+            vNoLink=nl;
+        }
 
-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;
-	}
+    protected:
+        double ** adjMatrix;
+        int numOfRouter;
 
-	void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+        int vNoLink;
+        int *links;
+        double *linkCosts;
+    };
 
-private:
-	void allocateLinkFaces();
-	void allocateDistanceToNeighbor();
-	void allocateDistFromNbrToDest();
-	void freeLinkFaces();
-	void freeDistanceToNeighbor();
-	void freeDistFromNbrToDest();	
+    class LinkStateRoutingTableCalculator: public RoutingTableCalculator
+    {
+    public:
+        LinkStateRoutingTableCalculator(int rn)
+            : EMPTY_PARENT(-12345)
+            , INF_DISTANCE(2147483647)
+            , NO_MAPPING_NUM(-1)
+            , NO_NEXT_HOP(-12345)
+        {
+            numOfRouter=rn;
+        }
 
-	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;
+        void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
 
-	int *linkFaces;
-	double *distanceToNeighbor;
-	double *distFromNbrToDest;
 
-	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/nlsr_rte.cpp b/src/nlsr_rte.cpp
index 59325f0..f96da11 100644
--- a/src/nlsr_rte.cpp
+++ b/src/nlsr_rte.cpp
@@ -3,23 +3,24 @@
 
 #include "nlsr_rte.hpp"
 
-namespace nlsr{
-
-using namespace std;
-
-ostream&
-operator<<(ostream& os, RoutingTableEntry &rte)
+namespace nlsr
 {
-	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;
-}
+
+    using namespace std;
+
+    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 <<"  Nexthop "<<i<<": "<<(*it)<<endl;
+        }
+        return os;
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_rte.hpp b/src/nlsr_rte.hpp
index 9540b40..25bc7ce 100644
--- a/src/nlsr_rte.hpp
+++ b/src/nlsr_rte.hpp
@@ -5,47 +5,48 @@
 
 #include "nlsr_nhl.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-class RoutingTableEntry
+namespace nlsr
 {
-public:
-	RoutingTableEntry()
-		: destination()
-		, nhl()
-	{
-		
-	}
 
-	~RoutingTableEntry()
-	{
-	}
+    using namespace std;
 
-	RoutingTableEntry(string dest)
-		: nhl()
-	{
-		destination=dest;
-	}
+    class RoutingTableEntry
+    {
+    public:
+        RoutingTableEntry()
+            : destination()
+            , nhl()
+        {
 
-	string getDestination()
-	{
-		return destination;
-	}
+        }
 
-	Nhl& getNhl()
-	{
-		return nhl;
-	}
-	
-private:
-	string destination;
-	Nhl nhl;
-};
+        ~RoutingTableEntry()
+        {
+        }
 
-ostream&
-operator<<(ostream& os, RoutingTableEntry &rte);
+        RoutingTableEntry(string dest)
+            : nhl()
+        {
+            destination=dest;
+        }
+
+        string getDestination()
+        {
+            return destination;
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+
+    private:
+        string destination;
+        Nhl nhl;
+    };
+
+    ostream&
+    operator<<(ostream& os, RoutingTableEntry &rte);
 
 }
 
diff --git a/src/nlsr_sm.cpp b/src/nlsr_sm.cpp
index 9de1b1a..d9f3a95 100644
--- a/src/nlsr_sm.cpp
+++ b/src/nlsr_sm.cpp
@@ -2,11 +2,12 @@
 #include <iostream>
 #include "nlsr_sm.hpp"
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
+    using namespace std;
 
-class Nlsr;
+    class Nlsr;
 
 }//namespace nlsr
 
diff --git a/src/nlsr_sm.hpp b/src/nlsr_sm.hpp
index 52ccbbd..7dfe1b0 100644
--- a/src/nlsr_sm.hpp
+++ b/src/nlsr_sm.hpp
@@ -5,59 +5,63 @@
 #include<string>
 #include <ndn-cpp-dev/face.hpp>
 
-namespace nlsr {
-
-using namespace std;
-
-class SequencingManager
+namespace nlsr
 {
-public:
-	SequencingManager()
-		: nameLsaSeq(0)
-		, adjLsaSeq(0)
-		, corLsaSeq(0)
-	{
-	}
 
-	SequencingManager(uint32_t nlsn, uint32_t alsn, uint32_t clsn)
-	{
-		nameLsaSeq=nlsn;
-		adjLsaSeq=alsn;
-		corLsaSeq=clsn;
-	}
-	
-	uint32_t getNameLsaSeq()
-	{
-		return nameLsaSeq;
-	}
+    using namespace std;
 
-	void setNameLsaSeq(uint32_t nlsn){
-		nameLsaSeq=nlsn;
-	}
+    class SequencingManager
+    {
+    public:
+        SequencingManager()
+            : nameLsaSeq(0)
+            , adjLsaSeq(0)
+            , corLsaSeq(0)
+        {
+        }
 
-	uint32_t getAdjLsaSeq()
-	{
-		return adjLsaSeq;
-	}
+        SequencingManager(uint32_t nlsn, uint32_t alsn, uint32_t clsn)
+        {
+            nameLsaSeq=nlsn;
+            adjLsaSeq=alsn;
+            corLsaSeq=clsn;
+        }
 
-	void setAdjLsaSeq(uint32_t alsn){
-		adjLsaSeq=alsn;
-	}
+        uint32_t getNameLsaSeq()
+        {
+            return nameLsaSeq;
+        }
 
-	uint32_t getCorLsaSeq()
-	{
-		return corLsaSeq;
-	}
+        void setNameLsaSeq(uint32_t nlsn)
+        {
+            nameLsaSeq=nlsn;
+        }
 
-	void setCorLsaSeq(uint32_t clsn){
-		corLsaSeq=clsn;
-	}
+        uint32_t getAdjLsaSeq()
+        {
+            return adjLsaSeq;
+        }
 
-private:
-	uint32_t nameLsaSeq;
-	uint32_t adjLsaSeq;
-	uint32_t corLsaSeq;
-};
+        void setAdjLsaSeq(uint32_t alsn)
+        {
+            adjLsaSeq=alsn;
+        }
+
+        uint32_t getCorLsaSeq()
+        {
+            return corLsaSeq;
+        }
+
+        void setCorLsaSeq(uint32_t clsn)
+        {
+            corLsaSeq=clsn;
+        }
+
+    private:
+        uint32_t nameLsaSeq;
+        uint32_t adjLsaSeq;
+        uint32_t corLsaSeq;
+    };
 
 
 }//namespace nlsr
diff --git a/src/nlsr_test.cpp b/src/nlsr_test.cpp
index 99b01f7..f7d8d13 100644
--- a/src/nlsr_test.cpp
+++ b/src/nlsr_test.cpp
@@ -5,104 +5,105 @@
 #include "nlsr.hpp"
 #include "nlsr_test.hpp"
 
-namespace nlsr {
-
-using namespace std;
-using namespace ndn;
-
-void 
-NlsrTest::schedlueAddingLsas(Nlsr& pnlsr)
+namespace nlsr
 {
-	// scheduling adding two name lsas, two Cor Lsas and three Adj LSAs
 
-	//Scheduling Adding LSAs for router altair
-	string router("/ndn/memphis.edu/cs/altair");
-	string name1("/ndn/memphis.edu/cs/altair/name1");
-	string name2("/ndn/memphis.edu/cs/altair/name2");
-	string name3("/ndn/memphis.edu/cs/broadcast");
-	Adjacent adj1("/ndn/memphis.edu/cs/pollux",7,17,1,0);
-	Adjacent adj2("/ndn/memphis.edu/cs/maia",15,27,1,0);
-	
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(30),
-							ndn::bind(&NlsrTest::secheduledAddNameLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,router,name1,name2,name3));
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(37),
-							ndn::bind(&NlsrTest::secheduledAddCorLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,router,123.098,1.875));
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(47),
-							ndn::bind(&NlsrTest::scheduledAddAdjacentLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,router,adj1,adj2));
+    using namespace std;
+    using namespace ndn;
 
-	//Scheduling Adding LSAs for router Maia
-	string routerMaia("/ndn/memphis.edu/cs/maia");
-	string maiaName1("/ndn/memphis.edu/maia/name1");
-	string maiaName2("/ndn/memphis.edu/maia/name2");
-	string maiaName3("/ndn/memphis.edu/cs/broadcast");
-	Adjacent maiaAdj1("/ndn/memphis.edu/cs/pollux",8,25,1,0);
-	Adjacent maiaAdj2("/ndn/memphis.edu/cs/altair",11,15,1,0);
+    void
+    NlsrTest::schedlueAddingLsas(Nlsr& pnlsr)
+    {
+        // scheduling adding two name lsas, two Cor Lsas and three Adj LSAs
 
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(55),
-							ndn::bind(&NlsrTest::secheduledAddNameLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,routerMaia,maiaName1,maiaName2,maiaName3));
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(65),
-							ndn::bind(&NlsrTest::secheduledAddCorLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,routerMaia,12.098,0.875));
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(75),
-							ndn::bind(&NlsrTest::scheduledAddAdjacentLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,routerMaia,maiaAdj1,maiaAdj2));
+        //Scheduling Adding LSAs for router altair
+        string router("/ndn/memphis.edu/cs/altair");
+        string name1("/ndn/memphis.edu/cs/altair/name1");
+        string name2("/ndn/memphis.edu/cs/altair/name2");
+        string name3("/ndn/memphis.edu/cs/broadcast");
+        Adjacent adj1("/ndn/memphis.edu/cs/pollux",7,17,1,0);
+        Adjacent adj2("/ndn/memphis.edu/cs/maia",15,27,1,0);
 
-	//sheduling Adding LSAs for Router itself
-	string routerPollux("/ndn/memphis.edu/cs/pollux");
-	Adjacent polluxAdj1("/ndn/memphis.edu/cs/maia",9,13,1,0);
-	Adjacent polluxAdj2("/ndn/memphis.edu/cs/altair",12,23,1,0);
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(30),
+                                           ndn::bind(&NlsrTest::secheduledAddNameLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,router,name1,name2,name3));
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(37),
+                                           ndn::bind(&NlsrTest::secheduledAddCorLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,router,123.098,1.875));
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(47),
+                                           ndn::bind(&NlsrTest::scheduledAddAdjacentLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,router,adj1,adj2));
 
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(90),
-							ndn::bind(&NlsrTest::scheduledAddAdjacentLsa,pnlsr.getNlsrTesting(), 
-																									boost::ref(pnlsr)
-							,routerPollux,polluxAdj1,polluxAdj2));
-	
-	
-}
+        //Scheduling Adding LSAs for router Maia
+        string routerMaia("/ndn/memphis.edu/cs/maia");
+        string maiaName1("/ndn/memphis.edu/maia/name1");
+        string maiaName2("/ndn/memphis.edu/maia/name2");
+        string maiaName3("/ndn/memphis.edu/cs/broadcast");
+        Adjacent maiaAdj1("/ndn/memphis.edu/cs/pollux",8,25,1,0);
+        Adjacent maiaAdj2("/ndn/memphis.edu/cs/altair",11,15,1,0);
+
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(55),
+                                           ndn::bind(&NlsrTest::secheduledAddNameLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,routerMaia,maiaName1,maiaName2,maiaName3));
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(65),
+                                           ndn::bind(&NlsrTest::secheduledAddCorLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,routerMaia,12.098,0.875));
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(75),
+                                           ndn::bind(&NlsrTest::scheduledAddAdjacentLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,routerMaia,maiaAdj1,maiaAdj2));
+
+        //sheduling Adding LSAs for Router itself
+        string routerPollux("/ndn/memphis.edu/cs/pollux");
+        Adjacent polluxAdj1("/ndn/memphis.edu/cs/maia",9,13,1,0);
+        Adjacent polluxAdj2("/ndn/memphis.edu/cs/altair",12,23,1,0);
+
+        pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(90),
+                                           ndn::bind(&NlsrTest::scheduledAddAdjacentLsa,pnlsr.getNlsrTesting(),
+                                                   boost::ref(pnlsr)
+                                                   ,routerPollux,polluxAdj1,polluxAdj2));
+
+
+    }
 
 
 
-void 
-NlsrTest::secheduledAddNameLsa(Nlsr& pnlsr, string router,
-																		 string name1, string name2, string name3)
-{
-	Npl npl;
-	npl.insertIntoNpl(name1);
-	npl.insertIntoNpl(name2);
-	npl.insertIntoNpl(name3);
-	NameLsa nameLsa(router,1,1,3600,npl);
-	pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
-	
-}
-																		 
-void 
-NlsrTest::secheduledAddCorLsa(Nlsr& pnlsr,string router, double r, double angle)
-{
-	CorLsa corLsa(router,3,1,3600,r,angle);
-	pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
-}
+    void
+    NlsrTest::secheduledAddNameLsa(Nlsr& pnlsr, string router,
+                                   string name1, string name2, string name3)
+    {
+        Npl npl;
+        npl.insertIntoNpl(name1);
+        npl.insertIntoNpl(name2);
+        npl.insertIntoNpl(name3);
+        NameLsa nameLsa(router,1,1,3600,npl);
+        pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
 
-void 
-NlsrTest::scheduledAddAdjacentLsa(Nlsr& pnlsr, string router, 
-	                                                Adjacent adj1, Adjacent adj2)
-{
-	Adl adl;
-	adl.insert(adj1);
-	adl.insert(adj2);
-	AdjLsa adjLsa(router,2,1,3600,2,adl);
-	pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
-	
-}
+    }
+
+    void
+    NlsrTest::secheduledAddCorLsa(Nlsr& pnlsr,string router, double r, double angle)
+    {
+        CorLsa corLsa(router,3,1,3600,r,angle);
+        pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
+    }
+
+    void
+    NlsrTest::scheduledAddAdjacentLsa(Nlsr& pnlsr, string router,
+                                      Adjacent adj1, Adjacent adj2)
+    {
+        Adl adl;
+        adl.insert(adj1);
+        adl.insert(adj2);
+        AdjLsa adjLsa(router,2,1,3600,2,adl);
+        pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+
+    }
 
 }//namespace nlsr
-	                                                
+
diff --git a/src/nlsr_test.hpp b/src/nlsr_test.hpp
index 17381a8..9963b3b 100644
--- a/src/nlsr_test.hpp
+++ b/src/nlsr_test.hpp
@@ -10,28 +10,29 @@
 #include "nlsr_npl.hpp"
 #include "nlsr_adjacent.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-class Nlsr;
-
-class NlsrTest
+namespace nlsr
 {
-public:
-	NlsrTest()
-	{
-	}
-	void schedlueAddingLsas(Nlsr& pnlsr);
-private:
-	void secheduledAddNameLsa(Nlsr& pnlsr, string router,
-																		 string name1, string name2, string name3);
-	void secheduledAddCorLsa(Nlsr& pnlsr,string router, double r, double angle);
 
-	void scheduledAddAdjacentLsa(Nlsr& pnlsr, string router, 
-	                                                Adjacent adj1, Adjacent adj2);
+    using namespace std;
 
-};
+    class Nlsr;
+
+    class NlsrTest
+    {
+    public:
+        NlsrTest()
+        {
+        }
+        void schedlueAddingLsas(Nlsr& pnlsr);
+    private:
+        void secheduledAddNameLsa(Nlsr& pnlsr, string router,
+                                  string name1, string name2, string name3);
+        void secheduledAddCorLsa(Nlsr& pnlsr,string router, double r, double angle);
+
+        void scheduledAddAdjacentLsa(Nlsr& pnlsr, string router,
+                                     Adjacent adj1, Adjacent adj2);
+
+    };
 
 } //namespace nlsr
 #endif
diff --git a/src/nlsr_tokenizer.cpp b/src/nlsr_tokenizer.cpp
index cf655ba..3c49f8c 100644
--- a/src/nlsr_tokenizer.cpp
+++ b/src/nlsr_tokenizer.cpp
@@ -6,115 +6,134 @@
 
 #include "nlsr_tokenizer.hpp"
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
-using namespace boost;
+    using namespace std;
+    using namespace boost;
 
-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();
-	
-	string ft(*tok_iter);
-	firstToken=ft;
-	++tok_iter;
+    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){
-		string oneToken(*tok_iter);
-		this->insertToken(oneToken);
-		restOfTheLine+=oneToken;
-		restOfTheLine+=seps;
-  	}
+        string ft(*tok_iter);
+        firstToken=ft;
+        ++tok_iter;
 
-	trim(restOfTheLine);
-}
+        for ( ; tok_iter != tokens.end(); ++tok_iter)
+        {
+            string oneToken(*tok_iter);
+            this->insertToken(oneToken);
+            restOfTheLine+=oneToken;
+            restOfTheLine+=seps;
+        }
 
-void 
-nlsrTokenizer::insertToken(const string& token){
-	tokenList.push_back(token);
-}
+        trim(restOfTheLine);
+    }
 
-int 
-nlsrTokenizer::getTokenPosition(string& token){
-	int pos=-1;
-	int i=1;
+    void
+    nlsrTokenizer::insertToken(const string& token)
+    {
+        tokenList.push_back(token);
+    }
 
-	for(std::list<string>::iterator it=tokenList.begin();it!=tokenList.end();it++){
-		if( (*it) == token ){
-			break;
-		}
-		i++;
-	}
+    int
+    nlsrTokenizer::getTokenPosition(string& token)
+    {
+        int pos=-1;
+        int i=1;
 
-	if( i < tokenList.size() ){
-		pos=i;
-	}
+        for(std::list<string>::iterator it=tokenList.begin(); it!=tokenList.end(); it++)
+        {
+            if( (*it) == token )
+            {
+                break;
+            }
+            i++;
+        }
 
-	return pos;
-}
+        if( i < tokenList.size() )
+        {
+            pos=i;
+        }
 
-string 
-nlsrTokenizer::getTokenString(int from , int to){
-	string returnString;
-	if ( from >=0 && to < tokenList.size()){
-		int i=0;
-		for(std::list<string>::iterator it=tokenList.begin();
-													it!=tokenList.end();it++){
-			i++;
-			if( i >= from && i<= to ){
-				string oneToken((*it));
-				returnString+=seps;
-				returnString+=oneToken;
-				
-			}
-			
-		}
-	}
+        return pos;
+    }
 
-	trim(returnString);
-	return returnString;
-}
+    string
+    nlsrTokenizer::getTokenString(int from , int to)
+    {
+        string returnString;
+        if ( from >=0 && to < tokenList.size())
+        {
+            int i=0;
+            for(std::list<string>::iterator it=tokenList.begin();
+                    it!=tokenList.end(); it++)
+            {
+                i++;
+                if( i >= from && i<= to )
+                {
+                    string oneToken((*it));
+                    returnString+=seps;
+                    returnString+=oneToken;
 
-string 
-nlsrTokenizer::getTokenString(int from){
-	string returnString;
-	if ( from >=0 && from < tokenList.size()){
-		int i=0;
-		for(std::list<string>::iterator it=tokenList.begin();
-													it!=tokenList.end();it++){
-			i++;
-			if( i >= from){
-				string oneToken((*it));
-				returnString+=seps;
-				returnString+=oneToken;
-				
-			}
-			
-		}
-	}
+                }
 
-	trim(returnString);
-	return returnString;
-}
+            }
+        }
 
-static bool
-tokenCompare(string& s1, string& s2){
-	return s1==s2;
-}
+        trim(returnString);
+        return returnString;
+    }
 
-bool
-nlsrTokenizer::doesTokenExist(string token){
-	std::list<string >::iterator it = std::find_if( tokenList.begin(), 
-								tokenList.end(),	
-   								bind(&tokenCompare, _1 , token));
+    string
+    nlsrTokenizer::getTokenString(int from)
+    {
+        string returnString;
+        if ( from >=0 && from < tokenList.size())
+        {
+            int i=0;
+            for(std::list<string>::iterator it=tokenList.begin();
+                    it!=tokenList.end(); it++)
+            {
+                i++;
+                if( i >= from)
+                {
+                    string oneToken((*it));
+                    returnString+=seps;
+                    returnString+=oneToken;
 
-	if( it != tokenList.end() ){
-		return true;
-	}
+                }
 
-	return false;
-}
+            }
+        }
+
+        trim(returnString);
+        return returnString;
+    }
+
+    static bool
+    tokenCompare(string& s1, string& s2)
+    {
+        return s1==s2;
+    }
+
+    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() )
+        {
+            return true;
+        }
+
+        return false;
+    }
 
 }//namespace nlsr
diff --git a/src/nlsr_tokenizer.hpp b/src/nlsr_tokenizer.hpp
index 1f09cac..4818952 100644
--- a/src/nlsr_tokenizer.hpp
+++ b/src/nlsr_tokenizer.hpp
@@ -8,55 +8,59 @@
 #include <list>
 #include <ndn-cpp-dev/face.hpp>
 
-namespace nlsr {
+namespace nlsr
+{
 
-using namespace std;
-using namespace boost;
+    using namespace std;
+    using namespace boost;
 
-class nlsrTokenizer{
-	public:
-		nlsrTokenizer(const string& inputString)
-			:firstToken(),
-			 restOfTheLine()	
-		{
-			seps = " ";
-			originalString = inputString;
-			makeToken();
-		}
+    class nlsrTokenizer
+    {
+    public:
+        nlsrTokenizer(const string& inputString)
+            :firstToken(),
+             restOfTheLine()
+        {
+            seps = " ";
+            originalString = inputString;
+            makeToken();
+        }
 
-		nlsrTokenizer(const string& inputString, const string& separator)
-			:firstToken(),
-			 restOfTheLine()	
-		{
-			seps = separator;
-			originalString = inputString;
-			makeToken();
-		}
-		
-		string getFirstToken(){
-			return firstToken;
-		}
+        nlsrTokenizer(const string& inputString, const string& separator)
+            :firstToken(),
+             restOfTheLine()
+        {
+            seps = separator;
+            originalString = inputString;
+            makeToken();
+        }
 
-		string getRestOfLine(){
-			return restOfTheLine;
-		}
+        string getFirstToken()
+        {
+            return firstToken;
+        }
 
-		int getTokenPosition(string& token);
-		string getTokenString(int from , int to);
-		string getTokenString(int from);
-		bool doesTokenExist(string token);
+        string getRestOfLine()
+        {
+            return restOfTheLine;
+        }
 
-	private:
+        int getTokenPosition(string& token);
+        string getTokenString(int from , int to);
+        string getTokenString(int from);
+        bool doesTokenExist(string token);
 
-		void makeToken();
-		void insertToken(const string& token);
-	
-		string seps;
-		string originalString;
-		string firstToken;
-		string restOfTheLine;
-		std::list<string> tokenList;
-};
+    private:
+
+        void makeToken();
+        void insertToken(const string& token);
+
+        string seps;
+        string originalString;
+        string firstToken;
+        string restOfTheLine;
+        std::list<string> tokenList;
+    };
 
 }//namespace nlsr
 #endif
