diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
index 5f4811c..9464f63 100644
--- a/src/route/nlsr_fe.cpp
+++ b/src/route/nlsr_fe.cpp
@@ -5,44 +5,44 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    bool
-    FibEntry::isEqualNextHops(Nhl &nhlOther)
+  bool
+  FibEntry::isEqualNextHops(Nhl &nhlOther)
+  {
+    if ( nhl.getNhlSize() != nhlOther.getNhlSize() )
     {
-        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() )
         {
-            return false;
+          it1->setRouteCost(it2->getRouteCost());
+          nhCount++;
         }
         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();
+          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;
-    }
+  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
index c85e045..edd77ab 100644
--- a/src/route/nlsr_fe.hpp
+++ b/src/route/nlsr_fe.hpp
@@ -11,74 +11,78 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class FibEntry
+  class FibEntry
+  {
+  public:
+    FibEntry()
+      : name()
+      , timeToRefresh(0)
+      , feSeqNo(0)
+      , nhl()
     {
-    public:
-        FibEntry()
-            : name()
-            , timeToRefresh(0)
-            , feSeqNo(0)
-        {
-        }
+    }
 
-        FibEntry(string n)
-        {
-            name=n;
-        }
+    FibEntry(string n)
+      : timeToRefresh(0)
+      , feSeqNo(0)
+      , nhl()
+    {
+      name=n;
+    }
 
-        string getName()
-        {
-            return name;
-        }
+    string getName()
+    {
+      return name;
+    }
 
-        Nhl& getNhl()
-        {
-            return nhl;
-        }
+    Nhl& getNhl()
+    {
+      return nhl;
+    }
 
-        int getTimeToRefresh()
-        {
-            return timeToRefresh;
-        }
+    int getTimeToRefresh()
+    {
+      return timeToRefresh;
+    }
 
-        void setTimeToRefresh(int ttr)
-        {
-            timeToRefresh=ttr;
-        }
+    void setTimeToRefresh(int ttr)
+    {
+      timeToRefresh=ttr;
+    }
 
-        void setFeExpiringEventId(ndn::EventId feid)
-        {
-            feExpiringEventId=feid;
-        }
+    void setFeExpiringEventId(ndn::EventId feid)
+    {
+      feExpiringEventId=feid;
+    }
 
-        ndn::EventId getFeExpiringEventId()
-        {
-            return feExpiringEventId;
-        }
+    ndn::EventId getFeExpiringEventId()
+    {
+      return feExpiringEventId;
+    }
 
-        void setFeSeqNo(int fsn)
-        {
-            feSeqNo=fsn;
-        }
+    void setFeSeqNo(int fsn)
+    {
+      feSeqNo=fsn;
+    }
 
-        int getFeSeqNo()
-        {
-            return feSeqNo;
-        }
+    int getFeSeqNo()
+    {
+      return feSeqNo;
+    }
 
-        bool isEqualNextHops(Nhl &nhlOther);
+    bool isEqualNextHops(Nhl &nhlOther);
 
-    private:
-        string name;
-        int timeToRefresh;
-        ndn::EventId feExpiringEventId;
-        int feSeqNo;
-        Nhl nhl;
-    };
+  private:
+    string name;
+    int timeToRefresh;
+    ndn::EventId feExpiringEventId;
+    int feSeqNo;
+    Nhl nhl;
+  };
 
-    ostream& operator<<(ostream& os, FibEntry& fe);
+  ostream& operator<<(ostream& os,FibEntry fe);
 
 } //namespace nlsr
 
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
index 8fb7928..8b03409 100644
--- a/src/route/nlsr_fib.cpp
+++ b/src/route/nlsr_fib.cpp
@@ -7,162 +7,177 @@
 namespace nlsr
 {
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    static bool
-    fibEntryNameCompare(FibEntry& fe, string name)
+  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() )
     {
-        return fe.getName() == name ;
+      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::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
+
+  void
+  Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList)
+  {
+    std::cout<<"Fib::updateFib Called"<<std::endl;
+    int startFace=0;
+    int endFace=getNumberOfFacesForName(nextHopList,
+                                        pnlsr.getConfParameter().getMaxFacesPerPrefix());
+    std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                        fibTable.end(),
+                                        bind(&fibEntryNameCompare, _1, name));
+    if( it == fibTable.end() )
     {
-        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() )
+      if( nextHopList.getNhlSize() > 0 )
+      {
+        nextHopList.sortNhl();
+        FibEntry newEntry(name);
+        std::list<NextHop> nhl=nextHopList.getNextHopList();
+        std::list<NextHop>::iterator nhit=nhl.begin();
+        for(int i=startFace; i< endFace && nhit!=nhl.end(); ++nhit, i++)
         {
-            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);
+          newEntry.getNhl().addNextHop((*nhit));
+          //Add entry to NDN-FIB
         }
+        newEntry.getNhl().sortNhl();
+        newEntry.setTimeToRefresh(fibEntryRefreshTime);
+        newEntry.setFeSeqNo(1);
+        newEntry.setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                      name ,1,fibEntryRefreshTime));
+        fibTable.push_back(newEntry);
+      }
     }
-
-
-    void
-    Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+    else
     {
-        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() )
+      std::cout<<"Old FIB Entry"<<std::endl;
+      if( nextHopList.getNhlSize() > 0 )
+      {
+        nextHopList.sortNhl();
+        if ( !it->isEqualNextHops(nextHopList) )
         {
-            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
+          std::list<NextHop> nhl=nextHopList.getNextHopList();
+          std::list<NextHop>::iterator nhit=nhl.begin();
+          // Add first Entry to NDN-FIB
+          removeFibEntryHop(pnlsr, it->getNhl(),nhit->getConnectingFace());
+          it->getNhl().resetNhl();
+          it->getNhl().addNextHop((*nhit));
+          ++startFace;
+          ++nhit;
+          for(int i=startFace; i< endFace && nhit!=nhl.end(); ++nhit, i++)
+          {
+            it->getNhl().addNextHop((*nhit));
+            //Add Entry to 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
-        }
+        it->setTimeToRefresh(fibEntryRefreshTime);
+        cancelScheduledFeExpiringEvent(pnlsr, it->getFeExpiringEventId());
+        it->setFeSeqNo(it->getFeSeqNo()+1);
+        (*it).setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                   it->getName() ,
+                                   it->getFeSeqNo(),fibEntryRefreshTime));
+      }
+      else
+      {
+        removeFromFib(pnlsr,name);
+      }
     }
