diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
new file mode 100644
index 0000000..5f4811c
--- /dev/null
+++ b/src/route/nlsr_fe.cpp
@@ -0,0 +1,48 @@
+#include <list>
+#include "nlsr_fe.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    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;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_fe.hpp b/src/route/nlsr_fe.hpp
new file mode 100644
index 0000000..c85e045
--- /dev/null
+++ b/src/route/nlsr_fe.hpp
@@ -0,0 +1,85 @@
+#ifndef NLSR_FE_HPP
+#define NLSR_FE_HPP
+
+#include<list>
+#include <iostream>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_nexthop.hpp"
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class FibEntry
+    {
+    public:
+        FibEntry()
+            : name()
+            , timeToRefresh(0)
+            , feSeqNo(0)
+        {
+        }
+
+        FibEntry(string n)
+        {
+            name=n;
+        }
+
+        string getName()
+        {
+            return name;
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+
+        int getTimeToRefresh()
+        {
+            return timeToRefresh;
+        }
+
+        void setTimeToRefresh(int ttr)
+        {
+            timeToRefresh=ttr;
+        }
+
+        void setFeExpiringEventId(ndn::EventId feid)
+        {
+            feExpiringEventId=feid;
+        }
+
+        ndn::EventId getFeExpiringEventId()
+        {
+            return feExpiringEventId;
+        }
+
+        void setFeSeqNo(int fsn)
+        {
+            feSeqNo=fsn;
+        }
+
+        int getFeSeqNo()
+        {
+            return feSeqNo;
+        }
+
+        bool isEqualNextHops(Nhl &nhlOther);
+
+    private:
+        string name;
+        int timeToRefresh;
+        ndn::EventId feExpiringEventId;
+        int feSeqNo;
+        Nhl nhl;
+    };
+
+    ostream& operator<<(ostream& os, FibEntry& fe);
+
+} //namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
new file mode 100644
index 0000000..8fb7928
--- /dev/null
+++ b/src/route/nlsr_fib.cpp
@@ -0,0 +1,168 @@
+#include<list>
+#include "nlsr_fe.hpp"
+#include "nlsr_fib.hpp"
+#include "nlsr_nhl.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace ndn;
+
+    static bool
+    fibEntryNameCompare(FibEntry& fe, string name)
+    {
+        return fe.getName() == name ;
+    }
+
+    void
+    Fib::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
+    {
+        pnlsr.getScheduler().cancelEvent(eid);
+    }
+
+
+    ndn::EventId
+    Fib::scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                                    int refreshTime)
+    {
+        return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
+                ndn::bind(&Fib::refreshFibEntry,this,name,feSeqNum));
+    }
+
+    void
+    Fib::refreshFibEntry(string name, int feSeqNum)
+    {
+    }
+
+    void
+    Fib::removeFromFib(Nlsr& pnlsr, string name)
+    {
+        std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                            fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+        if( it != fibTable.end() )
+        {
+            for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+            {
+                //remove entry from NDN-FIB
+            }
+            cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+            fibTable.erase(it);
+        }
+    }
+
+
+    void
+    Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        int startFace=0;
+        int endFace=getNumberOfFacesForName(nextHopList,maxFacesPerPrefix);
+        std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                            fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+        if( it != fibTable.end() )
+        {
+            nextHopList.sortNhl();
+            if ( !(*it).isEqualNextHops(nextHopList) )
+            {
+                std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+                (*it).getNhl().addNextHop((*nhit));
+                removeFibEntryHop((*it).getNhl(),(*nhit).getConnectingFace());
+                startFace++;
+                nhit++;
+                for( int i=startFace; i< endFace; nhit++,i++)
+                {
+                    (*it).getNhl().addNextHop((*nhit));
+                }
+                (*it).setTimeToRefresh(fibEntryRefreshTime);
+            }
+            (*it).getNhl().sortNhl();
+            cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+            (*it).setFeSeqNo((*it).getFeSeqNo()+1);
+            (*it).setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                       (*it).getName() ,
+                                       (*it).getFeSeqNo(),fibEntryRefreshTime));
+            //update NDN-FIB
+        }
+        else
+        {
+            nextHopList.sortNhl();
+            FibEntry newEntry(name);
+            std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+            for(int i=startFace; i< endFace ; i++)
+            {
+                newEntry.getNhl().addNextHop((*nhit));
+                ++nhit;
+            }
+            newEntry.getNhl().sortNhl();
+            newEntry.setTimeToRefresh(fibEntryRefreshTime);
+            newEntry.setFeSeqNo(1);
+            fibTable.push_back(newEntry);
+            //cancelScheduledFeExpiringEvent(pnlsr, newEntry().getFeExpiringEventId());
+            //Update NDN-FIB
+        }
+    }
+
+
+
+    void Fib::cleanFib(Nlsr& pnlsr)
+    {
+        for( std::list<FibEntry >::iterator it=fibTable.begin(); it != fibTable.end();
+                ++it)
+        {
+            for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+            {
+                cancelScheduledFeExpiringEvent(pnlsr,(*it).getFeExpiringEventId());
+                //remove entry from NDN-FIB
+            }
+        }
+        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);
+        }
+    }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_fib.hpp b/src/route/nlsr_fib.hpp
new file mode 100644
index 0000000..d93d972
--- /dev/null
+++ b/src/route/nlsr_fib.hpp
@@ -0,0 +1,48 @@
+#ifndef NLSR_FIB_HPP
+#define NLSR_FIB_HPP
+
+#include <list>
+#include "nlsr_fe.hpp"
+
+namespace nlsr
+{
+
+    class Nlsr;
+
+    using namespace std;
+    using namespace ndn;
+
+    class Fib
+    {
+    public:
+        Fib()
+        {
+        }
+
+        void removeFromFib(Nlsr& pnlsr, string name);
+        void updateFib(Nlsr& pnlsr, string name, Nhl& nextHopList,
+                       int maxFacesPerPrefix);
+        void cleanFib(Nlsr& pnlsr);
+        void setFibEntryRefreshTime(int fert)
+        {
+            fibEntryRefreshTime=fert;
+        }
+
+        void printFib();
+
+    private:
+        void removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId);
+        int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
+        ndn::EventId
+        scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                                   int refreshTime);
+        void cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid);
+        void refreshFibEntry(string name, int feSeqNum);
+
+    private:
+        std::list<FibEntry> fibTable;
+        int fibEntryRefreshTime;
+    };
+
+}//namespace nlsr
+#endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
new file mode 100644
index 0000000..47b02ec
--- /dev/null
+++ b/src/route/nlsr_map.cpp
@@ -0,0 +1,124 @@
+#include<iostream>
+#include<list>
+
+#include "nlsr.hpp"
+#include "nlsr_adjacent.hpp"
+#include "nlsr_lsa.hpp"
+#include "nlsr_lsdb.hpp"
+#include "nlsr_map.hpp"
+
+namespace nlsr
+{
+
+    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;
+    }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_map.hpp b/src/route/nlsr_map.hpp
new file mode 100644
index 0000000..0352d1d
--- /dev/null
+++ b/src/route/nlsr_map.hpp
@@ -0,0 +1,88 @@
+#ifndef NLSR_MAP_HPP
+#define NLSR_MAP_HPP
+
+#include <iostream>
+#include <list>
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr
+{
+
+    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);
+
+} // namespace nlsr
+#endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
new file mode 100644
index 0000000..e58b23c
--- /dev/null
+++ b/src/route/nlsr_nexthop.cpp
@@ -0,0 +1,13 @@
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    ostream&
+    operator<<(ostream& os, NextHop& nh)
+    {
+        os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_nexthop.hpp b/src/route/nlsr_nexthop.hpp
new file mode 100644
index 0000000..1361d52
--- /dev/null
+++ b/src/route/nlsr_nexthop.hpp
@@ -0,0 +1,56 @@
+#ifndef NLSR_NEXTHOP_HPP
+#define NLSR_NEXTHOP_HPP
+
+#include<iostream>
+
+namespace nlsr
+{
+
+    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);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
new file mode 100644
index 0000000..2aaa2a6
--- /dev/null
+++ b/src/route/nlsr_nhl.cpp
@@ -0,0 +1,90 @@
+#include <iostream>
+
+#include "nlsr_nhl.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    static bool
+    nexthopCompare(NextHop& nh1, NextHop& nh2)
+    {
+        return nh1.getConnectingFace()==nh2.getConnectingFace();
+    }
+
+    static bool
+    nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+    {
+        return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
+                nh1.getRouteCost() == nh2.getRouteCost()) ;
+    }
+
+    static bool
+    nextHopSortingComparator(NextHop& nh1, NextHop& nh2)
+    {
+        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;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_nhl.hpp b/src/route/nlsr_nhl.hpp
new file mode 100644
index 0000000..9f6bd76
--- /dev/null
+++ b/src/route/nlsr_nhl.hpp
@@ -0,0 +1,54 @@
+#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"
+
+namespace nlsr
+{
+
+    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);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
new file mode 100644
index 0000000..9c4d4cb
--- /dev/null
+++ b/src/route/nlsr_npt.cpp
@@ -0,0 +1,142 @@
+#include <list>
+#include <utility>
+#include <algorithm>
+
+#include "nlsr_npt.hpp"
+#include "nlsr_npte.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+    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(pnlsr, name,newEntry.getNhl(),
+                                     pnlsr.getConfParameter().getMaxFacesPerPrefix());
+        }
+        else
+        {
+            (*it).addRoutingTableEntry(rte);
+            (*it).generateNhlfromRteList();
+            // update FIB here with nhl list from (*it).getNhl()
+            pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl() ,
+                                     pnlsr.getConfParameter().getMaxFacesPerPrefix());
+        }
+    }
+
+    void
+    Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    {
+        std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+                                        npteList.end(), bind(&npteCompare, _1, name));
+        if ( it != npteList.end() )
+        {
+            string destRouter=rte.getDestination();
+            (*it).removeRoutingTableEntry(rte);
+            if ( ((*it).getRteListSize() == 0 ) &&
+                    (!pnlsr.getLsdb().doesLsaExist(destRouter+"/1",1) ) &&
+                    (!pnlsr.getLsdb().doesLsaExist(destRouter+"/2",2) ) &&
+                    (!pnlsr.getLsdb().doesLsaExist(destRouter+"/3",3) )   )
+            {
+                npteList.erase(it); // remove entry from NPT
+                // remove FIB entry with this name
+                pnlsr.getFib().removeFromFib(pnlsr,name);
+            }
+            else
+            {
+                (*it).generateNhlfromRteList();
+                // update FIB entry with new NHL
+                pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl(),
+                                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
+            }
+        }
+    }
+
+
+    void
+    Npt::addNpte(string name, string destRouter, Nlsr& pnlsr)
+    {
+        std::pair<RoutingTableEntry& , bool> rteCheck=
+            pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+        if(rteCheck.second)
+        {
+            addNpte(name,rteCheck.first,pnlsr);
+        }
+        else
+        {
+            RoutingTableEntry rte(destRouter);
+            addNpte(name, rte,pnlsr);
+        }
+    }
+
+    void
+    Npt::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/route/nlsr_npt.hpp b/src/route/nlsr_npt.hpp
new file mode 100644
index 0000000..f4ddbf9
--- /dev/null
+++ b/src/route/nlsr_npt.hpp
@@ -0,0 +1,34 @@
+#ifndef NLSR_NPT_HPP
+#define NLSR_NPT_HPP
+
+#include <list>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class Nlsr;
+
+    class Npt
+    {
+    public:
+        Npt()
+        {
+        }
+        void addNpte(string name, string destRouter, Nlsr& pnlsr);
+        void removeNpte(string name, string destRouter, Nlsr& pnlsr);
+        void updateNptWithNewRoute(Nlsr& pnlsr);
+        void printNpt();
+    private:
+        void addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+        void removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+    private:
+        std::list<Npte> npteList;
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
new file mode 100644
index 0000000..60013ff
--- /dev/null
+++ b/src/route/nlsr_npte.cpp
@@ -0,0 +1,83 @@
+#include <list>
+#include <utility>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    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;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_npte.hpp b/src/route/nlsr_npte.hpp
new file mode 100644
index 0000000..e64328c
--- /dev/null
+++ b/src/route/nlsr_npte.hpp
@@ -0,0 +1,61 @@
+#ifndef NLSR_NPTE_HPP
+#define NLSR_NPTE_HPP
+
+#include <list>
+#include <utility>
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    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);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
new file mode 100644
index 0000000..f9923f2
--- /dev/null
+++ b/src/route/nlsr_rt.cpp
@@ -0,0 +1,231 @@
+#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"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    void
+    RoutingTable::calculate(Nlsr& pnlsr)
+    {
+        //debugging purpose
+        pnlsr.getNpt().printNpt();
+        pnlsr.getLsdb().printAdjLsdb();
+        pnlsr.getLsdb().printCorLsdb();
+        pnlsr.getLsdb().printNameLsdb();
+        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();
+        }
+    }
+
+}//namespace nlsr
+
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
new file mode 100644
index 0000000..fb9a060
--- /dev/null
+++ b/src/route/nlsr_rt.hpp
@@ -0,0 +1,50 @@
+#ifndef NLSR_RT_HPP
+#define NLSR_RT_HPP
+
+#include<iostream>
+#include<utility>
+#include<string>
+
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    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;
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
new file mode 100644
index 0000000..acdf6d5
--- /dev/null
+++ b/src/route/nlsr_rtc.cpp
@@ -0,0 +1,504 @@
+#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"
+
+namespace nlsr
+{
+
+    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;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
new file mode 100644
index 0000000..987686e
--- /dev/null
+++ b/src/route/nlsr_rtc.hpp
@@ -0,0 +1,145 @@
+#ifndef NLSR_RTC_HPP
+#define NLSR_RTC_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr
+{
+
+    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;
+
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
new file mode 100644
index 0000000..f96da11
--- /dev/null
+++ b/src/route/nlsr_rte.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <string>
+
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    ostream&
+    operator<<(ostream& os, RoutingTableEntry &rte)
+    {
+        os<<"Destination: "<<rte.getDestination()<<endl;
+        os<<"Nexthops: "<<endl;
+        int i=1;
+        std::list< NextHop > nhl = rte.getNhl().getNextHopList();
+        for( std::list<NextHop>::iterator it=nhl.begin();
+                it!= nhl.end() ; it++,i++)
+        {
+            os <<"  Nexthop "<<i<<": "<<(*it)<<endl;
+        }
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
new file mode 100644
index 0000000..27d3601
--- /dev/null
+++ b/src/route/nlsr_rte.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_RTE_HPP
+#define NLSR_RTE_HPP
+
+#include<iostream>
+
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+    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
