FIB manipaulation done
diff --git a/nlsr.hpp b/nlsr.hpp
index 52d5277..460f2f1 100644
--- a/nlsr.hpp
+++ b/nlsr.hpp
@@ -13,6 +13,8 @@
 #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"
 
@@ -41,6 +43,8 @@
     , isRouteCalculationScheduled(0)
     , isRoutingTableCalculating(0)
     , routingTable()
+    , npt()
+    , fib()
     , nlsrTesting()
 	{
 		isDaemonProcess=false;
@@ -123,6 +127,16 @@
 		return routingTable;
 	}
 
+	Npt& getNpt()
+	{
+		return npt;
+	}
+
+	Fib& getFib()
+	{
+		return fib;
+	}
+
 	long int getAdjBuildCount()
 	{
 		return adjBuildCount;
@@ -200,7 +214,8 @@
 	
 	Lsdb nlsrLsdb;
 	RoutingTable routingTable;
-	
+	Npt npt;
+	Fib fib;
 	
 
 	long int adjBuildCount;
diff --git a/nlsr_fe.cpp b/nlsr_fe.cpp
new file mode 100644
index 0000000..350270e
--- /dev/null
+++ b/nlsr_fe.cpp
@@ -0,0 +1,44 @@
+#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<<fe.getNhl()<<endl;
+	return os;
+}
diff --git a/nlsr_fe.hpp b/nlsr_fe.hpp
new file mode 100644
index 0000000..c3af73b
--- /dev/null
+++ b/nlsr_fe.hpp
@@ -0,0 +1,44 @@
+#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()
+	{
+	}
+
+	FibEntry(string n)
+	{
+		name=n;
+	}	
+
+	string getName()
+	{
+		return name;
+	}
+
+	Nhl& getNhl()
+	{
+		return nhl;
+	}
+
+	bool isEqualNextHops(Nhl &nhlOther);
+	
+private:
+	string name;
+	Nhl nhl;
+};
+
+ostream& operator<<(ostream& os, FibEntry& fe);
+
+#endif
diff --git a/nlsr_fib.cpp b/nlsr_fib.cpp
new file mode 100644
index 0000000..a1e4968
--- /dev/null
+++ b/nlsr_fib.cpp
@@ -0,0 +1,132 @@
+#include<list>
+#include "nlsr_fe.hpp"
+#include "nlsr_fib.hpp"
+#include "nlsr_nhl.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);
+  }
+}
+
+/**
+If NHL is equal for current FIB and NPT then to change
+Otherwise
+ Add the first Nexthop to FIB
+ remove all old nexthop from FIB
+ And add all other Nexthop to FIB
+*/
+
+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() )
+  {
+  		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));
+  			}
+  		}
+  }
+  else
+  {
+  		FibEntry newEntry(name);
+  		for(std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+  															nhit!=nextHopList.getNextHopList().end();++nhit)
+  		{
+  			newEntry.getNhl().addNextHop((*nhit));
+  		}
+  		fibTable.push_back(newEntry);	
+  }
+}
+
+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 doNotRemoveHop)
+{
+	for( std::list<NextHop >::iterator it=nl.getNextHopList().begin(); 
+	                                      it != nl.getNextHopList().end();   ++it)
+	{
+		if ( (*it).getConnectingFace() != doNotRemoveHop )
+		{
+			nl.getNextHopList().erase(it);
+		}
+	}
+}
+
+
+int 
+Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+{
+	int endFace=0;
+  	if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
+  	{
+  		return nextHopList.getNhlSize();
+  	}
+  	else
+  	{
+  		return maxFacesPerPrefix;
+  	}
+
+  	return endFace;
+}
+
+void
+Fib::printFib()
+{
+	cout<<"-------------------FIB-----------------------------"<<endl;
+	for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
+	                                                                         ++it)
+	{
+		cout<<(*it);
+	}
+}
diff --git a/nlsr_fib.hpp b/nlsr_fib.hpp
new file mode 100644
index 0000000..f1f54ed
--- /dev/null
+++ b/nlsr_fib.hpp
@@ -0,0 +1,31 @@
+#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 cleanFib();
+	void printFib();
+
+private:
+	void removeFibEntryHop(Nhl& nl, int doNotRemoveHop);
+	int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
+	
+private:
+	std::list<FibEntry> fibTable;	
+};
+
+#endif
diff --git a/nlsr_lsa.hpp b/nlsr_lsa.hpp
index 2a7294a..a75f572 100644
--- a/nlsr_lsa.hpp
+++ b/nlsr_lsa.hpp
@@ -84,6 +84,11 @@
 		npl.insertIntoNpl(name);
 	}
 