+  }
 
 
 
-    void Fib::cleanFib(Nlsr& pnlsr)
+  void Fib::cleanFib(Nlsr& pnlsr)
+  {
+    for( std::list<FibEntry >::iterator it=fibTable.begin(); it != fibTable.end();
+         ++it)
     {
-        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();
-        }
+      for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+          nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+      {
+        cancelScheduledFeExpiringEvent(pnlsr,(*it).getFeExpiringEventId());
+        //Remove entry from NDN-FIB
+      }
     }
-
-
-    void
-    Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
+    if ( fibTable.size() > 0 )
     {
-        for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
-                it != nl.getNextHopList().end();   ++it)
-        {
-            if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
-            {
-                nl.getNextHopList().erase(it);
-            }
-        }
+      fibTable.clear();
     }
+  }
 
-
-    int
-    Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+  int
+  Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+  {
+    int endFace=0;
+    if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
     {
-        int endFace=0;
-        if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
-        {
-            return nextHopList.getNhlSize();
-        }
-        else
-        {
-            return maxFacesPerPrefix;
-        }
-        return endFace;
+      return nextHopList.getNhlSize();
     }
-
-    void
-    Fib::printFib()
+    else
     {
-        cout<<"-------------------FIB-----------------------------"<<endl;
-        for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
-                ++it)
-        {
-            cout<<(*it);
-        }
+      return maxFacesPerPrefix;
     }
+    return endFace;
+  }
+
+  void
+  Fib::removeFibEntryHop(Nlsr& pnlsr, Nhl& nl, int doNotRemoveHopFaceId)
+  {
+    for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
+         it != nl.getNextHopList().end();   ++it)
+    {
+      if ( it->getConnectingFace() != doNotRemoveHopFaceId )
+      {
+        //Remove FIB Entry from NDN-FIB
+      }
+    }
+  }
+
+  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
index d93d972..50369d4 100644
--- a/src/route/nlsr_fib.hpp
+++ b/src/route/nlsr_fib.hpp
@@ -7,42 +7,43 @@
 namespace nlsr
 {
 
-    class Nlsr;
+  class Nlsr;
 
-    using namespace std;
-    using namespace ndn;
+  using namespace std;
+  using namespace ndn;
 
-    class Fib
+  class Fib
+  {
+  public:
+    Fib()
+      : fibTable()
+      , fibEntryRefreshTime(0)
     {
-    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 removeFromFib(Nlsr& pnlsr, string name);
+    void updateFib(Nlsr& pnlsr, string name, Nhl& nextHopList);
+    void cleanFib(Nlsr& pnlsr);
+    void setFibEntryRefreshTime(int fert)
+    {
+      fibEntryRefreshTime=fert;
+    }
 
-        void printFib();
+    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:
+    void removeFibEntryHop(Nlsr& pnlsr, 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;
-    };
+  private:
+    std::list<FibEntry> fibTable;
+    int fibEntryRefreshTime;
+  };
 
 }//namespace nlsr
 #endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
index 47b02ec..19c57c1 100644
--- a/src/route/nlsr_map.cpp
+++ b/src/route/nlsr_map.cpp
@@ -10,115 +10,115 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    ostream&
-    operator<<(ostream& os, MapEntry& mpe)
-    {
-        os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
-        os<<mpe.getMappingNumber()<<" )"<<endl;
-        return os;
-    }
+  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
+  mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
+  {
+    return mpe1.getRouter()==rtrName;
+  }
 
-    static bool
-    mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
-    {
-        return mpe1.getMappingNumber()==mappingNo;
-    }
+  static bool
+  mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
+  {
+    return mpe1.getMappingNumber()==mappingNo;
+  }
 
-    void
-    Map::addMapElement(string& rtrName)
+  void
+  Map::addMapElement(string& rtrName)
+  {
+    MapEntry me(rtrName,mappingIndex);
+    if (  addMapElement(me) )
     {
-        MapEntry me(rtrName,mappingIndex);
-        if (  addMapElement(me) )
-        {
-            mappingIndex++;
-        }
+      mappingIndex++;
     }
+  }
 
-    bool
-    Map::addMapElement(MapEntry& mpe)
+  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() )
     {
-        //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;
+      rMap.push_back(mpe);
+      return true;
     }
+    return false;
+  }
 
-    string
-    Map::getRouterNameByMappingNo(int mn)
+  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() )
     {
-        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
-                                            rMap.end(),
-                                            bind(&mapEntryCompareByMappingNo, _1, mn));
-        if ( it != rMap.end() )
-        {
-            return (*it).getRouter();
-        }
-        return "";
+      return (*it).getRouter();
     }
+    return "";
+  }
 
-    int
-    Map::getMappingNoByRouterName(string& rName)
+  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() )
     {
-        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;
+      return (*it).getMappingNumber();
     }
+    return -1;
+  }
 
