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