+	void removeNameFromLsa(string& name)
+	{
+		npl.removeFromNpl(name);
+	}
+
 	string getNameLsaKey();
 
 	string getNameLsaData();
diff --git a/nlsr_lsdb.cpp b/nlsr_lsdb.cpp
index 855f1c7..3177fc8 100644
--- a/nlsr_lsdb.cpp
+++ b/nlsr_lsdb.cpp
@@ -1,36 +1,10 @@
 #include<string>
+#include<utility>
 #include "nlsr_lsdb.hpp"
 #include "nlsr.hpp"
 
 using namespace std;
 
-
-
-
-
-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;
-	
-}
-
-//Name LSA and LSDB related functions start here
-
-
 static bool
 nameLsaCompareByKey(NameLsa& nlsa1, string& key){
 	return nlsa1.getNameLsaKey()==key;
@@ -46,11 +20,11 @@
 					, pnlsr.getConfParameter().getRouterDeadInterval()
 					, pnlsr.getNpl() );
 	pnlsr.getSm().setNameLsaSeq(pnlsr.getSm().getNameLsaSeq()+1);
-	return installNameLsa(nameLsa);
+	return installNameLsa(pnlsr,nameLsa);
 
 }
 
-NameLsa& 
+std::pair<NameLsa&, bool> 
 Lsdb::getNameLsa(string key)
 {
 	std::list<NameLsa >::iterator it = std::find_if( nameLsdb.begin(), 
@@ -59,31 +33,77 @@
 
 	if( it != nameLsdb.end())
 	{
-		return (*it);
+		return std::make_pair(boost::ref((*it)),true);
 	}
 
+	NameLsa nlsa;
+	return std::make_pair(boost::ref(nlsa),false);
+
 }
 
 
 
 bool 
-Lsdb::installNameLsa(NameLsa &nlsa)
+Lsdb::installNameLsa(nlsr& pnlsr, NameLsa &nlsa)
 {
-	bool doesLsaExist_ = doesNameLsaExist(nlsa.getNameLsaKey());
-	if ( !doesLsaExist_ )
+	std::pair<NameLsa& , bool> chkNameLsa=getNameLsa(nlsa.getNameLsaKey());
+	if ( !chkNameLsa.second )
 	{
-		// add name LSA
 		addNameLsa(nlsa);
-		// update NPT and FIB
-		// if its not own LSA
 		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++)
+			{
+				pnlsr.getNpt().addNpte((*it),nlsa.getOrigRouter(),pnlsr);
+			}
+		} 
 	}
 	else
 	{
-		// check for newer name LSA
-		NameLsa oldNameLsa=getNameLsa(nlsa.getNameLsaKey());
-		// Discard or Update Name lsa, NPT, FIB
-		// if its not own LSA
+		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() )
+      		{
+      			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() )
+      		{
+      			pnlsr.getNpt().removeNpte((*it),nlsa.getOrigRouter(),pnlsr);
+      		}
+      }  
+			
+		}
 	}
 	
 	return true;
@@ -169,7 +189,7 @@
 	return true;
 }
 
