diff --git a/src/nlsr.cpp b/src/nlsr.cpp
new file mode 100644
index 0000000..f1b5d93
--- /dev/null
+++ b/src/nlsr.cpp
@@ -0,0 +1,126 @@
+#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/src/nlsr.hpp b/src/nlsr.hpp
new file mode 100644
index 0000000..5ff2ef7
--- /dev/null
+++ b/src/nlsr.hpp
@@ -0,0 +1,231 @@
+#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/src/nlsr_adjacent.cpp b/src/nlsr_adjacent.cpp
new file mode 100644
index 0000000..8a1c048
--- /dev/null
+++ b/src/nlsr_adjacent.cpp
@@ -0,0 +1,35 @@
+#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/src/nlsr_adjacent.hpp b/src/nlsr_adjacent.hpp
new file mode 100644
index 0000000..910b8a9
--- /dev/null
+++ b/src/nlsr_adjacent.hpp
@@ -0,0 +1,81 @@
+#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/src/nlsr_adl.cpp b/src/nlsr_adl.cpp
new file mode 100644
index 0000000..eaf0699
--- /dev/null
+++ b/src/nlsr_adl.cpp
@@ -0,0 +1,264 @@
+#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/src/nlsr_adl.hpp b/src/nlsr_adl.hpp
new file mode 100644
index 0000000..0d868ae
--- /dev/null
+++ b/src/nlsr_adl.hpp
@@ -0,0 +1,54 @@
+#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/src/nlsr_conf_param.cpp b/src/nlsr_conf_param.cpp
new file mode 100644
index 0000000..8ae7647
--- /dev/null
+++ b/src/nlsr_conf_param.cpp
@@ -0,0 +1,27 @@
+#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/src/nlsr_conf_param.hpp b/src/nlsr_conf_param.hpp
new file mode 100644
index 0000000..817bf2e
--- /dev/null
+++ b/src/nlsr_conf_param.hpp
@@ -0,0 +1,209 @@
+#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/src/nlsr_conf_processor.cpp b/src/nlsr_conf_processor.cpp
new file mode 100644
index 0000000..939aa56
--- /dev/null
+++ b/src/nlsr_conf_processor.cpp
@@ -0,0 +1,385 @@
+#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/src/nlsr_conf_processor.hpp b/src/nlsr_conf_processor.hpp
new file mode 100644
index 0000000..1a1ff8a
--- /dev/null
+++ b/src/nlsr_conf_processor.hpp
@@ -0,0 +1,46 @@
+#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/src/nlsr_dm.cpp b/src/nlsr_dm.cpp
new file mode 100644
index 0000000..46b278d
--- /dev/null
+++ b/src/nlsr_dm.cpp
@@ -0,0 +1,82 @@
+#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/src/nlsr_dm.hpp b/src/nlsr_dm.hpp
new file mode 100644
index 0000000..923d2fa
--- /dev/null
+++ b/src/nlsr_dm.hpp
@@ -0,0 +1,26 @@
+#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/src/nlsr_fe.cpp b/src/nlsr_fe.cpp
new file mode 100644
index 0000000..1b9621f
--- /dev/null
+++ b/src/nlsr_fe.cpp
@@ -0,0 +1,45 @@
+#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/src/nlsr_fe.hpp b/src/nlsr_fe.hpp
new file mode 100644
index 0000000..8392dfb
--- /dev/null
+++ b/src/nlsr_fe.hpp
@@ -0,0 +1,56 @@
+#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/src/nlsr_fib.cpp b/src/nlsr_fib.cpp
new file mode 100644
index 0000000..399584f
--- /dev/null
+++ b/src/nlsr_fib.cpp
@@ -0,0 +1,163 @@
+#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/src/nlsr_fib.hpp b/src/nlsr_fib.hpp
new file mode 100644
index 0000000..453b7db
--- /dev/null
+++ b/src/nlsr_fib.hpp
@@ -0,0 +1,39 @@
+#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/src/nlsr_im.cpp b/src/nlsr_im.cpp
new file mode 100644
index 0000000..6ae0131
--- /dev/null
+++ b/src/nlsr_im.cpp
@@ -0,0 +1,154 @@
+#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/src/nlsr_im.hpp b/src/nlsr_im.hpp
new file mode 100644
index 0000000..6e71500
--- /dev/null
+++ b/src/nlsr_im.hpp
@@ -0,0 +1,37 @@
+#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/src/nlsr_lsa.cpp b/src/nlsr_lsa.cpp
new file mode 100644
index 0000000..6eebb16
--- /dev/null
+++ b/src/nlsr_lsa.cpp
@@ -0,0 +1,238 @@
+#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/src/nlsr_lsa.hpp b/src/nlsr_lsa.hpp
new file mode 100644
index 0000000..0f3e528
--- /dev/null
+++ b/src/nlsr_lsa.hpp
@@ -0,0 +1,194 @@
+#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/src/nlsr_lsdb.cpp b/src/nlsr_lsdb.cpp
new file mode 100644
index 0000000..9e3ffe7
--- /dev/null
+++ b/src/nlsr_lsdb.cpp
@@ -0,0 +1,685 @@
+#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/src/nlsr_lsdb.hpp b/src/nlsr_lsdb.hpp
new file mode 100644
index 0000000..62c91ee
--- /dev/null
+++ b/src/nlsr_lsdb.hpp
@@ -0,0 +1,76 @@
+#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/src/nlsr_map.cpp b/src/nlsr_map.cpp
new file mode 100644
index 0000000..3c4ee86
--- /dev/null
+++ b/src/nlsr_map.cpp
@@ -0,0 +1,117 @@
+#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/src/nlsr_map.hpp b/src/nlsr_map.hpp
new file mode 100644
index 0000000..c02104a
--- /dev/null
+++ b/src/nlsr_map.hpp
@@ -0,0 +1,84 @@
+#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/src/nlsr_nexthop.cpp b/src/nlsr_nexthop.cpp
new file mode 100644
index 0000000..7af0bd4
--- /dev/null
+++ b/src/nlsr_nexthop.cpp
@@ -0,0 +1,8 @@
+#include "nlsr_nexthop.hpp"
+
+ostream&
+operator<<(ostream& os, NextHop& nh)
+{
+	os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
+	return os;
+}
diff --git a/src/nlsr_nexthop.hpp b/src/nlsr_nexthop.hpp
new file mode 100644
index 0000000..17393c6
--- /dev/null
+++ b/src/nlsr_nexthop.hpp
@@ -0,0 +1,51 @@
+#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/src/nlsr_nhl.cpp b/src/nlsr_nhl.cpp
new file mode 100644
index 0000000..4fe50aa
--- /dev/null
+++ b/src/nlsr_nhl.cpp
@@ -0,0 +1,81 @@
+#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/src/nlsr_nhl.hpp b/src/nlsr_nhl.hpp
new file mode 100644
index 0000000..0d381f5
--- /dev/null
+++ b/src/nlsr_nhl.hpp
@@ -0,0 +1,49 @@
+#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/src/nlsr_npl.cpp b/src/nlsr_npl.cpp
new file mode 100644
index 0000000..b278699
--- /dev/null
+++ b/src/nlsr_npl.cpp
@@ -0,0 +1,63 @@
+#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/src/nlsr_npl.hpp b/src/nlsr_npl.hpp
new file mode 100644
index 0000000..3a0393a
--- /dev/null
+++ b/src/nlsr_npl.hpp
@@ -0,0 +1,34 @@
+#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/src/nlsr_npt.cpp b/src/nlsr_npt.cpp
new file mode 100644
index 0000000..ba516e5
--- /dev/null
+++ b/src/nlsr_npt.cpp
@@ -0,0 +1,140 @@
+#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/src/nlsr_npt.hpp b/src/nlsr_npt.hpp
new file mode 100644
index 0000000..8ceae33
--- /dev/null
+++ b/src/nlsr_npt.hpp
@@ -0,0 +1,29 @@
+#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/src/nlsr_npte.cpp b/src/nlsr_npte.cpp
new file mode 100644
index 0000000..65f2722
--- /dev/null
+++ b/src/nlsr_npte.cpp
@@ -0,0 +1,78 @@
+#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/src/nlsr_npte.hpp b/src/nlsr_npte.hpp
new file mode 100644
index 0000000..49f763a
--- /dev/null
+++ b/src/nlsr_npte.hpp
@@ -0,0 +1,56 @@
+#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/src/nlsr_params.hpp b/src/nlsr_params.hpp
new file mode 100644
index 0000000..a5f11c5
--- /dev/null
+++ b/src/nlsr_params.hpp
@@ -0,0 +1,12 @@
+#ifndef NLSR_PARAMS_HPP
+#define NLSR_PARAMS_HPP
+
+class nlsrParams{
+
+	
+
+
+
+};
+
+#endif
diff --git a/src/nlsr_rt.cpp b/src/nlsr_rt.cpp
new file mode 100644
index 0000000..efa423a
--- /dev/null
+++ b/src/nlsr_rt.cpp
@@ -0,0 +1,229 @@
+#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/src/nlsr_rt.hpp b/src/nlsr_rt.hpp
new file mode 100644
index 0000000..ef54742
--- /dev/null
+++ b/src/nlsr_rt.hpp
@@ -0,0 +1,45 @@
+#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/src/nlsr_rtc.cpp b/src/nlsr_rtc.cpp
new file mode 100644
index 0000000..539c6e9
--- /dev/null
+++ b/src/nlsr_rtc.cpp
@@ -0,0 +1,525 @@
+#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/src/nlsr_rtc.hpp b/src/nlsr_rtc.hpp
new file mode 100644
index 0000000..cba183b
--- /dev/null
+++ b/src/nlsr_rtc.hpp
@@ -0,0 +1,142 @@
+#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/src/nlsr_rte.cpp b/src/nlsr_rte.cpp
new file mode 100644
index 0000000..cc9feab
--- /dev/null
+++ b/src/nlsr_rte.cpp
@@ -0,0 +1,21 @@
+#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/src/nlsr_rte.hpp b/src/nlsr_rte.hpp
new file mode 100644
index 0000000..6f64836
--- /dev/null
+++ b/src/nlsr_rte.hpp
@@ -0,0 +1,48 @@
+#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/src/nlsr_sm.cpp b/src/nlsr_sm.cpp
new file mode 100644
index 0000000..4a1706d
--- /dev/null
+++ b/src/nlsr_sm.cpp
@@ -0,0 +1,9 @@
+#include <string>
+#include <iostream>
+#include "nlsr_sm.hpp"
+
+using namespace std;
+
+class nlsr;
+
+
diff --git a/src/nlsr_sm.hpp b/src/nlsr_sm.hpp
new file mode 100644
index 0000000..542203b
--- /dev/null
+++ b/src/nlsr_sm.hpp
@@ -0,0 +1,61 @@
+#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/src/nlsr_test.cpp b/src/nlsr_test.cpp
new file mode 100644
index 0000000..ef19e63
--- /dev/null
+++ b/src/nlsr_test.cpp
@@ -0,0 +1,104 @@
+#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/src/nlsr_test.hpp b/src/nlsr_test.hpp
new file mode 100644
index 0000000..e6e7dfd
--- /dev/null
+++ b/src/nlsr_test.hpp
@@ -0,0 +1,34 @@
+#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/src/nlsr_tokenizer.cpp b/src/nlsr_tokenizer.cpp
new file mode 100644
index 0000000..e03d2d2
--- /dev/null
+++ b/src/nlsr_tokenizer.cpp
@@ -0,0 +1,116 @@
+#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/src/nlsr_tokenizer.hpp b/src/nlsr_tokenizer.hpp
new file mode 100644
index 0000000..9363462
--- /dev/null
+++ b/src/nlsr_tokenizer.hpp
@@ -0,0 +1,59 @@
+#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
diff --git a/waf b/waf
new file mode 100755
index 0000000..d45d28b
--- /dev/null
+++ b/waf
Binary files differ
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..ce05b4b
--- /dev/null
+++ b/wscript
@@ -0,0 +1,79 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+VERSION='1.0.0'
+APPNAME='nlsr'
+
+from waflib import Configure, Build, Logs
+
+def options(opt):
+    opt.load('compiler_cxx boost')
+    # opt.load('ndnx', tooldir=["waf-tools"])
+
+    syncopt = opt.add_option_group ("nlsr Options")
+
+    syncopt.add_option('--debug',action='store_true',default=False,dest='debug',help='''debugging mode''')
+
+def configure(conf):
+    conf.load('compiler_cxx boost')
+
+    if conf.options.debug:
+        conf.define ('_DEBUG', 1)
+        conf.add_supported_cxxflags (cxxflags = ['-O0',
+                                                 '-Wall',
+                                                 '-Wno-unused-variable',
+                                                 '-g3',
+                                                 '-Wno-unused-private-field', # only clang supports
+                                                 '-fcolor-diagnostics',       # only clang supports
+                                                 '-Qunused-arguments',         # only clang supports
+                                                 '-Wno-tautological-compare', # suppress warnings from CryptoPP
+                                                 '-Wno-deprecated-declarations'
+                                                 ])
+    else:
+        conf.add_supported_cxxflags (cxxflags = ['-O3',
+                                                 '-g',
+                                                 '-Wno-unused-variable',
+                                                 '-Wno-tautological-compare', 
+                                                 '-Wno-unused-function', 
+                                                 '-Wno-deprecated-declarations'
+                                                 ])
+
+    conf.check_cfg(package='libndn-cpp-dev', args=['--cflags', '--libs'], uselib_store='NDNCPP', mandatory=True)
+
+    conf.check_boost(lib='system iostreams thread unit_test_framework', mandatory=True)
+    
+    conf.check_cfg(package='ChronoSync', args=['--cflags', '--libs'], uselib_store='ChronoSync', mandatory=True)
+
+
+
+def build (bld):
+    bld (
+        # vnum = "1.0.0",
+        features=['cxx', 'cxxprogram'],
+        target="nlsr",
+        source = bld.path.ant_glob('src/*.cpp'),
+        use = 'BOOST NDNCPP ChronoSync',
+        #cwd = bld.path.find_dir ("src"),
+        #includes = ['src'],
+        )
+
+    #bld.install_files (
+     #   dest = "%s/nlsr" % bld.env['INCLUDEDIR'], 
+     #   files = bld.path.ant_glob(['*.hpp']), 
+     #   cwd = bld.path.find_dir ("src"),
+     #   relative_trick = True,
+     #  )
+
+@Configure.conf
+def add_supported_cxxflags(self, cxxflags):
+    """
+    Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
+    """
+    self.start_msg('Checking allowed flags for c++ compiler')
+
+    supportedFlags = []
+    for flag in cxxflags:
+        if self.check_cxx (cxxflags=[flag], mandatory=False):
+            supportedFlags += [flag]
+
+    self.end_msg (' '.join (supportedFlags))
+    self.env.CXXFLAGS += supportedFlags