-    void
-    Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+  void
+  Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+  {
+    std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+    for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+         it!= adjLsdb.end() ; it++)
     {
-        std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
-        for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
-                it!= adjLsdb.end() ; it++)
-        {
-            string linkStartRouter=(*it).getOrigRouter();
-            addMapElement(linkStartRouter);
-            std::list<Adjacent> adl=(*it).getAdl().getAdjList();
-            for( std::list<Adjacent>::iterator itAdl=adl.begin();
-                    itAdl!= adl.end() ; itAdl++)
-            {
-                string linkEndRouter=(*itAdl).getAdjacentName();
-                addMapElement(linkEndRouter);
-            }
-        }
+      string 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;
-    }
+  void
+  Map::resetMap()
+  {
+    rMap.clear();
+    mappingIndex=0;
+  }
 
-    ostream&
-    operator<<(ostream& os, Map& rMap)
+  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<<"---------------Map----------------------"<<endl;
-        std::list< MapEntry > ml=rMap.getMapList();
-        for( std::list<MapEntry>::iterator it=ml.begin(); it!= ml.end() ; it++)
-        {
-            os<< (*it);
-        }
-        return os;
+      os<< (*it);
     }
+    return os;
+  }
 
 } //namespace nlsr
diff --git a/src/route/nlsr_map.hpp b/src/route/nlsr_map.hpp
index 0352d1d..c362706 100644
--- a/src/route/nlsr_map.hpp
+++ b/src/route/nlsr_map.hpp
@@ -9,80 +9,80 @@
 namespace nlsr
 {
 
-    class Nlsr;
+  class Nlsr;
 
-    using namespace std;
+  using namespace std;
 
-    class MapEntry
+  class MapEntry
+  {
+  public:
+    MapEntry()
+      : router()
+      , mappingNumber(-1)
     {
-    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
+    ~MapEntry()
     {
-    public:
-        Map()
-            : mappingIndex(0)
-        {
-        }
+    }
+
+    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;
-        }
+    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();
-        }
+    int getMapSize()
+    {
+      return rMap.size();
+    }
 
 
-    private:
-        bool addMapElement(MapEntry& mpe);
+  private:
+    bool addMapElement(MapEntry& mpe);
 
-        int mappingIndex;
-        std::list< MapEntry > rMap;
-    };
+    int mappingIndex;
+    std::list< MapEntry > rMap;
+  };
 
-    ostream&
-    operator<<(ostream& os, Map& rMap);
+  ostream&
+  operator<<(ostream& os, Map& rMap);
 
 } // namespace nlsr
 #endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
index e58b23c..1c7257b 100644
--- a/src/route/nlsr_nexthop.cpp
+++ b/src/route/nlsr_nexthop.cpp
@@ -3,11 +3,11 @@
 namespace nlsr
 {
 
-    ostream&
-    operator<<(ostream& os, NextHop& nh)
-    {
-        os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
-        return os;
-    }
+  ostream&
+  operator<<(ostream& os, NextHop& nh)
+  {
+    os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_nexthop.hpp b/src/route/nlsr_nexthop.hpp
index 1361d52..b8a0af0 100644
--- a/src/route/nlsr_nexthop.hpp
+++ b/src/route/nlsr_nexthop.hpp
@@ -6,50 +6,50 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class NextHop
+  class NextHop
+  {
+  public:
+    NextHop()
+      : connectingFace(0)
+      , routeCost(0)
     {
-    public:
-        NextHop()
-            : connectingFace(0)
-            , routeCost(0)
-        {
-        }
+    }
 
-        NextHop(int cf, double rc)
-        {
-            connectingFace=cf;
-            routeCost=rc;
-        }
+    NextHop(int cf, double rc)
+    {
+      connectingFace=cf;
+      routeCost=rc;
+    }
 
-        int getConnectingFace()
-        {
-            return connectingFace;
-        }
+    int getConnectingFace() const
+    {
+      return connectingFace;
+    }
 
-        void setConnectingFace(int cf)
-        {
-            connectingFace=cf;
-        }
+    void setConnectingFace(int cf)
+    {
+      connectingFace=cf;
+    }
 
-        double getRouteCost()
-        {
-            return routeCost;
-        }
+    double getRouteCost() const
+    {
+      return routeCost;
+    }
 
-        void setRouteCost(double rc)
-        {
-            routeCost=rc;
-        }
-    private:
-        int connectingFace;
-        double routeCost;
-    };
+    void setRouteCost(double rc)
+    {
+      routeCost=rc;
+    }
+  private:
+    int connectingFace;
+    double routeCost;
+  };
 
 
-    ostream&
-    operator<<(ostream& os, NextHop& nh);
+  ostream&
+  operator<<(ostream& os, NextHop& nh);
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
index 2aaa2a6..953a0b6 100644
--- a/src/route/nlsr_nhl.cpp
+++ b/src/route/nlsr_nhl.cpp
@@ -6,85 +6,85 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    static bool
-    nexthopCompare(NextHop& nh1, NextHop& nh2)
+  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(const NextHop& nh1, const 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() )
     {
-        return nh1.getConnectingFace()==nh2.getConnectingFace();
+      nexthopList.push_back(nh);
     }
-
-    static bool
-    nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+    if ( (*it).getRouteCost() > nh.getRouteCost() )
     {
-        return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
-                nh1.getRouteCost() == nh2.getRouteCost()) ;
+      (*it).setRouteCost(nh.getRouteCost());
     }
+  }
 
-    static bool
-    nextHopSortingComparator(NextHop& nh1, NextHop& nh2)
+  /**
+  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() )
     {
-        return nh1.getRouteCost() < nh2.getRouteCost();
+      nexthopList.erase(it);
     }
+  }
 
-    /**
-    Add next hop to the Next Hop list
-    If next hop is new it is added
-    If next hop already exists in next
-    hop list then updates the route
-    cost with new next hop's route cost
-    */
+  void
+  Nhl::sortNhl()
+  {
+    nexthopList.sort(nextHopSortingComparator);
+  }
 
-    void
-    Nhl::addNextHop(NextHop& nh)
+  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++)
     {
-        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());
-        }
+      os << "Nexthop "<<i<<": "<<(*it)<<endl;
     }