-CorLsa& 
+std::pair<CorLsa&, bool> 
 Lsdb::getCorLsa(string key)
 {
 	std::list< CorLsa >::iterator it = std::find_if( corLsdb.begin(), 
@@ -177,19 +197,26 @@
    																	bind(corLsaCompareByKey, _1, key));
 
 	if( it != corLsdb.end()){
-		return (*it);
+		return std::make_pair(boost::ref((*it)), true);
 	}
+
+	CorLsa clsa;
+	return std::make_pair(boost::ref(clsa),false);
 }
 
 bool 
 Lsdb::installCorLsa(nlsr& pnlsr, CorLsa &clsa)
 {
-	bool doesLsaExist_ = doesCorLsaExist(clsa.getCorLsaKey());
-	if ( !doesLsaExist_ )
+	std::pair<CorLsa& , bool> chkCorLsa=getCorLsa(clsa.getCorLsaKey());
+	if ( !chkCorLsa.second )
 	{
 		// add cor LSA
 		addCorLsa(clsa);
 		printCorLsdb(); //debugging purpose
+		if ( clsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+		{
+			pnlsr.getNpt().addNpte(clsa.getOrigRouter(),clsa.getOrigRouter(),pnlsr);
+		}
 		//schedule routing table calculation only if 
 		//hyperbolic calculation is scheduled
 		if (pnlsr.getConfParameter().getIsHyperbolicCalc() >=1 )
@@ -207,7 +234,7 @@
 	else
 	{
 		// check for newer cor LSA
-		CorLsa oldCorLsa=getCorLsa(clsa.getCorLsaKey());
+		//CorLsa oldCorLsa=getCorLsa(clsa.getCorLsaKey());
 		
 	}
 	
@@ -336,7 +363,7 @@
 	
 }
 
-AdjLsa& 
+std::pair<AdjLsa& , bool> 
 Lsdb::getAdjLsa(string key)
 {
 	std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(), 
@@ -344,18 +371,28 @@
    																	bind(adjLsaCompareByKey, _1, key));
 
 	if( it != adjLsdb.end()){
-		return (*it);
+		return std::make_pair(boost::ref((*it)),true);
 	}
+
+	AdjLsa alsa;
+	return std::make_pair(boost::ref(alsa),false);
 }
 
 bool 
 Lsdb::installAdjLsa(nlsr& pnlsr, AdjLsa &alsa)
 {
-	bool doesLsaExist_ = doesAdjLsaExist(alsa.getAdjLsaKey());
-	if ( !doesLsaExist_ )
+	//bool doesLsaExist_ = doesAdjLsaExist(alsa.getAdjLsaKey());
+	//if ( !doesLsaExist_ )
+	std::pair<AdjLsa& , bool> chkAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
+	if ( !chkAdjLsa.second )
 	{
 		// add Adj LSA
 		addAdjLsa(alsa);
+		// adding a NPT entry for router itself
+		if ( alsa.getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
+		{
+			pnlsr.getNpt().addNpte(alsa.getOrigRouter(),alsa.getOrigRouter(),pnlsr);
+		}
 		// schedule routing table calculation
 		if ( pnlsr.getIsRouteCalculationScheduled() != 1 )
 		{
@@ -368,7 +405,7 @@
 	else
 	{
 		// check for newer name LSA
-		AdjLsa oldAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
+		//AdjLsa oldAdjLsa=getAdjLsa(alsa.getAdjLsaKey());
 		
 	}
 
@@ -436,3 +473,24 @@
 	}
 }
 
+//-----utility function -----
+bool 
+Lsdb::doesLsaExist(string key, int lsType)
+{
+	if ( lsType == 1)
+	{
+		return doesNameLsaExist(key);
+	}
+	else if ( lsType == 2)
+	{
+		return doesAdjLsaExist(key);
+	}
+	else if ( lsType == 3)
+	{
+		return doesCorLsaExist(key);
+	}
+	
+	return false;	
+}
+
+
diff --git a/nlsr_lsdb.hpp b/nlsr_lsdb.hpp
index 5961b98..5d278ea 100644
--- a/nlsr_lsdb.hpp
+++ b/nlsr_lsdb.hpp
@@ -1,6 +1,7 @@
 #ifndef NLSR_LSDB_HPP
 #define NLSR_LSDB_HPP
 
+#include <utility>
 #include "nlsr_lsa.hpp"
 
 using namespace std;
@@ -17,14 +18,14 @@
 	bool doesLsaExist(string key, int lsType);
 	// function related to Name LSDB 
 	bool buildAndInstallOwnNameLsa(nlsr& pnlsr);
-	NameLsa& getNameLsa(string key);
-	bool installNameLsa(NameLsa &nlsa);
+	std::pair<NameLsa&, bool>  getNameLsa(string key);
+	bool installNameLsa(nlsr& pnlsr, NameLsa &nlsa);
 	bool removeNameLsa(string& key);
 	void printNameLsdb(); //debugging
 
 	//function related to Cor LSDB
 	bool buildAndInstallOwnCorLsa(nlsr& pnlsr);
-	CorLsa& getCorLsa(string key);
+	std::pair<CorLsa&, bool> getCorLsa(string key);
 	bool installCorLsa(nlsr& pnlsr, CorLsa &clsa);
 	bool removeCorLsa(string& key);
 	void printCorLsdb(); //debugging
@@ -34,7 +35,7 @@
 	bool buildAndInstallOwnAdjLsa(nlsr& pnlsr);
 	bool removeAdjLsa(string& key);
 	bool installAdjLsa(nlsr& pnlsr, AdjLsa &alsa);
-	AdjLsa& getAdjLsa(string key);
+	std::pair<AdjLsa& , bool> getAdjLsa(string key);
 	std::list<AdjLsa>& getAdjLsdb();
 	void printAdjLsdb();
 	
diff --git a/nlsr_nhl.cpp b/nlsr_nhl.cpp
index 6654e8e..4fe50aa 100644
--- a/nlsr_nhl.cpp
+++ b/nlsr_nhl.cpp
@@ -10,6 +10,18 @@
 	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
@@ -33,6 +45,27 @@
 	}
 }
 
+/**
+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)
diff --git a/nlsr_nhl.hpp b/nlsr_nhl.hpp
index 94b77e0..0d381f5 100644
--- a/nlsr_nhl.hpp
+++ b/nlsr_nhl.hpp
@@ -21,6 +21,19 @@
 	{
 	}
 	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;
diff --git a/nlsr_npl.cpp b/nlsr_npl.cpp
index 251c647..b278699 100644
--- a/nlsr_npl.cpp
+++ b/nlsr_npl.cpp
@@ -33,6 +33,26 @@
 
 }
 
+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;
diff --git a/nlsr_npl.hpp b/nlsr_npl.hpp
index 878e4cc..3a0393a 100644
--- a/nlsr_npl.hpp
+++ b/nlsr_npl.hpp
@@ -14,6 +14,8 @@
 	~Npl();
 
 	int insertIntoNpl(string& name);
+	int removeFromNpl(string& name);
+	void sortNpl();
 	int getNplSize()
 	{
 		return nameList.size();
diff --git a/nlsr_npt.cpp b/nlsr_npt.cpp
new file mode 100644
index 0000000..ba516e5
--- /dev/null
+++ b/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/nlsr_npt.hpp b/nlsr_npt.hpp
new file mode 100644
index 0000000..8ceae33
--- /dev/null
+++ b/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/nlsr_npte.cpp b/nlsr_npte.cpp
new file mode 100644
index 0000000..65f2722
--- /dev/null
+++ b/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/nlsr_npte.hpp b/nlsr_npte.hpp
new file mode 100644
index 0000000..49f763a
--- /dev/null
+++ b/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/nlsr_rt.cpp b/nlsr_rt.cpp
index 2487db5..ae7fc88 100644
--- a/nlsr_rt.cpp
+++ b/nlsr_rt.cpp
@@ -7,12 +7,15 @@
 #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 )
 	{
@@ -44,6 +47,12 @@
 				}
 
 				//need to update NPT here
+				pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
+				//debugging purpose
+				printRoutingTable();
+				pnlsr.getNpt().printNpt();
+				pnlsr.getFib().printFib();
+				//debugging purpose end
 			}
 			else
 			{
@@ -58,9 +67,14 @@
 			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
 		}
 
-		printRoutingTable();
 
 		pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
 		pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
@@ -71,6 +85,7 @@
 									 ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
 		pnlsr.setIsRouteCalculationScheduled(1);
 	}
+
 }
 
 
diff --git a/nlsr_rtc.cpp b/nlsr_rtc.cpp
index f7ec5cd..539c6e9 100644
--- a/nlsr_rtc.cpp
+++ b/nlsr_rtc.cpp
@@ -459,26 +459,29 @@
 	string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
 	string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
 
-	double srcRadius=pnlsr.getLsdb().getCorLsa(srcRouterKey).getCorRadius();
-	double srcTheta=pnlsr.getLsdb().getCorLsa(srcRouterKey).getCorTheta();
+	double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
+	double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
 
-	double destRadius=pnlsr.getLsdb().getCorLsa(destRouterKey).getCorRadius();
-	double destTheta=pnlsr.getLsdb().getCorLsa(destRouterKey).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){
+	if (diffTheta > MATH_PI)
+	{
 		diffTheta = 2 * MATH_PI - diffTheta; 	
 	}
 
-	if ( srcRadius != -1 && destRadius != -1 ){
+	if ( srcRadius != -1 && destRadius != -1 )
+	{
 		if (diffTheta == 0)
 			distance = fabs (srcRadius - destRadius); 
 		else
 			distance = acosh((cosh(srcRadius)*cosh(destRadius))-
 					(sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
-	}else{
+	}else
+	{
 		distance = -1;
 	}
 
diff --git a/nlsr_test.cpp b/nlsr_test.cpp
index 6138620..ef19e63 100644
--- a/nlsr_test.cpp
+++ b/nlsr_test.cpp
@@ -17,7 +17,7 @@
 	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/altair/name3");
+	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);
 	
@@ -38,7 +38,7 @@
 	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/maia/name3");
+	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);
 
@@ -79,7 +79,7 @@
 	npl.insertIntoNpl(name2);
 	npl.insertIntoNpl(name3);
 	NameLsa nameLsa(router,1,1,3600,npl);
-	pnlsr.getLsdb().installNameLsa(nameLsa);
+	pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
 	
 }