diff --git a/nlsr.cpp b/nlsr.cpp
deleted file mode 100644
index f1b5d93..0000000
--- a/nlsr.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include <cstdlib>
-#include<string>
-#include <sstream>
-
-#include "nlsr.hpp"
-#include "nlsr_conf_param.hpp"
-#include "nlsr_conf_processor.hpp"
-#include "nlsr_lsdb.hpp"
-//test purpose of NLSR
-#include "nlsr_test.hpp" 
-
-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::startEventLoop()
-{
-	getNlsrFace().processEvents();
-}
-
-int 
-nlsr::usage(const string& progname)
-{
-
-        cout << "Usage: " << progname << " [OPTIONS...]"<<endl;
-        cout << "   NDN routing...." << endl;
-        cout << "       -d, --daemon        Run in daemon mode" << endl;
-        cout << "       -f, --config_file   Specify configuration file name" <<endl;
-        cout << "       -p, --api_port      port where api client will connect" <<endl;
-        cout << "       -h, --help          Display this help message" << endl;
-
-        exit(EXIT_FAILURE);
-}
-
-int 
-main(int argc, char **argv){
-	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;
-    }
-  }
-	
-	
-	ConfFileProcessor cfp(nlsr.getConfFileName());
-	int res=cfp.processConfFile(nlsr);
-	if ( res < 0 )
-	{
-		return EXIT_FAILURE;
-	}
-	
-	nlsr.getConfParameter().buildRouterPrefix();
-	nlsr.getLsdb().setLsaRefreshTime(nlsr.getConfParameter().getLsaRefreshTime());
-	nlsr.getFib().setFibEntryRefreshTime(2*nlsr.getConfParameter().getLsaRefreshTime());
-	nlsr.getFib().scheduleFibRefreshing(nlsr, 60);
-	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);
-
-	//testing purpose
-	nlsr.getNlsrTesting().schedlueAddingLsas(nlsr);
-
-	nlsr.setInterestFilterNlsr(nlsr.getConfParameter().getRouterPrefix());
-	nlsr.getIm().scheduleInfoInterest(nlsr,1);
-
-	
-	
-
-	try{
-		nlsr.startEventLoop();
-	}catch(std::exception &e) {
-    		std::cerr << "ERROR: " << e.what() << std::endl;
-	}
-
-	return EXIT_SUCCESS;
-}
diff --git a/nlsr.hpp b/nlsr.hpp
deleted file mode 100644
index 5ff2ef7..0000000
--- a/nlsr.hpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#ifndef NLSR_HPP
-#define NLSR_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include "nlsr_conf_param.hpp"
-#include "nlsr_adl.hpp"
-#include "nlsr_npl.hpp"
-#include "nlsr_im.hpp"
-#include "nlsr_dm.hpp"
-#include "nlsr_lsdb.hpp"
-#include "nlsr_sm.hpp"
-#include "nlsr_rt.hpp"
-#include "nlsr_npt.hpp"
-#include "nlsr_fib.hpp"
-//testing
-#include "nlsr_test.hpp"
-
-
-
-using namespace ndn;
-using namespace std;
-
-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()
-    , nlsrTesting()
-	{
-		isDaemonProcess=false;
-		configFileName="nlsr.conf";	
-	}
-
-	void nlsrRegistrationFailed(const ndn::Name& name);
-
-	void setInterestFilterNlsr(const string& name);
-	void startEventLoop();
-	
-	int usage(const string& progname);
-
-	string getConfFileName()
-  {
-		return configFileName;
-	}
-
-  void setConfFileName(const string& fileName)
-  {
-    configFileName=fileName;
-  }
-
-  bool isSetDaemonProcess()
-  {
-    return isDaemonProcess;
-  }
-
-  void setIsDaemonProcess(bool value)
-  {
-    isDaemonProcess=value;
-  }
-
-	ConfParameter& getConfParameter(){
-		return confParam;
-	}
-
-	Adl& getAdl(){
-		return adl;
-	}
-
-	Npl& getNpl(){
-		return npl;
-	}
-
-	ndn::shared_ptr<boost::asio::io_service>& getIo()
-	{
-		return io;
-	}
-
-	ndn::Scheduler& getScheduler(){
-		return scheduler;
-	}
-
-	ndn::Face& getNlsrFace(){
-		return nlsrFace;
-	}
-
-	ndn::KeyChain& getKeyChain(){
-		return kChain;
-	}
-
-	interestManager& getIm(){
-		return im;
-	}
-
-	DataManager& getDm(){
-		return dm;
-	}
-
-	SequencingManager& getSm(){
-	 return sm;
-	}
-
-	Lsdb& getLsdb(){
-		return nlsrLsdb;
-	}
-
-	RoutingTable& getRoutingTable(){
-		return routingTable;
-	}
-
-	Npt& getNpt()
-	{
-		return npt;
-	}
-
-	Fib& getFib()
-	{
-		return fib;
-	}
-
-	long int getAdjBuildCount()
-	{
-		return adjBuildCount;
-	}
-
-	void incrementAdjBuildCount()
-	{
-		adjBuildCount++;
-	}
-
-	void setAdjBuildCount(long int abc)
-	{
-		adjBuildCount=abc;
-	}
-
-	int getIsBuildAdjLsaSheduled()
-	{
-		return isBuildAdjLsaSheduled;
-	}
-
-	void setIsBuildAdjLsaSheduled(int iabls)
-	{
-		isBuildAdjLsaSheduled=iabls;
-	}
-
-	nlsrTest& getNlsrTesting()
-	{
-		return nlsrTesting;
-	}
-
-	void setApiPort(int ap)
-	{
-		apiPort=ap;
-	}
-
-	int getApiPort()
-	{
-		return apiPort;
-	}
-
-	int getIsRoutingTableCalculating()
-	{
-		return isRoutingTableCalculating;
-	}
-
-	void setIsRoutingTableCalculating(int irtc)
-	{
-		isRoutingTableCalculating=irtc;
-	}
-
-	int getIsRouteCalculationScheduled()
-	{
-		return isRouteCalculationScheduled;
-	}
-
-	void setIsRouteCalculationScheduled(int ircs)
-	{
-		isRouteCalculationScheduled=ircs;
-	}
-	
-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;
-	
-
-	long int adjBuildCount;
-	int isBuildAdjLsaSheduled;
-	int isRouteCalculationScheduled;
-	int isRoutingTableCalculating;
-
-	nlsrTest nlsrTesting;
-	
-
-};
-
-#endif
diff --git a/nlsr_adjacent.cpp b/nlsr_adjacent.cpp
deleted file mode 100644
index 8a1c048..0000000
--- a/nlsr_adjacent.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include<iostream>
-#include<string>
-#include<cmath>
-#include<limits>
-
-#include "nlsr_adjacent.hpp"
-
-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;
-}
diff --git a/nlsr_adjacent.hpp b/nlsr_adjacent.hpp
deleted file mode 100644
index 910b8a9..0000000
--- a/nlsr_adjacent.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef ADJACENT_HPP
-#define ADJACENT_HPP
-
-using namespace std;
-
-class Adjacent{
-
-	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, int cf, double lc, int s, int iton);	
-
-		string getAdjacentName(){
-			return adjacentName;
-		}
-
-		void setAdjacentName(const string& an){
-			adjacentName=an;
-		}
-
-		int getConnectingFace(){
-			return connectingFace;
-		}
-		 
-		void setConnectingFace(int cf){
-			connectingFace=cf;
-		}
-
-		double getLinkCost(){
-			return linkCost;
-		}
-
-		void setLinkCost(double lc){
-			linkCost=lc;
-		}
-
-		int getStatus(){
-			return status;
-		}
-
-		void setStatus(int s){
-			status=s;
-		}
-
-		int getInterestTimedOutNo(){
-			return interestTimedOutNo;
-		}
-
-		void setInterestTimedOutNo(int iton){
-			interestTimedOutNo=iton;
-		}
-
-		bool isAdjacentEqual(Adjacent& adj);
-	private:
-		string adjacentName;
-		int connectingFace;
-		double linkCost;
-		int status;
-		int interestTimedOutNo;
-};
-
-std::ostream&
-operator << (std::ostream &os, Adjacent &adj);
-
-#endif
diff --git a/nlsr_adl.cpp b/nlsr_adl.cpp
deleted file mode 100644
index eaf0699..0000000
--- a/nlsr_adl.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-#include<iostream>
-#include<algorithm>
-
-#include "nlsr_adl.hpp"
-#include "nlsr_adjacent.hpp"
-#include "nlsr.hpp"
-
-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)
-{
-	for(std::list<Adjacent >::iterator it=adl.getAdjList().begin();
-	                                             it!=adl.getAdjList().end(); ++it)
-	{
-		insert((*it));
-	}
-}
-
-int
-Adl::updateAdjacentStatus(string adjName, int s){
-	Adjacent adj(adjName);
-	
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it == adjList.end()){
-		return -1;
-	}
-
-	(*it).setStatus(s);
-	return 0;
-	
-
-}
-
-Adjacent 
-Adl::getAdjacent(string adjName)
-{
-	Adjacent adj(adjName);
-	
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it != adjList.end()){
-		return (*it);
-	}
-
-	return adj;
-}
-
-
-bool 
-Adl::isAdlEqual(Adl &adl)
-{
-	if ( getAdlSize() != adl.getAdlSize() )
-	{
-		return false;
-	}
-
-	adjList.sort(adjacent_compare);	
-	adl.getAdjList().sort(adjacent_compare);
-	int equalAdjCount=0;
-
-	std::list< Adjacent > adjList2=adl.getAdjList();
-
-	std::list<Adjacent>::iterator it1;
-	std::list<Adjacent>::iterator it2;
-	for(it1=adjList.begin() , it2=adjList2.begin() ; 
-	                                              it1!=adjList.end(); it1++,it2++)
-	{
-		if ( !(*it1).isAdjacentEqual((*it2)) )
-		{
-			break;
-		}
-		equalAdjCount++;
-	}
-
-	return equalAdjCount==getAdlSize();
-}
-
-
-int 
-Adl::updateAdjacentLinkCost(string adjName, double lc){
-	Adjacent adj(adjName);
-	
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it == adjList.end()){
-		return -1;
-	}
-
-	(*it).setLinkCost(lc);
-	return 0;
-
-}
-
-bool 
-Adl::isNeighbor(string adjName){
-	Adjacent adj(adjName);
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it == adjList.end()){
-		return false;
-	}
-
-	return true;
-}
-
-void 
-Adl::incrementTimedOutInterestCount(string& neighbor){
-	Adjacent adj(neighbor);
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it == adjList.end()){
-		return ;
-	}
-
-	(*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
-
-}
-
-void 
-Adl::setTimedOutInterestCount(string& neighbor, int count){
-	Adjacent adj(neighbor);
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it != adjList.end()){
-		(*it).setInterestTimedOutNo(count);
-	}
-}
-
-int
-Adl::getTimedOutInterestCount(string& neighbor)
-{
-	Adjacent adj(neighbor);
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it == adjList.end()){
-		return -1;
-	}
-
-	return (*it).getInterestTimedOutNo();
-}
-
-int 
-Adl::getStatusOfNeighbor(string& neighbor)
-{
-	Adjacent adj(neighbor);
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it == adjList.end()){
-		return -1;
-	}
-
-	return (*it).getStatus();
-}
-
-void
-Adl::setStatusOfNeighbor(string& neighbor, int status)
-{
-	Adjacent adj(neighbor);
-	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
-								adjList.end(),	
-   								bind(&adjacent_compare, _1, adj));
-
-	if( it != adjList.end()){
-		(*it).setStatus(status);
-	}
-}
-
-std::list<Adjacent>& 
-Adl::getAdjList(){
-	return adjList;
-}
-
-bool
-Adl::isAdjLsaBuildable(nlsr& pnlsr)
-{
-	int nbrCount=0;
-	for( std::list<Adjacent>::iterator it=adjList.begin(); 
-	                                                   it!= adjList.end() ; it++)
-	{
-		if ( ((*it).getStatus() == 1 ) )
-		{
-			nbrCount++;
-		}
-		else
-		{
-			if ( (*it).getInterestTimedOutNo() >= 
-				                       pnlsr.getConfParameter().getInterestRetryNumber())
-			{
-					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;
-	}
-}
diff --git a/nlsr_adl.hpp b/nlsr_adl.hpp
deleted file mode 100644
index 0d868ae..0000000
--- a/nlsr_adl.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef NLSR_ADL_HPP
-#define NLSR_ADL_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include "nlsr_adjacent.hpp"
-#include<list>
-
-class nlsr;
-
-using namespace std;
-
-class Adl{
-
-public:
-	Adl();
-	~Adl();
-	int insert(Adjacent& adj);
-	int updateAdjacentStatus(string adjName, int s);
-	int updateAdjacentLinkCost(string adjName, double lc);	
-	std::list<Adjacent>& getAdjList();
-	bool isNeighbor(string adjName);
-	void incrementTimedOutInterestCount(string& neighbor);
-	int getTimedOutInterestCount(string& neighbor);
-	int getStatusOfNeighbor(string& neighbor);
-	void setStatusOfNeighbor(string& neighbor, int status);
-	void setTimedOutInterestCount(string& neighbor, int count);
-	void addAdjacentsFromAdl(Adl& adl);
-
-	bool isAdjLsaBuildable(nlsr& pnlsr);
-	int getNumOfActiveNeighbor();
-	Adjacent getAdjacent(string adjName);
-
-	bool isAdlEqual(Adl &adl);
-
-	int getAdlSize()
-	{
-		return adjList.size();
-	}
-
-	void resetAdl()
-	{
-		if( adjList.size() > 0 )
-		{
-			adjList.clear();
-		}
-	}
-
-	void printAdl();
-
-private:	
-	std::list< Adjacent > adjList;
-};	
-
-#endif
diff --git a/nlsr_conf_param.cpp b/nlsr_conf_param.cpp
deleted file mode 100644
index 8ae7647..0000000
--- a/nlsr_conf_param.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include<iostream>
-#include "nlsr_conf_param.hpp"
-
-using namespace std;
-
-ostream&
-operator << (ostream &os, ConfParameter& cfp){
-  os  <<"Router Name: "<< cfp.getRouterName()<<endl;
-  os  <<"Site Name: "<< cfp.getSiteName()<<endl;
-  os  <<"Network: "<< cfp.getNetwork()<<endl;
-  os  <<"Router Prefix: "<< cfp.getRouterPrefix()<<endl;
-  os  <<"ChronoSync sync Prifex: "<< cfp.getChronosyncSyncPrefix()<<endl;
-  os  <<"Interest Retry number: "<< cfp.getInterestRetryNumber()<<endl;
-  os  <<"Interest Resend second: "<< cfp.getInterestResendTime()<<endl;
-	os  <<"Info Interest Interval: "<<cfp.getInfoInterestInterval()<<endl;
-  os  <<"LSA refresh time: "<< cfp.getLsaRefreshTime()<<endl;     
-  os  <<"Max Faces Per Prefix: "<< cfp.getMaxFacesPerPrefix()<<endl;
-  os  <<"Log Dir: "<< cfp.getLogDir()<<endl;
-  os  <<"Detalied logging: "<< cfp.getDetailedLogging()<<endl;
-  os  <<"Debugging: "<< cfp.getDebugging()<<endl;
-  os  <<"Hyperbolic ROuting: "<< cfp.getIsHyperbolicCalc()<<endl;
-  os  <<"Hyp R: "<< cfp.getCorR()<<endl;
-  os  <<"Hyp theta: "<< cfp.getCorTheta()<<endl;
-	os  <<"Tunnel Type: "<< cfp.getTunnelType()<<endl;
-
-	return os;
-}
diff --git a/nlsr_conf_param.hpp b/nlsr_conf_param.hpp
deleted file mode 100644
index 817bf2e..0000000
--- a/nlsr_conf_param.hpp
+++ /dev/null
@@ -1,209 +0,0 @@
-#ifndef CONF_PARAM_HPP
-#define CONF_PARAM_HPP
-
-#include<iostream>
-
-using namespace std;
-
-class ConfParameter{
-	
-public:
-	ConfParameter()
-		:chronosyncSyncPrefix("ndn/nlsr/sync")
-		,chronosyncLsaPrefix("/ndn/nlsr/LSA")
-		{
-      isStrictHierchicalKeyCheck=0;
-
-			interestRetryNumber=3;
-			interestResendTime=5;
-			infoInterestInterval=60;
-			lsaRefreshTime=1800;
-			routerDeadInterval=3600;
-			maxFacesPerPrefix=0;
-			tunnelType=0;
-			detailedLogging=0;
-      debugging=0;
-			isHyperbolicCalc=0;	
-		}
-
-		void setRouterName(const string& rn){  
-			routerName=rn;
-		}
-
-		string getRouterName(){
-			return routerName;
-		}
-
-		void setSiteName(const string& sn){  
-			siteName=sn;
-		}
-
-		string getSiteName(){
-			return siteName;
-		}
-
-		void setNetwork(const string& nn){  
-			network=nn;
-		}
-
-		string getNetwork(){
-			return network;
-		}
-
-		void buildRouterPrefix(){
-			routerPrefix="/"+network+"/"+siteName+"/"+routerName;
-		}
-		
-		string getRouterPrefix(){
-			return routerPrefix;
-		}
-
-		void setInterestRetryNumber(int irn){
-			interestRetryNumber=irn;
-		}
-
-		int getInterestRetryNumber(){
-			return interestRetryNumber;
-		}
-
-		void setInterestResendTime(int irt){
-			interestResendTime=irt;
-		}
-
-		int getInterestResendTime(){
-			return interestResendTime;
-		}
-
-		void setLsaRefreshTime(int lrt){
-			lsaRefreshTime=lrt;
-			routerDeadInterval=2*lsaRefreshTime;
-		}
-
-		int getLsaRefreshTime(){
-			return lsaRefreshTime;
-		}
-
-		void setRouterDeadInterval(int rdt){
-			routerDeadInterval=rdt;
-		}
-
-		long int getRouterDeadInterval(){
-			return routerDeadInterval;
-		}
-
-		void setMaxFacesPerPrefix(int mfpp){
-			maxFacesPerPrefix=mfpp;
-		}
-
-		int getMaxFacesPerPrefix(){
-			return maxFacesPerPrefix;
-		}
-
-		void setLogDir(string ld){
-			logDir=ld;
-		}
-		
-		string getLogDir(){
-			return logDir;
-		}
-
-		void setDetailedLogging(int dl){
-			detailedLogging=dl;		
-		}
-
-		int getDetailedLogging(){
-			return detailedLogging;
-		}
-
-		void setDebugging(int d){
-			debugging=d;
-		}
-		
-		int getDebugging(){
-			return debugging;
-		}
-
-		void setIsHyperbolicCalc(int ihc){
-			isHyperbolicCalc=ihc;
-		}
-
-		int getIsHyperbolicCalc(){
-			return isHyperbolicCalc;
-		}
-
-		void setCorR(double cr){
-			corR=cr;
-		}
-
-		double getCorR(){
-			return corR;
-		}
-
-		void setCorTheta(double ct){
-			corTheta=ct;
-		}
-
-		double getCorTheta(){
-			return corTheta;
-		}
-
-		void setTunnelType(int tt){
-			tunnelType=tt;
-		}
-
-		int getTunnelType(){
-			return tunnelType;
-		}
-
-		void setChronosyncSyncPrefix(const string& csp){
-			chronosyncSyncPrefix=csp;
-		} 
-
-		string getChronosyncSyncPrefix(){
-			return chronosyncSyncPrefix;
-		}
-
-		int getInfoInterestInterval(){
-			return infoInterestInterval;
-		}
-
-		void setInfoInterestInterval(int iii){
-			infoInterestInterval=iii;
-		}
-
-private:
-	string routerName;
-	string siteName;
-	string network;
-
-	string routerPrefix;
-	string lsaRouterPrefix;
-
-	string chronosyncSyncPrefix;
-	string chronosyncLsaPrefix;             
-
-	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);
-
-#endif
diff --git a/nlsr_conf_processor.cpp b/nlsr_conf_processor.cpp
deleted file mode 100644
index 939aa56..0000000
--- a/nlsr_conf_processor.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-#include<iostream>
-#include<fstream>
-#include<string>
-#include<cstdlib>
-#include <sstream>
-
-#include "nlsr_conf_processor.hpp"
-#include "nlsr_conf_param.hpp"
-#include "nlsr_tokenizer.hpp"
-#include "nlsr_adjacent.hpp"
-
-
-using namespace std;
-
-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;
-		}
-	}
-
-	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;
-}
-
-int
-ConfFileProcessor::processConfCommandNetwork(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Network can not be null or empty :( !"<<endl;
-		return -1;
-	}else{
-		if(command[command.size()-1] == '/' ){
-			command.erase(command.size() - 1);
-		}
-		if(command[0] == '/' ){
-			command.erase(0,1);
-		}
-		pnlsr.getConfParameter().setNetwork(command);
-	}
-	return 0;
-}
-
-int 
-ConfFileProcessor::processConfCommandSiteName(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<"Site name can not be null or empty :( !"<<endl;
-		return -1;
-	}else{
-		if(command[command.size()-1] == '/' ){
-			command.erase(command.size() - 1);
-		}
-		if(command[0] == '/' ){
-			command.erase(0,1);
-		}
-		pnlsr.getConfParameter().setSiteName(command);
-	}
-	return 0;
-}
-
-int 
-ConfFileProcessor::processConfCommandRouterName(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Router name can not be null or empty :( !"<<endl;
-		return -1;
-	}else{
-		if(command[command.size()-1] == '/' ){
-			command.erase(command.size() - 1);
-		}
-		if(command[0] == '/' ){
-			command.erase(0,1);
-		}
-		pnlsr.getConfParameter().setRouterName(command);
-	}
-	return 0;
-}
-
-int 
-ConfFileProcessor::processConfCommandInterestRetryNumber(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [interest-retry-num n]"<<endl;
-	}else{
-		int irn;
-		stringstream ss(command.c_str());
-		ss>>irn;
-		if ( irn >=1 && irn <=5){
-			pnlsr.getConfParameter().setInterestRetryNumber(irn);
-		}
-	}
-	return 0;
-}
-
-int 
-ConfFileProcessor::processConfCommandInterestResendTime(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
-	}else{
-		int irt;
-		stringstream ss(command.c_str());
-		ss>>irt;
-		if( irt>=1 && irt <=20){
-			pnlsr.getConfParameter().setInterestResendTime(irt);
-		}
-	}
-	return 0;
-}
-
-int 
-ConfFileProcessor::processConfCommandLsaRefreshTime(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
-	}else{
-		int lrt;
-		stringstream ss(command.c_str());
-		ss>>lrt;
-		if ( lrt>= 240 && lrt<=7200){
-			pnlsr.getConfParameter().setLsaRefreshTime(lrt);
-		}
-	}
-	return 0;
-}
-
-int 
-ConfFileProcessor::processConfCommandMaxFacesPerPrefix(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [max-faces-per-prefix n]"<<endl;
-	}else{
-		int mfpp;
-		stringstream ss(command.c_str());
-		ss>>mfpp;
-		if ( mfpp>=0 && mfpp<=60){
-			pnlsr.getConfParameter().setMaxFacesPerPrefix(mfpp);
-		}
-	}
-	return 0;
-}
-
-int
-ConfFileProcessor::processConfCommandTunnelType(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
-	}else{
-		if(command == "tcp" || command == "TCP" ){
-			pnlsr.getConfParameter().setTunnelType(1);
-		}
-		else if(command == "udp" || command == "UDP"){
-			pnlsr.getConfParameter().setTunnelType(0);
-		}else{
-			cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
-		}
-	}
-	return 0;
-}
-
-int
-ConfFileProcessor::processConfCommandChronosyncSyncPrefix(nlsr& pnlsr, 
-																string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [chronosync-sync-prefix name/prefix]!"<<endl;
-	}else{
-		pnlsr.getConfParameter().setChronosyncSyncPrefix(command);
-	}
-	return 0;
-}
-
-
-int
-ConfFileProcessor::processConfCommandLogDir(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [log-dir /path/to/log/dir]!"<<endl;
-	}else{
-		pnlsr.getConfParameter().setLogDir(command);
-	}
-	return 0;
-}
-
-int
-ConfFileProcessor::processConfCommandDebugging(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [debugging on/of]!"<<endl;
-	}else{
-		if(command == "on" || command == "ON" ){
-			pnlsr.getConfParameter().setDebugging(1);
-		}
-		else if(command == "off" || command == "off"){
-			pnlsr.getConfParameter().setDebugging(0);
-		}else{
-			cerr <<" Wrong command format ! [debugging on/off]!"<<endl;
-		}
-	}
-	return 0;
-}
-
-int
-ConfFileProcessor::processConfCommandDetailedLogging(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
-	}else{
-		if(command == "on" || command == "ON" ){
-			pnlsr.getConfParameter().setDetailedLogging(1);
-		}
-		else if(command == "off" || command == "off"){
-			pnlsr.getConfParameter().setDetailedLogging(0);
-		}else{
-			cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
-		}
-	}
-	return 0;
-}
-
-int
-ConfFileProcessor::processConfCommandIsHyperbolicCalc(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
-	}else{
-		if(command == "on" || command == "ON" ){
-			pnlsr.getConfParameter().setIsHyperbolicCalc(1);
-		}
-		else if(command == "dry-run" || command == "DRY-RUN"){
-			pnlsr.getConfParameter().setIsHyperbolicCalc(2);
-		}
-		else if(command == "off" || command == "off"){
-			pnlsr.getConfParameter().setIsHyperbolicCalc(0);
-		}else{
-			cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
-		}
-	}
-	return 0;
-}
-
-int
-ConfFileProcessor::processConfCommandHyperbolicCordinate(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [hyperbolic-cordinate r 0]!"<<endl;
-		if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 ){
-			return -1;
-		}
-	}else{
-		nlsrTokenizer nt(command," ");
-		stringstream ssr(nt.getFirstToken().c_str());
-		stringstream sst(nt.getRestOfLine().c_str());
-		
-		double r,theta;
-		ssr>>r;
-		sst>>theta;
-		
-		pnlsr.getConfParameter().setCorR(r);
-		pnlsr.getConfParameter().setCorTheta(theta);
-	}
-	return 0;
-}
-
-
-int 
-ConfFileProcessor::processConfCommandNdnNeighbor(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
-	}else{
-		nlsrTokenizer nt(command," ");
-		if( nt.getRestOfLine().empty())
-		{
-			cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
-			return 0;
-		}
-		else
-		{
-			stringstream sst(nt.getRestOfLine().c_str());
-			int faceId;
-			sst>>faceId;
-			Adjacent adj(nt.getFirstToken(),faceId,0.0,0,0);
-			pnlsr.getAdl().insert(adj);
-		}
-	}
-	return 0;	
-}
-
-int 
-ConfFileProcessor::processConfCommandNdnName(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [ndnname name/prefix]!"<<endl;
-	}else{
-		pnlsr.getNpl().insertIntoNpl(command);
-	}
-	return 0;
-}
-
-
-int 
-ConfFileProcessor::processConfCommandLinkCost(nlsr& pnlsr, string command){
-	if(command.empty() ){
-		cerr <<" Wrong command format ! [link-cost nbr/name cost]!"<<endl;
-		if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 ){
-			return -1;
-		}
-	}else{
-		nlsrTokenizer nt(command," ");
-		stringstream sst(nt.getRestOfLine().c_str());
-		
-		double cost;
-		sst>>cost;
-		
-		pnlsr.getAdl().updateAdjacentLinkCost(nt.getFirstToken(),cost);
-	}
-	return 0;
-}
-
diff --git a/nlsr_conf_processor.hpp b/nlsr_conf_processor.hpp
deleted file mode 100644
index 1a1ff8a..0000000
--- a/nlsr_conf_processor.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef CONF_PROCESSOR_HPP
-#define CONF_PROCESSOR_HPP
-
-#include "nlsr.hpp" 
-
-using namespace std;
-
-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 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 processConfCommandNdnNeighbor(nlsr& pnlsr, string command);
-		int processConfCommandNdnName(nlsr& pnlsr, string command);
-		int processConfCommandLinkCost(nlsr& pnlsr, string command);
-		
-
-	private:
-		string confFileName;
-};
-
-#endif
diff --git a/nlsr_dm.cpp b/nlsr_dm.cpp
deleted file mode 100644
index 46b278d..0000000
--- a/nlsr_dm.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include<iostream>
-#include<cstdlib>
-
-
-
-#include "nlsr.hpp"
-#include "nlsr_dm.hpp"
-#include "nlsr_tokenizer.hpp"
-#include "nlsr_lsdb.hpp"
-
-using namespace std;
-using namespace ndn;
-
-void
-DataManager::processContent(nlsr& pnlsr, const ndn::Interest &interest,
-								               const ndn::Data & data)
-{
-
-	cout << "I: " << interest.toUri() << endl;
-
-	string dataName(data.getName().toUri());
-	string dataContent((char *)data.getContent().value());
-	
-  	cout << "D: " << dataName << endl;
-	cout << "Data Content: " << dataContent << endl;
-
-	nlsrTokenizer nt(dataName,"/");
-	string chkString("info");
-	if( nt.doesTokenExist(chkString) ){
-		processContentInfo(pnlsr,dataName,dataContent);
-	}
-
-}
-
-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
-
-	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)));
-		}
-		
-	}
-
-	
-	
-}
diff --git a/nlsr_dm.hpp b/nlsr_dm.hpp
deleted file mode 100644
index 923d2fa..0000000
--- a/nlsr_dm.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef NLSR_DM_HPP
-#define NLSR_DM_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-
-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:
-  
-};
-
-
-#endif
diff --git a/nlsr_fe.cpp b/nlsr_fe.cpp
deleted file mode 100644
index 1b9621f..0000000
--- a/nlsr_fe.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <list>
-#include "nlsr_fe.hpp"
-#include "nlsr_nexthop.hpp"
-
-using namespace std;
-
-bool 
-FibEntry::isEqualNextHops(Nhl &nhlOther)
-{
-	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;
-			}
-		}
-
-		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;
-}
diff --git a/nlsr_fe.hpp b/nlsr_fe.hpp
deleted file mode 100644
index 8392dfb..0000000
--- a/nlsr_fe.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef NLSR_FE_HPP
-#define NLSR_FE_HPP
-
-#include<list>
-#include <iostream>
-
-#include "nlsr_nexthop.hpp"
-#include "nlsr_nhl.hpp"
-
-using namespace std;
-
-class FibEntry
-{
-public:
-	FibEntry()
-		: name()
-		, timeToRefresh(0)
-	{
-	}
-
-	FibEntry(string n)
-	{
-		name=n;
-	}	
-
-	string getName()
-	{
-		return name;
-	}
-
-	Nhl& getNhl()
-	{
-		return nhl;
-	}
-
-	int getTimeToRefresh()
-	{
-		return timeToRefresh;
-	}
-
-	void setTimeToRefresh(int ttr)
-	{
-		timeToRefresh=ttr;
-	}
-
-	bool isEqualNextHops(Nhl &nhlOther);
-	
-private:
-	string name;
-	int timeToRefresh;
-	Nhl nhl;
-};
-
-ostream& operator<<(ostream& os, FibEntry& fe);
-
-#endif
diff --git a/nlsr_fib.cpp b/nlsr_fib.cpp
deleted file mode 100644
index 399584f..0000000
--- a/nlsr_fib.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-#include<list>
-#include "nlsr_fe.hpp"
-#include "nlsr_fib.hpp"
-#include "nlsr_nhl.hpp"
-#include "nlsr.hpp"
-
-using namespace std;
-
-static bool
-fibEntryNameCompare(FibEntry& fe, string name)
-{
-	return fe.getName() == name ;
-}
-
-
-
-void 
-Fib::removeFromFib(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
-  		}
-  		fibTable.erase(it);
-  }
-}
-
-
-void 
-Fib::updateFib(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();
-  		//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);
-  		fibTable.push_back(newEntry);	
-  		//Update NDN-FIB
-  }
-}
-
-void
-Fib::refreshFib(nlsr& pnlsr)
-{
-	for ( std::list<FibEntry >::iterator it = fibTable.begin() ;
-																		               it != fibTable.end() ; ++it)
-	{
-		(*it).setTimeToRefresh((*it).getTimeToRefresh()-60);
-		if( (*it).getTimeToRefresh() < 0 )
-		{
-			cout<<"Refreshing FIB entry : "<<endl;
-			cout<<(*it)<<endl;
-			(*it).setTimeToRefresh(fibEntryRefreshTime);
-			//update NDN-FIB
-		}
-	}
-
-	printFib();
-	scheduleFibRefreshing(pnlsr,60);
-}
-
-void 
-Fib::scheduleFibRefreshing(nlsr& pnlsr, int refreshTime)
-{
-		pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
-								         ndn::bind(&Fib::refreshFib,this,boost::ref(pnlsr)));
-}
-
-void Fib::cleanFib()
-{
-	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++)
-  		{
-  			//remove entry from NDN-FIB
-  		}
-	}
-
-	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);
-		}
-	}
-}
-
-
-int 
-Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
-{
-	int endFace=0;
-  	if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
-  	{
-  		return nextHopList.getNhlSize();
-  	}
-  	else
-  	{
-  		return maxFacesPerPrefix;
-  	}
-
-  	return endFace;
-}
-
-void
-Fib::printFib()
-{
-	cout<<"-------------------FIB-----------------------------"<<endl;
-	for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
-	                                                                         ++it)
-	{
-		cout<<(*it);
-	}
-}
diff --git a/nlsr_fib.hpp b/nlsr_fib.hpp
deleted file mode 100644
index 453b7db..0000000
--- a/nlsr_fib.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef NLSR_FIB_HPP
-#define NLSR_FIB_HPP
-
-#include <list>
-#include "nlsr_fe.hpp"
-
-class nlsr;
-
-using namespace std;
-
-class Fib
-{
-public:
-	Fib()
-	{
-	}
-
-	void removeFromFib(string name);
-	void updateFib(string name, Nhl& nextHopList, int maxFacesPerPrefix);
-	void scheduleFibRefreshing(nlsr& pnlsr, int refreshTime);
-	void cleanFib();
-	void setFibEntryRefreshTime(int fert)
-	{
-		fibEntryRefreshTime=fert;
-	}
-	
-	void printFib();
-
-private:
-	void removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId);
-	int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
-	void refreshFib(nlsr& pnlsr);
-	
-private:
-	std::list<FibEntry> fibTable;	
-	int fibEntryRefreshTime;
-};
-
-#endif
diff --git a/nlsr_im.cpp b/nlsr_im.cpp
deleted file mode 100644
index 6ae0131..0000000
--- a/nlsr_im.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-#include<iostream>
-#include<cstdlib>
-
-
-
-#include "nlsr.hpp"
-#include "nlsr_im.hpp"
-#include "nlsr_dm.hpp"
-#include "nlsr_tokenizer.hpp"
-#include "nlsr_lsdb.hpp"
-
-using namespace std;
-using namespace ndn;
-
-void 
-interestManager::processInterest( nlsr& pnlsr,
-                                  const ndn::Name &name, 
-                                  const ndn::Interest &interest)
-{
-
-	cout << "<< I: " << interest << endl;
-	string intName=interest.getName().toUri();
-	cout << "Interest Received for Name: "<< intName <<endl;
-	nlsrTokenizer nt(intName,"/");
-	string chkString("info");
-	if( nt.doesTokenExist(chkString) ){
-		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);
-}
-
-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);
-
-  		int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
-  		if ( status == 0 )
-  		{
-			string intName=neighbor +"/"+"info"+
-                                     pnlsr.getConfParameter().getRouterPrefix();
-    		expressInterest(	pnlsr,intName,2,
-                              pnlsr.getConfParameter().getInterestResendTime());
-  		}
-	}
-}
-
-void 
-interestManager::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::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());
-	}
-
-	scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
-
-}
-
-void 
-interestManager::scheduleInfoInterest(nlsr& pnlsr, int seconds)
-{
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
-							ndn::bind(&interestManager::sendScheduledInfoInterest, this, 
-																									boost::ref(pnlsr),seconds));
-}
-
diff --git a/nlsr_im.hpp b/nlsr_im.hpp
deleted file mode 100644
index 6e71500..0000000
--- a/nlsr_im.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef NLSR_IM_HPP
-#define NLSR_IM_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-
-using namespace ndn;
-using namespace std;
-
-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);
-
-private:	
-
-
-};
-
-
-#endif
diff --git a/nlsr_lsa.cpp b/nlsr_lsa.cpp
deleted file mode 100644
index 6eebb16..0000000
--- a/nlsr_lsa.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-#include<string>
-#include<iostream>
-#include<algorithm>
-#include<cmath>
-#include<limits>
-
-#include "nlsr_lsa.hpp"
-#include "nlsr_npl.hpp"
-#include "nlsr_adjacent.hpp"
-#include "nlsr.hpp"
-
-using namespace std;
-
-
-string
-NameLsa::getNameLsaKey()
-{
-	string key;
-	key=origRouter + "/" + boost::lexical_cast<std::string>(1);
-	return key;
-}
-
-NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
-{
-	origRouter=origR;
-	lsType=lst;
-	lsSeqNo=lsn;
-	lifeTime=lt;
-
-	std::list<string> nl=npl.getNameList();
-	for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
-	{
-		addNameToLsa((*it));
-	}
-
-	
-}
-
-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;
-}
-
-string
-CorLsa::getCorLsaKey()
-{
-	string key;
-	key=origRouter + "/" + boost::lexical_cast<std::string>(3);
-	return key;
-}
-
-bool 
-CorLsa::isLsaContentEqual(CorLsa& clsa)
-{
-	return (std::abs(corRad - clsa.getCorRadius()) < 
-	                                    std::numeric_limits<double>::epsilon()) &&
-	       (std::abs(corTheta - clsa.getCorTheta()) < 
-	                                    std::numeric_limits<double>::epsilon());
-}
-
-string 
-CorLsa::getCorLsaData()
-{
-	string corLsaData;
-	corLsaData=origRouter + "|";
-	corLsaData+=(boost::lexical_cast<std::string>(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;
-}
-
-std::ostream& 
-operator<<(std::ostream& os, CorLsa& cLsa)
-{
-	os<<"Cor Lsa: "<<endl;
-	os<<"  Origination Router: "<<cLsa.getOrigRouter()<<endl;
-	os<<"  Ls Type: "<<(unsigned short)cLsa.getLsType()<<endl;
-	os<<"  Ls Seq No: "<<(unsigned int)cLsa.getLsSeqNo()<<endl;
-	os<<"  Ls Lifetime: "<<(unsigned int)cLsa.getLifeTime()<<endl;
-	os<<"    Hyperbolic Radius: "<<cLsa.getCorRadius()<<endl;
-	os<<"    Hyperbolic Theta: "<<cLsa.getCorTheta()<<endl;
-
-	return os;
-}
-
-
-AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, 
-	                                                        uint32_t nl ,Adl padl)
-{
-	origRouter=origR;
-	lsType=lst;
-	lsSeqNo=lsn;
-	lifeTime=lt;
-	noLink=nl;
-
-	std::list<Adjacent> al=padl.getAdjList();
-	for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
-	{
-		if((*it).getStatus()==1)
-		{
-				addAdjacentToLsa((*it));
-		}
-	}
-}
-
-string
-AdjLsa::getAdjLsaKey()
-{
-	string key;
-	key=origRouter + "/" + boost::lexical_cast<std::string>(2);
-	return key;
-}
-
-bool 
-AdjLsa::isLsaContentEqual(AdjLsa& alsa)
-{
-	return adl.isAdlEqual(alsa.getAdl());
-}
-
-
-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;
-}
-
-
-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);
-	}
-}
-
-
-
-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;  
-}
diff --git a/nlsr_lsa.hpp b/nlsr_lsa.hpp
deleted file mode 100644
index 0f3e528..0000000
--- a/nlsr_lsa.hpp
+++ /dev/null
@@ -1,194 +0,0 @@
-#ifndef NLSR_LSA_HPP
-#define NLSR_LSA_HPP
-
-#include "nlsr_adjacent.hpp"
-#include "nlsr_npl.hpp"
-#include "nlsr_adl.hpp"
-
-using namespace std;
-
-class Lsa{
-public:
-	Lsa()
-		: origRouter()
-		, lsSeqNo()
-		, lifeTime()
-	{
-	}	
-
-
-	void setLsType(uint8_t lst)
-	{
-		lsType=lst;
-	}
-
-	uint8_t getLsType()
-	{
-		return lsType;
-	}
-
-	void setLsSeqNo(uint32_t lsn)
-	{
-		lsSeqNo=lsn;
-	}
-
-	uint32_t getLsSeqNo()
-	{
-		return lsSeqNo;
-	}
-
-	string& getOrigRouter()
-	{
-		return origRouter;
-	}
-
-	void setOrigRouter(string& org)
-	{
-		origRouter=org;
-	}
-
-	uint32_t getLifeTime()
-	{
-		return lifeTime;
-	}
-
-	void setLifeTime(uint32_t lt)
-	{
-		lifeTime=lt;
-	}
-	//string getLsaKey();
-protected:
-	string origRouter;
-	uint8_t lsType;
-	uint32_t lsSeqNo;
-	uint32_t lifeTime;
-};
-
-class NameLsa:public Lsa{
-public:
-	NameLsa()
-		: Lsa()
-		, npl()
-	{
-		setLsType(1);
-	}
-
-	NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
-
-	Npl& getNpl(){
-		return npl;
-	}
-
-	void addNameToLsa(string& name)
-	{
-		npl.insertIntoNpl(name);
-	}
-
-	void removeNameFromLsa(string& name)
-	{
-		npl.removeFromNpl(name);
-	}
-
-	string getNameLsaKey();
-
-	string getNameLsaData();
-	
-private:
-	Npl npl;
-	
-};
-
-std::ostream& 
-operator<<(std::ostream& os, NameLsa& nLsa);
-
-class AdjLsa: public Lsa{
-public:
-	AdjLsa()
-		: Lsa()
-		, adl()
-	{
-		setLsType(2);
-	}
-
-	AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, 
-	                                                        uint32_t nl ,Adl padl);
-	Adl& getAdl(){
-		return adl;
-	}
-
-	void addAdjacentToLsa(Adjacent adj)
-	{
-		adl.insert(adj);
-	}
-	string getAdjLsaKey();
-	string getAdjLsaData();
-	uint32_t getNoLink()
-	{
-		return noLink;
-	}
-
-	bool isLsaContentEqual(AdjLsa& alsa);
-	void addNptEntriesForAdjLsa(nlsr& pnlsr);
-	void removeNptEntriesForAdjLsa(nlsr& pnlsr);
-
-private:
-	uint32_t noLink;
-	Adl adl;
-};
-
-std::ostream& 
-operator<<(std::ostream& os, AdjLsa& aLsa);
-
-class CorLsa:public Lsa{
-public:
-	CorLsa()
-		:Lsa()
-	{
-		setLsType(3);
-	}
-
-	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;
-	}
-
-	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);
-
-
-
-
-#endif
diff --git a/nlsr_lsdb.cpp b/nlsr_lsdb.cpp
deleted file mode 100644
index 9e3ffe7..0000000
--- a/nlsr_lsdb.cpp
+++ /dev/null
@@ -1,685 +0,0 @@
-#include<string>
-#include<utility>
-#include "nlsr_lsdb.hpp"
-#include "nlsr.hpp"
-
-using namespace std;
-
-static bool
-nameLsaCompareByKey(NameLsa& nlsa1, string& key){
-	return nlsa1.getNameLsaKey()==key;
-}
-
-
-bool
-Lsdb::buildAndInstallOwnNameLsa(nlsr& pnlsr)
-{
-	NameLsa nameLsa(pnlsr.getConfParameter().getRouterPrefix()
-					, 1
-					, pnlsr.getSm().getNameLsaSeq()+1
-					, pnlsr.getConfParameter().getRouterDeadInterval()
-					, pnlsr.getNpl() );
-	pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq()+1);
-	return installNameLsa(pnlsr,nameLsa);
-
-}
-
-std::pair<NameLsa&, bool> 
-Lsdb::getNameLsa(string key)
-{
-	std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(), 
-																		nameLsdb.end(),	
-   																	bind(nameLsaCompareByKey, _1, key));
-
-	if( it != nameLsdb.end())
-	{
-		return std::make_pair(boost::ref((*it)),true);
-	}
-
-	NameLsa nlsa;
-	return std::make_pair(boost::ref(nlsa),false);
-
-}
-
-
-void 
-Lsdb::scheduleNameLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime)
-{
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-								                      ndn::bind(&Lsdb::exprireOrRefreshNameLsa,
-								                      this,boost::ref(pnlsr), key, seqNo));
-}
-
-bool 
-Lsdb::installNameLsa(nlsr& pnlsr, NameLsa &nlsa)
-{
-	int timeToExpire=lsaRefreshTime;
-	std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(nlsa.getNameLsaKey());
-	if ( !chkNameLsa.second )
-	{
-		addNameLsa(nlsa);
-		printNameLsdb();
-		if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-		{
-			pnlsr.getNpt().addNpte(nlsa.getOrigRouter(),nlsa.getOrigRouter(),pnlsr);
-			std::list<string> nameList=nlsa.getNpl().getNameList();
-			for(std::list<string>::iterator it=nameList.begin(); it!=nameList.end();it++)
-			{
-				if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-				{
-					pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
-				}
-			}
-		}
-
-		if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-		{
-			timeToExpire=nlsa.getLifeTime();
-		}
-		scheduleNameLsaExpiration( pnlsr, nlsa.getNameLsaKey(),
-			                                         nlsa.getLsSeqNo(), timeToExpire);
-	}
-	else
-	{
-		if ( chkNameLsa.first.getLsSeqNo() < nlsa.getLsSeqNo() )
-		{
-			chkNameLsa.first.setLsSeqNo(nlsa.getLsSeqNo());
-			chkNameLsa.first.setLifeTime(nlsa.getLifeTime());
-
-			chkNameLsa.first.getNpl().sortNpl();
-			nlsa.getNpl().sortNpl();
-
-			std::list<string> nameToAdd;
-			std::set_difference(nlsa.getNpl().getNameList().begin(),
-			                    nlsa.getNpl().getNameList().end(),
-			                    chkNameLsa.first.getNpl().getNameList().begin(),
-			                    chkNameLsa.first.getNpl().getNameList().end(),
-                          std::inserter(nameToAdd, nameToAdd.begin()));
-      for(std::list<string>::iterator it=nameToAdd.begin(); it!=nameToAdd.end();
-                                                                           ++it)
-      {
-      		chkNameLsa.first.addNameToLsa((*it));
-      		if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      		{
-      			if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-      			{
-      				pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
-      			}
-      		}
-      }
-                          
-      std::list<string> nameToRemove;
-      std::set_difference(chkNameLsa.first.getNpl().getNameList().begin(),
-			                    chkNameLsa.first.getNpl().getNameList().end(),
-			                    nlsa.getNpl().getNameList().begin(),
-			                    nlsa.getNpl().getNameList().end(),
-                          std::inserter(nameToRemove, nameToRemove.begin()));
-      for(std::list<string>::iterator it=nameToRemove.begin(); 
-                                                   it!=nameToRemove.end(); ++it)
-      {
-      		chkNameLsa.first.removeNameFromLsa((*it));
-      		if ( nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-      		{
-      			if ( (*it) !=pnlsr.getConfParameter().getRouterPrefix())
-      			{
-      				pnlsr.getNpt().removeNpte((*it),nlsa.getOrigRouter(),pnlsr);
-      			}
-      		}
-      } 
-
-			if(nlsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-			{
-				timeToExpire=nlsa.getLifeTime();
-			}
-			scheduleNameLsaExpiration( pnlsr, nlsa.getNameLsaKey(),
-			                                         nlsa.getLsSeqNo(), timeToExpire);
-		}
-	}
-	
-	return true;
-}
-
-bool 
-Lsdb::addNameLsa(NameLsa &nlsa)
-{
-	std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(), 
-					 nameLsdb.end(), bind(nameLsaCompareByKey, _1, nlsa.getNameLsaKey()));
-
-	if( it == nameLsdb.end())
-	{
-		nameLsdb.push_back(nlsa);
-		return true;
-	}
-	return false;
-}
-
-bool 
-Lsdb::removeNameLsa(nlsr& pnlsr, string& key)
-{
-	std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(), 
-																		nameLsdb.end(),	
-   																	bind(nameLsaCompareByKey, _1, key));
-  if ( it != nameLsdb.end() )
-  {
-  		if ( (*it).getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()  )
-  		{
-  			pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);	
-  			for( std::list<string>::iterator nit=(*it).getNpl().getNameList().begin();
-  			                           nit!=(*it).getNpl().getNameList().end(); ++nit)
-  			{
-  				if ( (*nit) !=pnlsr.getConfParameter().getRouterPrefix())
-  				{
-  					pnlsr.getNpt().removeNpte((*nit),(*it).getOrigRouter(),pnlsr);
-  				}
-  			} 
-  			
-  		}
-		nameLsdb.erase(it);
-		return true;
-  }
-	return false;
-}
-
-bool 
-Lsdb::doesNameLsaExist(string key)
-{
-	std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(), 
-																		nameLsdb.end(),	
-   																	bind(nameLsaCompareByKey, _1, key));
-
-	if( it == nameLsdb.end()){
-		return false;
-	}
-
-	return true;
-}
-
-void 
-Lsdb::printNameLsdb()
-{
-	cout<<"---------------Name LSDB-------------------"<<endl;
-	for( std::list<NameLsa>::iterator it=nameLsdb.begin(); 
-	                                                 it!= nameLsdb.end() ; it++)
-	{
-		cout<< (*it) <<endl;
-	}
-}
-
-// Cor LSA and LSDB related Functions start here
-
-
-static bool
-corLsaCompareByKey(CorLsa& clsa, string& key){
-	return clsa.getCorLsaKey()==key;
-}
-
-bool 
-Lsdb::buildAndInstallOwnCorLsa(nlsr& pnlsr){
-	CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
-					, 3
-					, pnlsr.getSm().getCorLsaSeq()+1
-					, pnlsr.getConfParameter().getRouterDeadInterval()
-					, pnlsr.getConfParameter().getCorR()
-					, pnlsr.getConfParameter().getCorTheta() );
-	pnlsr.getSm().setCorLsaSeq(pnlsr.getSm().getCorLsaSeq()+1);
-	installCorLsa(pnlsr, corLsa);
-
-	return true;
-}
-
-std::pair<CorLsa&, bool> 
-Lsdb::getCorLsa(string key)
-{
-	std::list< CorLsa >::iterator it = std::find_if( corLsdb.begin(), 
-																		corLsdb.end(),	
-   																	bind(corLsaCompareByKey, _1, key));
-
-	if( it != corLsdb.end()){
-		return std::make_pair(boost::ref((*it)), true);
-	}
-
-	CorLsa clsa;
-	return std::make_pair(boost::ref(clsa),false);
-}
-
-void
-Lsdb::scheduleCorLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime)
-{
-	pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(expTime),
-								                      ndn::bind(&Lsdb::exprireOrRefreshCorLsa,
-								                      this,boost::ref(pnlsr),key,seqNo));
-}
-
-bool 
-Lsdb::installCorLsa(nlsr& pnlsr, CorLsa &clsa)
-{
-	int timeToExpire=lsaRefreshTime;
-	std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(clsa.getCorLsaKey());
-	if ( !chkCorLsa.second )
-	{
-		addCorLsa(clsa);
-		printCorLsdb(); //debugging purpose
-		if ( clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-		{
-			pnlsr.getNpt().addNpte(clsa.getOrigRouter(),clsa.getOrigRouter(),pnlsr);
-		}
-		if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-		{
-			pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);	
-		}
-
-		if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-		{
-				timeToExpire=clsa.getLifeTime();
-		}
-	  scheduleCorLsaExpiration(pnlsr,clsa.getCorLsaKey(),
-	                                         clsa.getLsSeqNo(), timeToExpire);
-		
-	}
-	else
-	{
-		if ( chkCorLsa.first.getLsSeqNo() < clsa.getLsSeqNo() )
-		{
-			chkCorLsa.first.setLsSeqNo(clsa.getLsSeqNo());
-			chkCorLsa.first.setLifeTime(clsa.getLifeTime());
-			if ( !chkCorLsa.first.isLsaContentEqual(clsa) )
-			{
-				chkCorLsa.first.setCorRadius(clsa.getCorRadius());
-				chkCorLsa.first.setCorTheta(clsa.getCorTheta());
-
-				if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
-				{
-					pnlsr.getRoutingTable().scheduleRoutingTableCalculation(pnlsr);	
-				}
-				
-			}
-
-			if(clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-			{
-				timeToExpire=clsa.getLifeTime();
-			}
-			scheduleCorLsaExpiration(pnlsr,clsa.getCorLsaKey(),
-	                                         clsa.getLsSeqNo(), timeToExpire);
-		}
-		
-	}
-	
-	return true;
-}
-
-bool 
-Lsdb::addCorLsa(CorLsa& clsa)
-{
-	std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(), 
-																		corLsdb.end(),	
-   														bind(corLsaCompareByKey, _1, clsa.getCorLsaKey()));
-
-	if( it == corLsdb.end())
-	{
-		corLsdb.push_back(clsa);
-		return true;
-	}
-	return false;
-}
-
-bool 
-Lsdb::removeCorLsa(nlsr& pnlsr, string& key)
-{
-	std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(), 
-																		corLsdb.end(),	
-   																	bind(corLsaCompareByKey, _1, key));
-  if ( it != corLsdb.end() )
-  {
-  		if ( (*it).getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
-		{
-			pnlsr.getNpt().removeNpte((*it).getOrigRouter(),(*it).getOrigRouter(),pnlsr);
-		}
-		corLsdb.erase(it);
-		return true;
-  }
-	return false;
-
-}
-
-bool 
-Lsdb::doesCorLsaExist(string key)
-{
-	std::list<CorLsa >::iterator it = std::find_if( corLsdb.begin(), 
-																		corLsdb.end(),	
-   																	bind(corLsaCompareByKey, _1, key));
-
-	if( it == corLsdb.end()){
-		return false;
-	}
-
-	return true;
-}
-
-void 
-Lsdb::printCorLsdb() //debugging
-{
-	cout<<"---------------Cor LSDB-------------------"<<endl;
-	for( std::list<CorLsa>::iterator it=corLsdb.begin(); 
-	                                                 it!= corLsdb.end() ; it++)
-	{
-		cout<< (*it) <<endl;
-	}
-}
-
-
-// Adj LSA and LSDB related function starts here
-
-static bool
-adjLsaCompareByKey(AdjLsa& alsa, string& key){
-	return alsa.getAdjLsaKey()==key;
-}
-
-
-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)));
-	}
-
-}
-
-
-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;
-	
-}
-
-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);
-	}
-
-	AdjLsa alsa;
-	return std::make_pair(boost::ref(alsa),false);
-}
-
-
-
-void 
-Lsdb::scheduleAdjLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime)
-{
-	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);
-
-		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 ( !	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();
-			}
-			scheduleAdjLsaExpiration(pnlsr,alsa.getAdjLsaKey(),
-		                                            alsa.getLsSeqNo(),timeToExpire);
-		}
-		
-	}
-
-	printAdjLsdb();
-	
-	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);
-}
-
-bool 
-Lsdb::removeAdjLsa(nlsr& pnlsr, string& key)
-{
-	std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(), 
-																		adjLsdb.end(),	
-   																	bind(adjLsaCompareByKey, _1, key));
-  if ( it != adjLsdb.end() )
-  {
-  		(*it).removeNptEntriesForAdjLsa(pnlsr);
-		adjLsdb.erase(it);
-		return true;
-  }
-	return false;
-	
-}
-
-bool 
-Lsdb::doesAdjLsaExist(string key)
-{
-	std::list< AdjLsa >::iterator it = std::find_if( adjLsdb.begin(), 
-																		adjLsdb.end(),	
-   																	bind(adjLsaCompareByKey, _1, key));
-
-	if( it == adjLsdb.end()){
-		return false;
-	}
-
-	return true;
-}
-
-std::list<AdjLsa>& 
-Lsdb::getAdjLsdb()
-{
-		return adjLsdb;
-}
-
-void 
-Lsdb::setLsaRefreshTime(int lrt)
-{
-	lsaRefreshTime=lrt;
-}
-
-void 
-Lsdb::setThisRouterPrefix(string trp)
-{
-	thisRouterPrefix=trp;
-}
-
-void 
-Lsdb::exprireOrRefreshNameLsa(nlsr& pnlsr, string lsaKey, int seqNo)
-{
-	cout<<"Lsdb::exprireOrRefreshNameLsa Called "<<endl;
-	cout<<"LSA Key : "<<lsaKey<<" Seq No: "<<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;
-	}
-}
-
-//-----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;	
-}
-
-
diff --git a/nlsr_lsdb.hpp b/nlsr_lsdb.hpp
deleted file mode 100644
index 62c91ee..0000000
--- a/nlsr_lsdb.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef NLSR_LSDB_HPP
-#define NLSR_LSDB_HPP
-
-#include <utility>
-#include "nlsr_lsa.hpp"
-
-using namespace std;
-
-class nlsr;
-
-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
-
-	//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();
-
-	//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);
-
-	bool addAdjLsa(AdjLsa &alsa);
-	bool doesAdjLsaExist(string key);
-  
-	void scheduleNameLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime);
-	void exprireOrRefreshNameLsa(nlsr& pnlsr, string lsaKey, int seqNo);
-	void scheduleAdjLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime);
-	void exprireOrRefreshAdjLsa(nlsr& pnlsr, string lsaKey, int seqNo);
-	void scheduleCorLsaExpiration(nlsr& pnlsr, string key, int seqNo, int expTime);
-	void exprireOrRefreshCorLsa(nlsr& pnlsr, string lsaKey, int seqNo);
-	
-
-private:
-	std::list<NameLsa> nameLsdb;
-	std::list<AdjLsa> adjLsdb;
-	std::list<CorLsa> corLsdb;
-
-	int lsaRefreshTime;
-	string thisRouterPrefix;
-
-};
-
-#endif
diff --git a/nlsr_map.cpp b/nlsr_map.cpp
deleted file mode 100644
index 3c4ee86..0000000
--- a/nlsr_map.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-#include<iostream>
-#include<list>
-
-#include "nlsr.hpp"
-#include "nlsr_adjacent.hpp"
-#include "nlsr_lsa.hpp"
-#include "nlsr_lsdb.hpp"
-#include "nlsr_map.hpp"
-
-
-using namespace std;
-
-ostream&
-operator<<(ostream& os, MapEntry& mpe)
-{
-	os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
-	os<<mpe.getMappingNumber()<<" )"<<endl;
-
-	return os;
-}
-
-static bool
-mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName){
-	return mpe1.getRouter()==rtrName;
-}
-
-static bool
-mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo){
-	return mpe1.getMappingNumber()==mappingNo;
-}
-
-void 
-Map::addMapElement(string& rtrName)
-{
-	MapEntry me(rtrName,mappingIndex);
-	if (  addMapElement(me) )
-	{
-		mappingIndex++;
-	}
-}
-
-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;
-}
-
-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 "";
-}
-
-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;
-}
-
-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);
-		}
-		
-	}
-}
-
-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;
-}
diff --git a/nlsr_map.hpp b/nlsr_map.hpp
deleted file mode 100644
index c02104a..0000000
--- a/nlsr_map.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef NLSR_MAP_HPP
-#define NLSR_MAP_HPP
-
-#include <iostream>
-#include <list>
-
-#include <ndn-cpp-dev/face.hpp>
-
-class nlsr;
-
-using namespace std;
-
-class MapEntry
-{
-public:
-	MapEntry()
-		: router()
-		, mappingNumber(-1)
-	{
-	}
-
-	~MapEntry()
-	{
-	}
-	
-	MapEntry(string rtr, int mn)
-	{
-		router=rtr;
-		mappingNumber=mn;
-	}
-
-	string getRouter()
-	{
-		return router;
-	}
-
-	int getMappingNumber()
-	{
-		return mappingNumber;
-	}
-private:
-	string router;
-	int mappingNumber;
-};
-
-ostream&
-operator<<(ostream& os, MapEntry& mpe);
-
-class Map
-{
-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);
-
-#endif
diff --git a/nlsr_nexthop.cpp b/nlsr_nexthop.cpp
deleted file mode 100644
index 7af0bd4..0000000
--- a/nlsr_nexthop.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "nlsr_nexthop.hpp"
-
-ostream&
-operator<<(ostream& os, NextHop& nh)
-{
-	os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
-	return os;
-}
diff --git a/nlsr_nexthop.hpp b/nlsr_nexthop.hpp
deleted file mode 100644
index 17393c6..0000000
--- a/nlsr_nexthop.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef NLSR_NEXTHOP_HPP
-#define NLSR_NEXTHOP_HPP
-
-#include<iostream>
-
-using namespace std;
-
-class NextHop
-{
-public:
-	NextHop()
-		: connectingFace(0)
-		, routeCost(0)
-	{
-	}
-
-	NextHop(int cf, double rc)
-	{
-		connectingFace=cf;
-		routeCost=rc;
-	}
-
-	int getConnectingFace()
-	{
-		return connectingFace;
-	}	
-
-	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);
-
-#endif
diff --git a/nlsr_nhl.cpp b/nlsr_nhl.cpp
deleted file mode 100644
index 4fe50aa..0000000
--- a/nlsr_nhl.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-#include <iostream>
-
-#include "nlsr_nhl.hpp"
-#include "nlsr_nexthop.hpp"
-
-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)
-{
-	return nh1.getRouteCost() < nh2.getRouteCost();
-}
-
-/** 
-Add next hop to the Next Hop list
-If next hop is new it is added
-If next hop already exists in next
-hop list then updates the route
-cost with new next hop's route cost
-*/
-
-void
-Nhl::addNextHop(NextHop& nh)
-{
-	std::list<NextHop >::iterator it = std::find_if( nexthopList.begin(), 
-									nexthopList.end(),	
-   								bind(&nexthopCompare, _1, nh));
-	if ( it == nexthopList.end() ){
-		nexthopList.push_back(nh);
-	}
-	if ( (*it).getRouteCost() > nh.getRouteCost() )
-	{
-		(*it).setRouteCost(nh.getRouteCost());
-	}
-}
-
-/**
-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;
-}
diff --git a/nlsr_nhl.hpp b/nlsr_nhl.hpp
deleted file mode 100644
index 0d381f5..0000000
--- a/nlsr_nhl.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef NLSR_NHL_HPP
-#define NLSR_NHL_HPP
-
-#include <ndn-cpp-dev/face.hpp>
-#include "nlsr_adjacent.hpp"
-#include <list>
-#include <iostream>
-
-#include "nlsr_nexthop.hpp"
-
-using namespace std;
-
-class Nhl
-{
-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;
-	}
-
-private:
-	std::list< NextHop > nexthopList;
-};
-
-ostream&
-operator<<(ostream& os, Nhl& nhl);
-
-#endif
diff --git a/nlsr_npl.cpp b/nlsr_npl.cpp
deleted file mode 100644
index b278699..0000000
--- a/nlsr_npl.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include<iostream>
-#include<algorithm>
-
-#include "nlsr_npl.hpp"
-
-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)
-{
-	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++;
-	}
-}
diff --git a/nlsr_npl.hpp b/nlsr_npl.hpp
deleted file mode 100644
index 3a0393a..0000000
--- a/nlsr_npl.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef NPL_HPP
-#define NPL_HPP
-
-#include<list>
-#include<string>
-#include <ndn-cpp-dev/face.hpp>
-
-using namespace std;
-
-class Npl{
-	
-public:
-	Npl();
-	~Npl();
-
-	int insertIntoNpl(string& name);
-	int removeFromNpl(string& name);
-	void sortNpl();
-	int getNplSize()
-	{
-		return nameList.size();
-	}
-	std::list<string>& getNameList()
-	{
-		return nameList;
-	}
-	void printNpl();
-
-private:
-	std::list<string> nameList;
-
-};
-
-#endif
diff --git a/nlsr_npt.cpp b/nlsr_npt.cpp
deleted file mode 100644
index ba516e5..0000000
--- a/nlsr_npt.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#include <list>
-#include <utility>
-#include <algorithm>
-
-#include "nlsr_npt.hpp"
-#include "nlsr_npte.hpp"
-#include "nlsr.hpp"
-
-using namespace std;
-
-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(name,newEntry.getNhl(),
-  		                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
-  }	
-  else
-  {
-  		(*it).addRoutingTableEntry(rte);
-  		(*it).generateNhlfromRteList();
-  		// update FIB here with nhl list from (*it).getNhl()
-  		pnlsr.getFib().updateFib(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(name);
-  			
-  		}
-  		else
-  		{
-  			(*it).generateNhlfromRteList();
-  			// update FIB entry with new NHL
-  			pnlsr.getFib().updateFib(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::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::printNpt()
-{
-	cout<<"----------------NPT----------------------"<<endl;
-	for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
-	{
-		cout <<(*it)<<endl;
-	}
-}
diff --git a/nlsr_npt.hpp b/nlsr_npt.hpp
deleted file mode 100644
index 8ceae33..0000000
--- a/nlsr_npt.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef NLSR_NPT_HPP
-#define NLSR_NPT_HPP
-
-#include <list>
-#include "nlsr_npte.hpp"
-#include "nlsr_rte.hpp"
-
-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;
-};
-
-#endif
diff --git a/nlsr_npte.cpp b/nlsr_npte.cpp
deleted file mode 100644
index 65f2722..0000000
--- a/nlsr_npte.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <list>
-#include <utility>
-#include "nlsr_npte.hpp"
-#include "nlsr_rte.hpp"
-#include "nlsr_nexthop.hpp"
-
-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;
-}
-
-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));
-		}
-  }
-}
-
-//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();
-
-	return os;
-}
diff --git a/nlsr_npte.hpp b/nlsr_npte.hpp
deleted file mode 100644
index 49f763a..0000000
--- a/nlsr_npte.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef NLSR_NPTE_HPP
-#define NLSR_NPTE_HPP
-
-#include <list>
-#include <utility>
-#include "nlsr_rte.hpp"
-
-using namespace std;
-
-class Npte
-{
-public:
-	Npte()
-		: namePrefix()
-		, nhl()
-	{
-	}
-	Npte(string np)
-		: nhl()
-	{
-		namePrefix=np;
-	}
-
-	string getNamePrefix()
-	{
-		return namePrefix;
-	}
-
-	std::list<RoutingTableEntry>& getRteList()
-	{
-		return rteList;
-	}
-
-	int getRteListSize()
-	{
-		return rteList.size();
-	}
-
-	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);
-
-#endif
diff --git a/nlsr_params.hpp b/nlsr_params.hpp
deleted file mode 100644
index a5f11c5..0000000
--- a/nlsr_params.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef NLSR_PARAMS_HPP
-#define NLSR_PARAMS_HPP
-
-class nlsrParams{
-
-	
-
-
-
-};
-
-#endif
diff --git a/nlsr_rt.cpp b/nlsr_rt.cpp
deleted file mode 100644
index efa423a..0000000
--- a/nlsr_rt.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-#include<iostream>
-#include<string>
-#include<list>
-
-#include "nlsr_rt.hpp"
-#include "nlsr.hpp"
-#include "nlsr_map.hpp"
-#include "nlsr_rtc.hpp"
-#include "nlsr_rte.hpp"
-#include "nlsr_npt.hpp"
-
-using namespace std;
-
-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);
-	}
-
-}
-
-
-void 
-RoutingTable::calculateLsRoutingTable(nlsr& pnlsr)
-{
-	cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
-	Map vMap;
-	vMap.createMapFromAdjLsdb(pnlsr);
-	int numOfRouter=vMap.getMapSize();
-
-	LinkStateRoutingTableCalculator lsrtc(numOfRouter);
-	lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
-}
-
-void 
-RoutingTable::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::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;
-}
-
-// 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);
-	}
-}
-
-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;
-	}
-}
-
-
-//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::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::clearDryRoutingTable()
-{
-	if (dryTable.size()>0 )
-	{
-		dryTable.clear();
-	}
-}
-
diff --git a/nlsr_rt.hpp b/nlsr_rt.hpp
deleted file mode 100644
index ef54742..0000000
--- a/nlsr_rt.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef NLSR_RT_HPP
-#define NLSR_RT_HPP
-
-#include<iostream>
-#include<utility>
-#include<string>
-
-#include "nlsr_rte.hpp"
-
-class nlsr;
-class NextHop;
-
-using namespace std;
-
-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;
-};
-
-#endif
diff --git a/nlsr_rtc.cpp b/nlsr_rtc.cpp
deleted file mode 100644
index 539c6e9..0000000
--- a/nlsr_rtc.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-#include <iostream>
-#include <cmath>
-#include "nlsr_lsdb.hpp"
-#include "nlsr_rtc.hpp"
-#include "nlsr_map.hpp"
-#include "nlsr_lsa.hpp"
-#include "nlsr_nexthop.hpp"
-#include "nlsr.hpp"
-
-using namespace std;
-
-void 
-RoutingTableCalculator::allocateAdjMatrix()
-{
-	adjMatrix = new double*[numOfRouter];
-	for(int i = 0; i < numOfRouter; ++i) 
-	{
-    adjMatrix[i] = new double[numOfRouter];
-	}
-}
-
-void 
-RoutingTableCalculator::initMatrix()
-{
-	for(int i=0;i<numOfRouter;i++)
-	{
-		for(int j=0;j<numOfRouter;j++)
-			adjMatrix[i][j]=0;
-	}
-}
-
-void
-RoutingTableCalculator::makeAdjMatrix(nlsr& pnlsr, Map pMap)
-{
-	std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
-	for( std::list<AdjLsa>::iterator it=adjLsdb.begin(); 
-	                                                 it!= adjLsdb.end() ; it++)
-	{
-		string linkStartRouter=(*it).getOrigRouter();
-		int row=pMap.getMappingNoByRouterName(linkStartRouter);
-		std::list<Adjacent> adl=(*it).getAdl().getAdjList();
-		for( std::list<Adjacent>::iterator itAdl=adl.begin(); 
-																								itAdl!= adl.end() ; itAdl++)
-		{
-			string linkEndRouter=(*itAdl).getAdjacentName();
-			int col=pMap.getMappingNoByRouterName(linkEndRouter);
-			double cost=(*itAdl).getLinkCost();
-			if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
-			{
-				adjMatrix[row][col]=cost;
-			}
-		}
-		
-	}
-}
-
-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::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::allocateLinkCosts()
-{
-	linkCosts=new double[vNoLink];
-}
-
-void 
-RoutingTableCalculator::freeLinks()
-{
-	delete [] links;
-}
-void 
-RoutingTableCalculator::freeLinksCosts()
-{
-	delete [] linkCosts;
-}
-
-void
-LinkStateRoutingTableCalculator::calculatePath(Map& pMap, 
-                                                  RoutingTable& rt, nlsr& pnlsr)
-{
-	cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
-	allocateAdjMatrix();
-	initMatrix();
-	makeAdjMatrix(pnlsr,pMap);
-	cout<<pMap;
-	printAdjMatrix();
-	string routerName=pnlsr.getConfParameter().getRouterPrefix();
-	int sourceRouter=pMap.getMappingNoByRouterName(routerName);
-	int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
-	allocateParent();
-	allocateDistance();
-
-	if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
-	{
-		// Single Path
-		doDijkstraPathCalculation(sourceRouter);
-		// print all ls path -- debugging purpose
-		printAllLsPath(sourceRouter);
-		// update routing table
-		addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
-	}
-	else
-	{
-		// Multi Path
-		setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
-		allocateLinks();
-		allocateLinkCosts();
-
-		getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
-		for (int i=0 ; i < vNoLink; i++)
-		{
-			
-			adjustAdMatrix(sourceRouter,links[i], linkCosts[i]);
-			printAdjMatrix();
-			doDijkstraPathCalculation(sourceRouter);
-			// print all ls path -- debugging purpose
-			printAllLsPath(sourceRouter);
-			//update routing table
-			addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
-		}
-		
-		freeLinks();
-	  freeLinksCosts();
-	}
-
-	freeParent();
-	freeDistance();
-	freeAdjMatrix();
-}
-
-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;
-	} 
-
-	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];
-
-	}
-
-	if ( dest != source )
-	{
-		nextHop=NO_NEXT_HOP;	
-	}
-
-	return nextHop;
-}
-
-void
-LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
-{
-	cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
-	cout<<"Source Router: "<<sourceRouter<<endl;
-	for(int i=0; i < numOfRouter ; i++)
-	{
-		if ( i!= sourceRouter )
-		{
-			printLsPath(i);
-			cout<<endl;
-		}
-	}
-}
-
-void
-LinkStateRoutingTableCalculator::printLsPath(int destRouter)
-{
-	if (parent[destRouter] != EMPTY_PARENT )
-	{
-		printLsPath(parent[destRouter]);
-	}
-
-	cout<<" "<<destRouter;
-}
-
-void 
-LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
-                                             double *dist,int start,int element)
-{
-	for ( int i=start ; i < element ; i ++) 
-	{
-		for( int j=i+1; j<element; j ++)
-		{
-			if (dist[Q[j]] < dist[Q[i]])
-			{
-				int tempU=Q[j];
-				Q[j]=Q[i];
-				Q[i]=tempU;
-			}
-		}
-	}
-
-}
-
-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::allocateParent()
-{
-	parent=new int[numOfRouter];
-}
-
-void 
-LinkStateRoutingTableCalculator::allocateDistance()
-{
-	distance= new double[numOfRouter];
-}
-
-void 
-LinkStateRoutingTableCalculator::freeParent()
-{
-	delete [] parent;
-}
-
-void LinkStateRoutingTableCalculator::freeDistance()
-{
-	delete [] distance;
-}
-
-
-
-void
-HypRoutingTableCalculator::calculatePath(Map& pMap, 
-                                                  RoutingTable& rt, nlsr& pnlsr)
-{
-	makeAdjMatrix(pnlsr,pMap);
-	string routerName=pnlsr.getConfParameter().getRouterPrefix();
-	int sourceRouter=pMap.getMappingNoByRouterName(routerName);
-	int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
-	setNoLink(noLink);
-	allocateLinks();
-	allocateLinkCosts();
-
-	getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
-
-	for(int i=0 ; i < numOfRouter ; ++i)
-	{
-			int k=0;
-			if ( i != sourceRouter)
-			{
-				allocateLinkFaces();
-				allocateDistanceToNeighbor();
-				allocateDistFromNbrToDest();
-
-				for(int j=0; j<vNoLink; j++)
-				{
-					string nextHopRouterName=pMap.getRouterNameByMappingNo(links[j]);
-					int nextHopFace=
-              pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
-          double distToNbr=getHyperbolicDistance(pnlsr,pMap,
-                                                         sourceRouter,links[j]);
-					double distToDestFromNbr=getHyperbolicDistance(pnlsr, 
-					                                                    pMap,links[j],i);
-					if ( distToDestFromNbr >= 0 )
-					{
-							linkFaces[k] = nextHopFace;
-							distanceToNeighbor[k] = distToNbr;
-							distFromNbrToDest[k] = distToDestFromNbr;
-							k++;
-					}
-				}
-
-				addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
-
-				freeLinkFaces();
-				freeDistanceToNeighbor();
-				freeDistFromNbrToDest();	
-			}
-	}
-
-	freeLinks();
-	freeLinksCosts();
-	freeAdjMatrix();
-}
-
-void
-HypRoutingTableCalculator::addHypNextHopsToRoutingTable(nlsr& pnlsr,Map& pMap,
-                                        RoutingTable& rt, int noFaces, int dest)
-{
-	for(int i=0 ; i < noFaces ; ++i)
-	{
-		string destRouter=pMap.getRouterNameByMappingNo(dest);
-		NextHop nh(linkFaces[i],distFromNbrToDest[i]);
-		rt.addNextHop(destRouter,nh);
-		if( isDryRun == 1 )
-		{
-			rt.addNextHopToDryTable(destRouter,nh);
-		}
-	}
-	
-} 
-
-double 
-HypRoutingTableCalculator::getHyperbolicDistance(nlsr& pnlsr,
-                                                  Map& pMap, int src, int dest)
-{
-	double distance=0.0;
-
-	string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
-	string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
-
-	double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
-	double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
-
-	double destRadius=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorRadius();
-	double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
-
-
-	double diffTheta = fabs (srcTheta - destTheta);
-
-	if (diffTheta > MATH_PI)
-	{
-		diffTheta = 2 * MATH_PI - diffTheta; 	
-	}
-
-	if ( srcRadius != -1 && destRadius != -1 )
-	{
-		if (diffTheta == 0)
-			distance = fabs (srcRadius - destRadius); 
-		else
-			distance = acosh((cosh(srcRadius)*cosh(destRadius))-
-					(sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
-	}else
-	{
-		distance = -1;
-	}
-
-	return distance;
-}
-
-void 
-HypRoutingTableCalculator::allocateLinkFaces()
-{
-	linkFaces=new int[vNoLink];
-}
-
-void 
-HypRoutingTableCalculator::allocateDistanceToNeighbor()
-{
-	distanceToNeighbor=new double[vNoLink];
-}
-
-void 
-HypRoutingTableCalculator::allocateDistFromNbrToDest()
-{
-	distFromNbrToDest=new double[vNoLink];
-}
-
-void 
-HypRoutingTableCalculator::freeLinkFaces()
-{
-	delete [] linkFaces;
-}
-
-void 
-HypRoutingTableCalculator::freeDistanceToNeighbor()
-{
-	delete [] distanceToNeighbor;
-}
-
-void 
-HypRoutingTableCalculator::freeDistFromNbrToDest()
-{
-	delete [] distFromNbrToDest;
-}
diff --git a/nlsr_rtc.hpp b/nlsr_rtc.hpp
deleted file mode 100644
index cba183b..0000000
--- a/nlsr_rtc.hpp
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef NLSR_RTC_HPP
-#define NLSR_RTC_HPP
-
-#include <list>
-#include <iostream>
-
-
-
-class Map;
-class RoutingTable;
-class nlsr;
-
-
-using namespace std;
-
-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);
-
-	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();
-
-
-	
-
-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;
-
-};
-
-#endif
diff --git a/nlsr_rte.cpp b/nlsr_rte.cpp
deleted file mode 100644
index cc9feab..0000000
--- a/nlsr_rte.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <iostream>
-#include <string>
-
-#include "nlsr_rte.hpp"
-
-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;
-}
diff --git a/nlsr_rte.hpp b/nlsr_rte.hpp
deleted file mode 100644
index 6f64836..0000000
--- a/nlsr_rte.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef NLSR_RTE_HPP
-#define NLSR_RTE_HPP
-
-#include<iostream>
-
-#include "nlsr_nhl.hpp"
-
-using namespace std;
-
-class RoutingTableEntry
-{
-public:
-	RoutingTableEntry()
-		: destination()
-		, nhl()
-	{
-		
-	}
-
-	~RoutingTableEntry()
-	{
-	}
-
-	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);
-
-#endif
diff --git a/nlsr_sm.cpp b/nlsr_sm.cpp
deleted file mode 100644
index 4a1706d..0000000
--- a/nlsr_sm.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <string>
-#include <iostream>
-#include "nlsr_sm.hpp"
-
-using namespace std;
-
-class nlsr;
-
-
diff --git a/nlsr_sm.hpp b/nlsr_sm.hpp
deleted file mode 100644
index 542203b..0000000
--- a/nlsr_sm.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef NLSR_SM_HPP
-#define NLSR_SM_HPP
-
-#include<list>
-#include<string>
-#include <ndn-cpp-dev/face.hpp>
-
-
-using namespace std;
-
-class SequencingManager
-{
-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;
-	}
-
-	void setNameLsaSeq(uint32_t nlsn){
-		nameLsaSeq=nlsn;
-	}
-
-	uint32_t getAdjLsaSeq()
-	{
-		return adjLsaSeq;
-	}
-
-	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;
-};
-
-#endif
diff --git a/nlsr_test.cpp b/nlsr_test.cpp
deleted file mode 100644
index ef19e63..0000000
--- a/nlsr_test.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
-
-#include "nlsr.hpp"
-#include "nlsr_test.hpp"
-
-using namespace std;
-using namespace ndn;
-
-void 
-nlsrTest::schedlueAddingLsas(nlsr& pnlsr)
-{
-	// 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));
-
-	//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::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);
-	
-}
-	                                                
diff --git a/nlsr_test.hpp b/nlsr_test.hpp
deleted file mode 100644
index e6e7dfd..0000000
--- a/nlsr_test.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef NLSR_TEST_HPP
-#define NLSR_TEST_HPP
-
-#include <iostream>
-#include <string>
-
-#include "nlsr_lsdb.hpp"
-#include "nlsr_lsa.hpp"
-#include "nlsr_adl.hpp"
-#include "nlsr_npl.hpp"
-#include "nlsr_adjacent.hpp"
-
-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);
-
-};
-
-#endif
diff --git a/nlsr_tokenizer.cpp b/nlsr_tokenizer.cpp
deleted file mode 100644
index e03d2d2..0000000
--- a/nlsr_tokenizer.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include <iostream>
-#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <string>
-#include <algorithm>
-
-#include "nlsr_tokenizer.hpp"
-
-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;
-
-	for ( ;tok_iter != tokens.end(); ++tok_iter){
-		string oneToken(*tok_iter);
-		this->insertToken(oneToken);
-		restOfTheLine+=oneToken;
-		restOfTheLine+=seps;
-  	}
-
-	trim(restOfTheLine);
-}
-
-void 
-nlsrTokenizer::insertToken(const string& token){
-	tokenList.push_back(token);
-}
-
-int 
-nlsrTokenizer::getTokenPosition(string& token){
-	int pos=-1;
-	int i=1;
-
-	for(std::list<string>::iterator it=tokenList.begin();it!=tokenList.end();it++){
-		if( (*it) == token ){
-			break;
-		}
-		i++;
-	}
-
-	if( i < tokenList.size() ){
-		pos=i;
-	}
-
-	return pos;
-}
-
-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;
-				
-			}
-			
-		}
-	}
-
-	trim(returnString);
-	return returnString;
-}
-
-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;
-}
-
-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;
-}
diff --git a/nlsr_tokenizer.hpp b/nlsr_tokenizer.hpp
deleted file mode 100644
index 9363462..0000000
--- a/nlsr_tokenizer.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef NLSR_TOKENIZER_HPP
-#define NLSR_TOKENIZER_HPP
-
-#include <iostream>
-#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <string>
-#include <list>
-#include <ndn-cpp-dev/face.hpp>
-
-using namespace std;
-using namespace boost;
-
-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;
-		}
-
-		string getRestOfLine(){
-			return restOfTheLine;
-		}
-
-		int getTokenPosition(string& token);
-		string getTokenString(int from , int to);
-		string getTokenString(int from);
-		bool doesTokenExist(string token);
-
-	private:
-
-		void makeToken();
-		void insertToken(const string& token);
-	
-		string seps;
-		string originalString;
-		string firstToken;
-		string restOfTheLine;
-		std::list<string> tokenList;
-};
-
-#endif