-
-    /**
-    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;
-    }
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_nhl.hpp b/src/route/nlsr_nhl.hpp
index 9f6bd76..f82d37e 100644
--- a/src/route/nlsr_nhl.hpp
+++ b/src/route/nlsr_nhl.hpp
@@ -11,43 +11,44 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Nhl
+  class Nhl
+  {
+  public:
+    Nhl()
+      : nexthopList()
     {
-    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;
-        }
+    ~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;
-    };
+  private:
+    std::list< NextHop > nexthopList;
+  };
 
-    ostream&
-    operator<<(ostream& os, Nhl& nhl);
+  ostream&
+  operator<<(ostream& os, Nhl& nhl);
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
index 9c4d4cb..2dfa311 100644
--- a/src/route/nlsr_npt.cpp
+++ b/src/route/nlsr_npt.cpp
@@ -9,134 +9,141 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    static bool
-    npteCompare(Npte& npte, string& name)
+  static bool
+  npteCompare(Npte& npte, string& name)
+  {
+    return npte.getNamePrefix()==name;
+  }
+
+
+
+  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() )
     {
-        return npte.getNamePrefix()==name;
+      Npte newEntry(name);
+      newEntry.addRoutingTableEntry(rte);
+      newEntry.generateNhlfromRteList();
+      newEntry.getNhl().sortNhl();
+      npteList.push_back(newEntry);
+      if(rte.getNhl().getNhlSize()> 0)
+      {
+        pnlsr.getFib().updateFib(pnlsr, name,newEntry.getNhl());
+      }
     }
-
-// Following two methods will update FIB with response to change in NPT
-
-    void
-    Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    else
     {
-        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());
-        }
+      if ( rte.getNhl().getNhlSize()> 0 )
+      {
+        (*it).addRoutingTableEntry(rte);
+        (*it).generateNhlfromRteList();
+        (*it).getNhl().sortNhl();
+        pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl());
+      }
+      else
+      {
+        (*it).resetRteListNextHop();
+        (*it).getNhl().resetNhl();
+        pnlsr.getFib().removeFromFib(pnlsr,name);
+      }
     }
+  }
 
-    void
-    Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+  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() )
     {
-        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());
-            }
-        }
+      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);
+        pnlsr.getFib().removeFromFib(pnlsr,name);
+      }
+      else
+      {
+        (*it).generateNhlfromRteList();
+        pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl());
+      }
     }
+  }
 
 
-    void
-    Npt::addNpte(string name, string destRouter, Nlsr& pnlsr)
+  void
+  Npt::addNpteByDestName(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(destRouter);
+          pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
         if(rteCheck.second)
         {
-            addNpte(name,rteCheck.first,pnlsr);
+          addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
         }
         else
         {
-            RoutingTableEntry rte(destRouter);
-            addNpte(name, rte,pnlsr);
+          RoutingTableEntry rte((*rteit).getDestination());
+          addNpte((*it).getNamePrefix(), rte,pnlsr);
         }
+      }
     }
+  }
 
-    void
-    Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
+  void
+  Npt::printNpt()
+  {
+    cout<<"----------------NPT----------------------"<<endl;
+    for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
     {
-        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);
-        }
+      cout <<(*it)<<endl;
     }
-
-    void
-    Npt::updateNptWithNewRoute(Nlsr& pnlsr)
-    {
-        for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
-        {
-            std::list<RoutingTableEntry> rteList=(*it).getRteList();
-            for(std::list<RoutingTableEntry >::iterator rteit=rteList.begin();
-                    rteit !=rteList.end(); ++rteit)
-            {
-                std::pair<RoutingTableEntry& , bool> rteCheck=
-                    pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
-                if(rteCheck.second)
-                {
-                    addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
-                }
-                else
-                {
-                    RoutingTableEntry rte((*rteit).getDestination());
-                    addNpte((*it).getNamePrefix(), rte,pnlsr);
-                }
-            }
-        }
-    }
-
-    void
-    Npt::printNpt()
-    {
-        cout<<"----------------NPT----------------------"<<endl;
-        for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
-        {
-            cout <<(*it)<<endl;
-        }
-    }
+  }
 
 }
diff --git a/src/route/nlsr_npt.hpp b/src/route/nlsr_npt.hpp
index f4ddbf9..8e6a98c 100644
--- a/src/route/nlsr_npt.hpp
+++ b/src/route/nlsr_npt.hpp
@@ -8,26 +8,26 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Nlsr;
+  class Nlsr;
 
-    class Npt
+  class Npt
+  {
+  public:
+    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;
-    };
+    }
+    void addNpteByDestName(string name, string destRouter, Nlsr& pnlsr);
+    void removeNpte(string name, string destRouter, Nlsr& pnlsr);
+    void updateNptWithNewRoute(Nlsr& pnlsr);
+    void printNpt();
+  private:
+    void addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+    void removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+  private:
+    std::list<Npte> npteList;
+  };
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
index 60013ff..c342a21 100644
--- a/src/route/nlsr_npte.cpp
+++ b/src/route/nlsr_npte.cpp
@@ -7,77 +7,77 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    Npte::generateNhlfromRteList()
+  void
+  Npte::generateNhlfromRteList()
+  {
+    nhl.resetNhl();
+    for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+         it != rteList.end(); ++it )
     {
-        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));
-            }
-        }
+      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)
+  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() )
     {
-        return rte.getDestination()==destRouter;
+      rteList.erase(it);
     }
+  }
 
-    void
-    Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
+  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() )
     {
-        std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
-                rteList.end(),
-                bind(&rteCompare, _1, rte.getDestination()));
-        if ( it != rteList.end() )
-        {
-            rteList.erase(it);
-        }
+      rteList.push_back(rte);
     }
-
-    void
-    Npte::addRoutingTableEntry(RoutingTableEntry &rte)
+    else
     {
-        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));
-            }
-        }
+      (*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)
+  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)
     {
-        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;
+      cout<<(*it);
     }
+    os<<npte.getNhl();
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_npte.hpp b/src/route/nlsr_npte.hpp
index e64328c..3dfa04a 100644
--- a/src/route/nlsr_npte.hpp
+++ b/src/route/nlsr_npte.hpp
@@ -8,53 +8,65 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class Npte
+  class Npte
+  {
+  public:
+    Npte()
+      : namePrefix()
+      , nhl()
     {
-    public:
-        Npte()
-            : namePrefix()
-            , nhl()
-        {
-        }
-        Npte(string np)
-            : nhl()
-        {
-            namePrefix=np;
-        }
+    }
+    Npte(string np)
+      : nhl()
+    {
+      namePrefix=np;
+    }
 
-        string getNamePrefix()
+    string getNamePrefix()
+    {
+      return namePrefix;
+    }
+
+    std::list<RoutingTableEntry>& getRteList()
+    {
+      return rteList;
+    }
+
+    void resetRteListNextHop()
+    {
+      if (rteList.size() > 0 )
+      {
+        for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+             it != rteList.end(); ++it )
         {
-            return namePrefix;
+          (*it).getNhl().resetNhl();
         }
+      }
+    }
 
-        std::list<RoutingTableEntry>& getRteList()
-        {
-            return rteList;
-        }
+    int getRteListSize()
+    {
+      return rteList.size();
+    }
 
-        int getRteListSize()
-        {
-            return rteList.size();
-        }
+    Nhl& getNhl()
+    {
+      return nhl;
+    }
+    void generateNhlfromRteList();
+    void removeRoutingTableEntry(RoutingTableEntry& rte);
+    void addRoutingTableEntry(RoutingTableEntry &rte);
 
-        Nhl& getNhl()
-        {
-            return nhl;
-        }
-        void generateNhlfromRteList();
-        void removeRoutingTableEntry(RoutingTableEntry& rte);
-        void addRoutingTableEntry(RoutingTableEntry &rte);
+  private:
+    string namePrefix;
+    std::list<RoutingTableEntry> rteList;
+    Nhl nhl;
+  };
 
-    private:
-        string namePrefix;
-        std::list<RoutingTableEntry> rteList;
-        Nhl nhl;
-    };
-
-    ostream&
-    operator<<(ostream& os, Npte& npte);
+  ostream&
+  operator<<(ostream& os, Npte& npte);
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
index cc60650..2cd9b28 100644
--- a/src/route/nlsr_rt.cpp
+++ b/src/route/nlsr_rt.cpp
@@ -12,221 +12,222 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    RoutingTable::calculate(Nlsr& pnlsr)
+  void
+  RoutingTable::calculate(Nlsr& pnlsr)
+  {
+    //debugging purpose
+    std::cout<<pnlsr.getConfParameter()<<std::endl;
+    pnlsr.getNpt().printNpt();
+    pnlsr.getLsdb().printAdjLsdb();
+    pnlsr.getLsdb().printCorLsdb();
+    pnlsr.getLsdb().printNameLsdb();
+    if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
     {
-        //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)
         {
-            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
-                std::cout<<"Calling Update NPT With new Route"<<std::endl;
-                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
+          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
         {
-            scheduleRoutingTableCalculation(pnlsr);
+          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
+        std::cout<<"Calling Update NPT With new Route"<<std::endl;
+        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
     }
-
-
-    void
-    RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
+    else
     {
-        cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
-        Map vMap;
-        vMap.createMapFromAdjLsdb(pnlsr);
-        int numOfRouter=vMap.getMapSize();
-        LinkStateRoutingTableCalculator lsrtc(numOfRouter);
-        lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+      scheduleRoutingTableCalculation(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::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::scheduleRoutingTableCalculation(Nlsr& pnlsr)
-    {
-        if ( pnlsr.getIsRouteCalculationScheduled() != 1 )
-        {
-            pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
-                                               ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
-            pnlsr.setIsRouteCalculationScheduled(1);
-        }
-    }
+  void
+  RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
+  {
+    Map vMap;
+    vMap.createMapFromAdjLsdb(pnlsr);
+    int numOfRouter=vMap.getMapSize();
+    HypRoutingTableCalculator hrtc(numOfRouter,0);
+    hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+  }
 
-    static bool
-    routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter)
+  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 )
     {
-        return rte.getDestination()==destRouter;
+      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)
+  void
+  RoutingTable::addNextHop(string destRouter, NextHop& nh)
+  {
+    std::pair<RoutingTableEntry&, bool> rte=findRoutingTableEntry(destRouter);
+    if( !rte.second )
     {
-        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);
-        }
+      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::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() )
     {
-        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);
+      return std::make_pair(boost::ref((*it)),true);
     }
+    RoutingTableEntry rteEmpty;
+    return std::make_pair(boost::ref(rteEmpty),false);
+  }
 
-    void
-    RoutingTable::printRoutingTable()
+  void
+  RoutingTable::printRoutingTable()
+  {
+    cout<<"---------------Routing Table------------------"<<endl;
+    for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
+        it != rTable.end(); ++it)
     {
-        cout<<"---------------Routing Table------------------"<<endl;
-        for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
-                it != rTable.end(); ++it)
-        {
-            cout<<(*it)<<endl;
-        }
+      cout<<(*it)<<endl;
     }
+  }
 
 
 //function related to manipulation of dry routing table
-    void
-    RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
+  void
+  RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
+  {
+    std::list<RoutingTableEntry >::iterator it = std::find_if( dryTable.begin(),
+        dryTable.end(),
+        bind(&routingTableEntryCompare, _1, destRouter));
+    if ( it == dryTable.end() )
     {
-        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);
-        }
+      RoutingTableEntry rte(destRouter);
+      rte.getNhl().addNextHop(nh);
+      dryTable.push_back(rte);
     }
+    else
+    {
+      (*it).getNhl().addNextHop(nh);
+    }
+  }
 
-    void
-    RoutingTable::printDryRoutingTable()
+  void
+  RoutingTable::printDryRoutingTable()
+  {
+    cout<<"--------Dry Run's Routing Table--------------"<<endl;
+    for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
+        it != dryTable.end(); ++it)
     {
-        cout<<"--------Dry Run's Routing Table--------------"<<endl;
-        for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
-                it != dryTable.end(); ++it)
-        {
-            cout<<(*it)<<endl;
-        }
+      cout<<(*it)<<endl;
     }
+  }
 
 
-    void
-    RoutingTable::clearRoutingTable()
+  void
+  RoutingTable::clearRoutingTable()
+  {
+    if( rTable.size() > 0 )
     {
-        if( rTable.size() > 0 )
-        {
-            rTable.clear();
-        }
+      rTable.clear();
     }
+  }
 
-    void
-    RoutingTable::clearDryRoutingTable()
+  void
+  RoutingTable::clearDryRoutingTable()
+  {
+    if (dryTable.size()>0 )
     {
-        if (dryTable.size()>0 )
-        {
-            dryTable.clear();
-        }
+      dryTable.clear();
     }
+  }
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
index fb9a060..bf4e489 100644
--- a/src/route/nlsr_rt.hpp
+++ b/src/route/nlsr_rt.hpp
@@ -10,40 +10,40 @@
 namespace nlsr
 {
 
-    class Nlsr;
-    class NextHop;
+  class Nlsr;
+  class NextHop;
 
-    using namespace std;
+  using namespace std;
 
-    class RoutingTable
+  class RoutingTable
+  {
+  public:
+    RoutingTable()
+      : NO_NEXT_HOP(-12345)
     {
-    public:
-        RoutingTable()
-            : NO_NEXT_HOP(-12345)
-        {
-        }
-        void calculate(Nlsr& pnlsr);
-        void addNextHop(string destRouter, NextHop& nh);
-        void printRoutingTable();
+    }
+    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);
+    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);
+  private:
+    void calculateLsRoutingTable(Nlsr& pnlsr);
+    void calculateHypRoutingTable(Nlsr& pnlsr);
+    void calculateHypDryRoutingTable(Nlsr&pnlsr);
 
-        void clearRoutingTable();
-        void clearDryRoutingTable();
+    void clearRoutingTable();
+    void clearDryRoutingTable();
 
-        const int NO_NEXT_HOP;
+    const int NO_NEXT_HOP;
 
-        std::list< RoutingTableEntry > rTable;
-        std::list< RoutingTableEntry > dryTable;
-    };
+    std::list< RoutingTableEntry > rTable;
+    std::list< RoutingTableEntry > dryTable;
+  };
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
index acdf6d5..90200e5 100644
--- a/src/route/nlsr_rtc.cpp
+++ b/src/route/nlsr_rtc.cpp
@@ -10,495 +10,499 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    void
-    RoutingTableCalculator::allocateAdjMatrix()
+  void
+  RoutingTableCalculator::allocateAdjMatrix()
+  {
+    adjMatrix = new double*[numOfRouter];
+    for(int i = 0; i < numOfRouter; ++i)
     {
-        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[i] = new double[numOfRouter];
+          adjMatrix[row][col]=cost;
         }
+      }
     }
+  }
 
-    void
-    RoutingTableCalculator::initMatrix()
+  void
+  RoutingTableCalculator::printAdjMatrix()
+  {
+    for(int i=0; i<numOfRouter; i++)
     {
-        for(int i=0; i<numOfRouter; i++)
-        {
-            for(int j=0; j<numOfRouter; j++)
-                adjMatrix[i][j]=0;
-        }
+      for(int j=0; j<numOfRouter; j++)
+        printf("%f ",adjMatrix[i][j]);
+      printf("\n");
     }
+  }
 
-    void
-    RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
+  void
+  RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+  {
+    for ( int i = 0; i < numOfRouter; i++ )
     {
-        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;
-                }
-            }
-        }
+      if ( i == link )
+      {
+        adjMatrix[source][i]=linkCost;
+      }
+      else
+      {
+        adjMatrix[source][i]=0;
+      }
     }
+  }
 
-    void
-    RoutingTableCalculator::printAdjMatrix()
+  int
+  RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+  {
+    int noLink=0;
+    for(int i=0; i<numOfRouter; i++)
     {
-        for(int i=0; i<numOfRouter; i++)
-        {
-            for(int j=0; j<numOfRouter; j++)
-                printf("%f ",adjMatrix[i][j]);
-            printf("\n");
-        }
+      if ( adjMatrix[sRouter][i] > 0 )
+      {
+        noLink++;
+      }
     }
+    return noLink;
+  }
 
-    void
-    RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+  void
+  RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
+      double *linkCosts, int source)
+  {
+    int j=0;
+    for (int i=0; i <numOfRouter; i++)
     {
-        for ( int i = 0; i < numOfRouter; i++ )
-        {
-            if ( i == link )
-            {
-                adjMatrix[source][i]=linkCost;
-            }
-            else
-            {
-                adjMatrix[source][i]=0;
-            }
-        }
+      if ( adjMatrix[source][i] > 0 )
+      {
+        links[j]=i;
+        linkCosts[j]=adjMatrix[source][i];
+        j++;
+      }
     }
+  }
 
-    int
-    RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+  void
+  RoutingTableCalculator::freeAdjMatrix()
+  {
+    for(int i = 0; i < numOfRouter; ++i)
     {
-        int noLink=0;
-        for(int i=0; i<numOfRouter; i++)
-        {
-            if ( adjMatrix[sRouter][i] > 0 )
-            {
-                noLink++;
-            }
-        }
-        return noLink;
+      delete [] adjMatrix[i];
     }
+    delete [] adjMatrix;
+  }
 
-    void
-    RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
-            double *linkCosts, int source)
+
+  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 )
     {
-        int j=0;
-        for (int i=0; i <numOfRouter; i++)
-        {
-            if ( adjMatrix[source][i] > 0 )
-            {
-                links[j]=i;
-                linkCosts[j]=adjMatrix[source][i];
-                j++;
-            }
-        }
+      // Single Path
+      doDijkstraPathCalculation(sourceRouter);
+      // print all ls path -- debugging purpose
+      printAllLsPath(sourceRouter);
+      // update routing table
+      addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
     }
-
-    void
-    RoutingTableCalculator::freeAdjMatrix()
+    else
     {
-        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;
+      // 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();
-        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();
+        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)
+  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++)
     {
-        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;
+      parent[i]=EMPTY_PARENT;
+      distance[i]=INF_DISTANCE;
+      Q[i]=i;
     }
-
-    void
-    LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
-            RoutingTable& rt, Map& pMap, int sourceRouter)
+    if ( sourceRouter != NO_MAPPING_NUM )
     {
-        cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
+      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);
+        if ( nextHopRouter != NO_NEXT_HOP )
+        {
+          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;
-        for(int i=0; i < numOfRouter ; i++)
+      }
+    }
+  }
+
+  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]])
         {
-            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 tempU=Q[j];
+          Q[j]=Q[i];
+          Q[i]=tempU;
         }
+      }
     }
+  }
 
-    int
-    LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+  int
+  LinkStateRoutingTableCalculator::isNotExplored(int *Q,
+      int u,int start, int element)
+  {
+    int ret=0;
+    for(int i=start; i< element; i++)
     {
-        int nextHop;
-        while ( parent[dest] != EMPTY_PARENT )
+      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++)
         {
-            nextHop=dest;
-            dest=parent[dest];
+          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++;
+          }
         }
-        if ( dest != source )
-        {
-            nextHop=NO_NEXT_HOP;
-        }
-        return nextHop;
+        addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
+        freeLinkFaces();
+        freeDistanceToNeighbor();
+        freeDistFromNbrToDest();
+      }
     }
+    freeLinks();
+    freeLinksCosts();
+    freeAdjMatrix();
+  }
 
-    void
-    LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
+  void
+  HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+      RoutingTable& rt, int noFaces, int dest)
+  {
+    for(int i=0 ; i < noFaces ; ++i)
     {
-        cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
-        cout<<"Source Router: "<<sourceRouter<<endl;
-        for(int i=0; i < numOfRouter ; i++)
-        {
-            if ( i!= sourceRouter )
-            {
-                printLsPath(i);
-                cout<<endl;
-            }
-        }
+      string destRouter=pMap.getRouterNameByMappingNo(dest);
+      NextHop nh(linkFaces[i],distFromNbrToDest[i]);
+      rt.addNextHop(destRouter,nh);
+      if( isDryRun == 1 )
+      {
+        rt.addNextHopToDryTable(destRouter,nh);
+      }
     }
+  }
 
-    void
-    LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+  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)
     {
-        if (parent[destRouter] != EMPTY_PARENT )
-        {
-            printLsPath(parent[destRouter]);
-        }
-        cout<<" "<<destRouter;
+      diffTheta = 2 * MATH_PI - diffTheta;
     }
-
-    void
-    LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
-            double *dist,int start,int element)
+    if ( srcRadius != -1 && destRadius != -1 )
     {
-        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;
-                }
-            }
-        }
+      if (diffTheta == 0)
+        distance = fabs (srcRadius - destRadius);
+      else
+        distance = acosh((cosh(srcRadius)*cosh(destRadius))-
+                         (sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
     }
-
-    int
-    LinkStateRoutingTableCalculator::isNotExplored(int *Q,
-            int u,int start, int element)
+    else
     {
-        int ret=0;
-        for(int i=start; i< element; i++)
-        {
-            if ( Q[i] == u )
-            {
-                ret=1;
-                break;
-            }
-        }
-        return ret;
+      distance = -1;
     }
+    return distance;
+  }
 
-    void
-    LinkStateRoutingTableCalculator::allocateParent()
-    {
-        parent=new int[numOfRouter];
-    }
+  void
+  HypRoutingTableCalculator::allocateLinkFaces()
+  {
+    linkFaces=new int[vNoLink];
+  }
 
-    void
-    LinkStateRoutingTableCalculator::allocateDistance()
-    {
-        distance= new double[numOfRouter];
-    }
+  void
+  HypRoutingTableCalculator::allocateDistanceToNeighbor()
+  {
+    distanceToNeighbor=new double[vNoLink];
+  }
 
-    void
-    LinkStateRoutingTableCalculator::freeParent()
-    {
-        delete [] parent;
-    }
+  void
+  HypRoutingTableCalculator::allocateDistFromNbrToDest()
+  {
+    distFromNbrToDest=new double[vNoLink];
+  }
 
-    void LinkStateRoutingTableCalculator::freeDistance()
-    {
-        delete [] distance;
-    }
+  void
+  HypRoutingTableCalculator::freeLinkFaces()
+  {
+    delete [] linkFaces;
+  }
 
+  void
+  HypRoutingTableCalculator::freeDistanceToNeighbor()
+  {
+    delete [] distanceToNeighbor;
+  }
 
-
-    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;
-    }
+  void
+  HypRoutingTableCalculator::freeDistFromNbrToDest()
+  {
+    delete [] distFromNbrToDest;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
index 987686e..730612c 100644
--- a/src/route/nlsr_rtc.hpp
+++ b/src/route/nlsr_rtc.hpp
@@ -7,138 +7,138 @@
 namespace nlsr
 {
 
-    class Map;
-    class RoutingTable;
-    class Nlsr;
+  class Map;
+  class RoutingTable;
+  class Nlsr;
 
 
-    using namespace std;
+  using namespace std;
 
-    class RoutingTableCalculator
+  class RoutingTableCalculator
+  {
+  public:
+    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
+    }
+    RoutingTableCalculator(int rn)
     {
-    public:
-        LinkStateRoutingTableCalculator(int rn)
-            : EMPTY_PARENT(-12345)
-            , INF_DISTANCE(2147483647)
-            , NO_MAPPING_NUM(-1)
-            , NO_NEXT_HOP(-12345)
-        {
-            numOfRouter=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 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
+    void setNoLink(int nl)
     {
-    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;
-        }
+      vNoLink=nl;
+    }
 
-        void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+  protected:
+    double ** adjMatrix;
+    int numOfRouter;
 
-    private:
-        void allocateLinkFaces();
-        void allocateDistanceToNeighbor();
-        void allocateDistFromNbrToDest();
-        void freeLinkFaces();
-        void freeDistanceToNeighbor();
-        void freeDistFromNbrToDest();
+    int vNoLink;
+    int *links;
+    double *linkCosts;
+  };
 
-        double getHyperbolicDistance(Nlsr& pnlsr,Map& pMap, int src, int dest);
-        void addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
-                                          RoutingTable& rt, int noFaces,int dest);
+  class LinkStateRoutingTableCalculator: public RoutingTableCalculator
+  {
+  public:
+    LinkStateRoutingTableCalculator(int rn)
+      : EMPTY_PARENT(-12345)
+      , INF_DISTANCE(2147483647)
+      , NO_MAPPING_NUM(-1)
+      , NO_NEXT_HOP(-12345)
+    {
+      numOfRouter=rn;
+    }
 
-    private:
-        int isDryRun;
 
-        int *linkFaces;
-        double *distanceToNeighbor;
-        double *distFromNbrToDest;
+    void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
 
-        const double MATH_PI;
 
-    };
+  private:
+    void doDijkstraPathCalculation(int sourceRouter);
+    void sortQueueByDistance(int *Q, double *dist,int start,int element);
+    int isNotExplored(int *Q, int u,int start, int element);
+    void printAllLsPath(int sourceRouter);
+    void printLsPath(int destRouter);
+    void addAllLsNextHopsToRoutingTable(Nlsr& pnlsr, RoutingTable& rt,
+                                        Map& pMap,int sourceRouter);
+    int getLsNextHop(int dest, int source);
+
+    void allocateParent();
+    void allocateDistance();
+    void freeParent();
+    void freeDistance();
+
+
+
+
+  private:
+    int *parent;
+    double *distance;
+
+
+    const int EMPTY_PARENT;
+    const double INF_DISTANCE;
+    const int NO_MAPPING_NUM;
+    const int NO_NEXT_HOP;
+
+  };
+
+  class HypRoutingTableCalculator: public RoutingTableCalculator
+  {
+  public:
+    HypRoutingTableCalculator(int rn)
+      :  MATH_PI(3.141592654)
+    {
+      numOfRouter=rn;
+      isDryRun=0;
+    }
+    HypRoutingTableCalculator(int rn, int idr)
+      :  MATH_PI(3.141592654)
+    {
+      numOfRouter=rn;
+      isDryRun=idr;
+    }
+
+    void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+  private:
+    void allocateLinkFaces();
+    void allocateDistanceToNeighbor();
+    void allocateDistFromNbrToDest();
+    void freeLinkFaces();
+    void freeDistanceToNeighbor();
+    void freeDistFromNbrToDest();
+
+    double getHyperbolicDistance(Nlsr& pnlsr,Map& pMap, int src, int dest);
+    void addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+                                      RoutingTable& rt, int noFaces,int dest);
+
+  private:
+    int isDryRun;
+
+    int *linkFaces;
+    double *distanceToNeighbor;
+    double *distFromNbrToDest;
+
+    const double MATH_PI;
+
+  };
 
 }//namespace nlsr
 
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
index f96da11..129ab8a 100644
--- a/src/route/nlsr_rte.cpp
+++ b/src/route/nlsr_rte.cpp
@@ -6,21 +6,21 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    ostream&
-    operator<<(ostream& os, RoutingTableEntry &rte)
+  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<<"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;
+      os <<"  Nexthop "<<i<<": "<<(*it)<<endl;
     }
+    return os;
+  }
 
 }//namespace nlsr
diff --git a/src/route/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
index 27d3601..736909b 100644
--- a/src/route/nlsr_rte.hpp
+++ b/src/route/nlsr_rte.hpp
@@ -8,44 +8,44 @@
 namespace nlsr
 {
 
-    using namespace std;
+  using namespace std;
 
-    class RoutingTableEntry
+  class RoutingTableEntry
+  {
+  public:
+    RoutingTableEntry()
+      : destination()
+      , nhl()
     {
-    public:
-        RoutingTableEntry()
-            : destination()
-            , nhl()
-        {
-        }
+    }
 
-        ~RoutingTableEntry()
-        {
-        }
+    ~RoutingTableEntry()
+    {
+    }
 
-        RoutingTableEntry(string dest)
-            : nhl()
-        {
-            destination=dest;
-        }
+    RoutingTableEntry(string dest)
+      : nhl()
+    {
+      destination=dest;
+    }
 
-        string getDestination()
-        {
-            return destination;
-        }
+    string getDestination()
+    {
+      return destination;
+    }
 
-        Nhl& getNhl()
-        {
-            return nhl;
-        }
+    Nhl& getNhl()
+    {
+      return nhl;
+    }
 
-    private:
-        string destination;
-        Nhl nhl;
-    };
+  private:
+    string destination;
+    Nhl nhl;
+  };
 
-    ostream&
-    operator<<(ostream& os, RoutingTableEntry &rte);
+  ostream&
+  operator<<(ostream& os, RoutingTableEntry &rte);
 
 }
 
