diff --git a/src/nlsr_rtc.cpp b/src/nlsr_rtc.cpp
index 089808a..e594794 100644
--- a/src/nlsr_rtc.cpp
+++ b/src/nlsr_rtc.cpp
@@ -7,524 +7,532 @@
 #include "nlsr_nexthop.hpp"
 #include "nlsr.hpp"
 
-namespace nlsr {
-
-using namespace std;
-
-void 
-RoutingTableCalculator::allocateAdjMatrix()
+namespace nlsr
 {
-	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;
-	}
-}
+    using namespace std;
 
-void
-RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
-{
-	std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
-	for( std::list<AdjLsa>::iterator it=adjLsdb.begin(); 
-	                                                 it!= adjLsdb.end() ; it++)
-	{
-		string linkStartRouter=(*it).getOrigRouter();
-		int row=pMap.getMappingNoByRouterName(linkStartRouter);
-		std::list<Adjacent> adl=(*it).getAdl().getAdjList();
-		for( std::list<Adjacent>::iterator itAdl=adl.begin(); 
-																								itAdl!= adl.end() ; itAdl++)
-		{
-			string linkEndRouter=(*itAdl).getAdjacentName();
-			int col=pMap.getMappingNoByRouterName(linkEndRouter);
-			double cost=(*itAdl).getLinkCost();
-			if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
-			{
-				adjMatrix[row][col]=cost;
-			}
-		}
-		
-	}
-}
+    void
+    RoutingTableCalculator::allocateAdjMatrix()
+    {
+        adjMatrix = new double*[numOfRouter];
+        for(int i = 0; i < numOfRouter; ++i)
+        {
+            adjMatrix[i] = new double[numOfRouter];
+        }
+    }
 
-void
-RoutingTableCalculator::printAdjMatrix()
-{
-	for(int i=0;i<numOfRouter;i++)
-	{
-		for(int j=0;j<numOfRouter;j++)
-			printf("%f ",adjMatrix[i][j]);
-		printf("\n");
-	}
-}
+    void
+    RoutingTableCalculator::initMatrix()
+    {
+        for(int i=0; i<numOfRouter; i++)
+        {
+            for(int j=0; j<numOfRouter; j++)
+                adjMatrix[i][j]=0;
+        }
+    }
 
-void 
-RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
-{
-	for ( int i = 0; i < numOfRouter; i++ ){
-		if ( i == link ){
-			adjMatrix[source][i]=linkCost;
-		}
-		else{
-			adjMatrix[source][i]=0;
-		}
-	}
-}
+    void
+    RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
+    {
+        std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+        for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+                it!= adjLsdb.end() ; it++)
+        {
+            string linkStartRouter=(*it).getOrigRouter();
+            int row=pMap.getMappingNoByRouterName(linkStartRouter);
+            std::list<Adjacent> adl=(*it).getAdl().getAdjList();
+            for( std::list<Adjacent>::iterator itAdl=adl.begin();
+                    itAdl!= adl.end() ; itAdl++)
+            {
+                string linkEndRouter=(*itAdl).getAdjacentName();
+                int col=pMap.getMappingNoByRouterName(linkEndRouter);
+                double cost=(*itAdl).getLinkCost();
+                if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
+                {
+                    adjMatrix[row][col]=cost;
+                }
+            }
 
-int 
-RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
-{
-	int noLink=0;
-	for(int i=0;i<numOfRouter;i++)
-	{	
-		if ( adjMatrix[sRouter][i] > 0 )
-		{
-			noLink++;
-		}
-	}
-	return noLink;
-}
+        }
+    }
 
-void 
-RoutingTableCalculator::getLinksFromAdjMatrix(int *links, 
-                                                 double *linkCosts, int source)
-{
-	int j=0;
-	for (int i=0; i <numOfRouter; i++)
-	{
-		if ( adjMatrix[source][i] > 0 )
-		{
-			links[j]=i;
-			linkCosts[j]=adjMatrix[source][i];
-			j++;
-		}
-	}
-}
+    void
+    RoutingTableCalculator::printAdjMatrix()
+    {
+        for(int i=0; i<numOfRouter; i++)
+        {
+            for(int j=0; j<numOfRouter; j++)
+                printf("%f ",adjMatrix[i][j]);
+            printf("\n");
+        }
+    }
 
-void 
-RoutingTableCalculator::freeAdjMatrix()
-{
-	for(int i = 0; i < numOfRouter; ++i) 
-	{
-    	delete [] adjMatrix[i];
-	}
-	delete [] adjMatrix;
-}
+    void
+    RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+    {
+        for ( int i = 0; i < numOfRouter; i++ )
+        {
+            if ( i == link )
+            {
+                adjMatrix[source][i]=linkCost;
+            }
+            else
+            {
+                adjMatrix[source][i]=0;
+            }
+        }
+    }
+
+    int
+    RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+    {
+        int noLink=0;
+        for(int i=0; i<numOfRouter; i++)
+        {
+            if ( adjMatrix[sRouter][i] > 0 )
+            {
+                noLink++;
+            }
+        }
+        return noLink;
+    }
+
+    void
+    RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
+            double *linkCosts, int source)
+    {
+        int j=0;
+        for (int i=0; i <numOfRouter; i++)
+        {
+            if ( adjMatrix[source][i] > 0 )
+            {
+                links[j]=i;
+                linkCosts[j]=adjMatrix[source][i];
+                j++;
+            }
+        }
+    }
+
+    void
+    RoutingTableCalculator::freeAdjMatrix()
+    {
+        for(int i = 0; i < numOfRouter; ++i)
+        {
+            delete [] adjMatrix[i];
+        }
+        delete [] adjMatrix;
+    }
 
 
-void 
-RoutingTableCalculator::allocateLinks()
-{
-	links=new int[vNoLink];
-}
+    void
+    RoutingTableCalculator::allocateLinks()
+    {
+        links=new int[vNoLink];
+    }
 
-void RoutingTableCalculator::allocateLinkCosts()
-{
-	linkCosts=new double[vNoLink];
-}
+    void RoutingTableCalculator::allocateLinkCosts()
+    {
+        linkCosts=new double[vNoLink];
+    }
 
 
-void 
-RoutingTableCalculator::freeLinks()
-{
-	delete [] links;
-}
-void 
-RoutingTableCalculator::freeLinksCosts()
-{
-	delete [] linkCosts;
-}
+    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();
+    void
+    LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
+            RoutingTable& rt, Nlsr& pnlsr)
+    {
+        cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
+        allocateAdjMatrix();
+        initMatrix();
+        makeAdjMatrix(pnlsr,pMap);
+        cout<<pMap;
+        printAdjMatrix();
+        string routerName=pnlsr.getConfParameter().getRouterPrefix();
+        int sourceRouter=pMap.getMappingNoByRouterName(routerName);
+        int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
+        allocateParent();
+        allocateDistance();
 
-	if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
-	{
-		// Single Path
-		doDijkstraPathCalculation(sourceRouter);
-		// print all ls path -- debugging purpose
-		printAllLsPath(sourceRouter);
-		// update routing table
-		addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
-	}
-	else
-	{
-		// Multi Path
-		setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
-		allocateLinks();
-		allocateLinkCosts();
+        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();
-	}
+            getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+            for (int i=0 ; i < vNoLink; i++)
+            {
 
-	freeParent();
-	freeDistance();
-	freeAdjMatrix();
-}
+                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);
+            }
 
-void 
-LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
-{
-	int i;
-	int v,u;
-	int *Q=new int[numOfRouter];
-	int head=0;
-	/* Initiate the Parent */
-	for (i = 0 ; i < numOfRouter; i++){
-		parent[i]=EMPTY_PARENT;
-		distance[i]=INF_DISTANCE;
-		Q[i]=i;
-	} 
+            freeLinks();
+            freeLinksCosts();
+        }
 
-	if ( sourceRouter != NO_MAPPING_NUM ){
-		distance[sourceRouter]=0;
-		sortQueueByDistance(Q,distance,head,numOfRouter);
+        freeParent();
+        freeDistance();
+        freeAdjMatrix();
+    }
 
-		while (head < numOfRouter )
-		{
-			u=Q[head];
-			if(distance[u] == INF_DISTANCE)
-			{
-				break;
-			}
+    void
+    LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
+    {
+        int i;
+        int v,u;
+        int *Q=new int[numOfRouter];
+        int head=0;
+        /* Initiate the Parent */
+        for (i = 0 ; i < numOfRouter; i++)
+        {
+            parent[i]=EMPTY_PARENT;
+            distance[i]=INF_DISTANCE;
+            Q[i]=i;
+        }
 
-			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;
-						}	
+        if ( sourceRouter != NO_MAPPING_NUM )
+        {
+            distance[sourceRouter]=0;
+            sortQueueByDistance(Q,distance,head,numOfRouter);
 
-					}
+            while (head < numOfRouter )
+            {
+                u=Q[head];
+                if(distance[u] == INF_DISTANCE)
+                {
+                    break;
+                }
 
-				}
+                for(v=0 ; v <numOfRouter; v++)
+                {
+                    if( adjMatrix[u][v] > 0 )
+                    {
+                        if ( isNotExplored(Q,v,head+1,numOfRouter) )
+                        {
+                            if( distance[u] + adjMatrix[u][v] <  distance[v])
+                            {
+                                distance[v]=distance[u] + adjMatrix[u][v] ;
+                                parent[v]=u;
+                            }
 
-			}
+                        }
 
-			head++;
-			sortQueueByDistance(Q,distance,head,numOfRouter);
-		}
-	}
-	delete [] Q;
-}
+                    }
 
-void 
-LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
-																 RoutingTable& rt, Map& pMap, int sourceRouter)
-{
-	cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
-	cout<<endl;
-	for(int i=0; i < numOfRouter ; i++)
-	{
-		if ( i!= sourceRouter )
-		{
-			int nextHopRouter=getLsNextHop(i,sourceRouter);
-			double routeCost=distance[i];
-			string nextHopRouterName=pMap.getRouterNameByMappingNo(nextHopRouter);
-			int nxtHopFace=
-              pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
-			cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
-			cout<<"Next hop Router: "<<nextHopRouterName<<endl;
-			cout<<"Next hop Face: "<<nxtHopFace<<endl;
-			cout<<"Route Cost: "<<routeCost<<endl;
-			cout<<endl;
-			// Add next hop to routing table
-			NextHop nh(nxtHopFace,routeCost);
-			rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
-			
-		}
-	}
-}
+                }
 
-int 
-LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
-{
-	int nextHop;
-	while ( parent[dest] != EMPTY_PARENT )
-	{
-		nextHop=dest;
-		dest=parent[dest];
+                head++;
+                sortQueueByDistance(Q,distance,head,numOfRouter);
+            }
+        }
+        delete [] Q;
+    }
 
-	}
+    void
+    LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
+            RoutingTable& rt, Map& pMap, int sourceRouter)
+    {
+        cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
+        cout<<endl;
+        for(int i=0; i < numOfRouter ; i++)
+        {
+            if ( i!= sourceRouter )
+            {
+                int nextHopRouter=getLsNextHop(i,sourceRouter);
+                double routeCost=distance[i];
+                string nextHopRouterName=pMap.getRouterNameByMappingNo(nextHopRouter);
+                int nxtHopFace=
+                    pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+                cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
+                cout<<"Next hop Router: "<<nextHopRouterName<<endl;
+                cout<<"Next hop Face: "<<nxtHopFace<<endl;
+                cout<<"Route Cost: "<<routeCost<<endl;
+                cout<<endl;
+                // Add next hop to routing table
+                NextHop nh(nxtHopFace,routeCost);
+                rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
 
-	if ( dest != source )
-	{
-		nextHop=NO_NEXT_HOP;	
-	}
+            }
+        }
+    }
 
-	return nextHop;
-}
+    int
+    LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+    {
+        int nextHop;
+        while ( parent[dest] != EMPTY_PARENT )
+        {
+            nextHop=dest;
+            dest=parent[dest];
 
-void
-LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
-{
-	cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
-	cout<<"Source Router: "<<sourceRouter<<endl;
-	for(int i=0; i < numOfRouter ; i++)
-	{
-		if ( i!= sourceRouter )
-		{
-			printLsPath(i);
-			cout<<endl;
-		}
-	}
-}
+        }
 
-void
-LinkStateRoutingTableCalculator::printLsPath(int destRouter)
-{
-	if (parent[destRouter] != EMPTY_PARENT )
-	{
-		printLsPath(parent[destRouter]);
-	}
+        if ( dest != source )
+        {
+            nextHop=NO_NEXT_HOP;
+        }
 
-	cout<<" "<<destRouter;
-}
+        return nextHop;
+    }
 
-void 
-LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
-                                             double *dist,int start,int element)
-{
-	for ( int i=start ; i < element ; i ++) 
-	{
-		for( int j=i+1; j<element; j ++)
-		{
-			if (dist[Q[j]] < dist[Q[i]])
-			{
-				int tempU=Q[j];
-				Q[j]=Q[i];
-				Q[i]=tempU;
-			}
-		}
-	}
+    void
+    LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
+    {
+        cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
+        cout<<"Source Router: "<<sourceRouter<<endl;
+        for(int i=0; i < numOfRouter ; i++)
+        {
+            if ( i!= sourceRouter )
+            {
+                printLsPath(i);
+                cout<<endl;
+            }
+        }
+    }
 
-}
+    void
+    LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+    {
+        if (parent[destRouter] != EMPTY_PARENT )
+        {
+            printLsPath(parent[destRouter]);
+        }
 
-int 
-LinkStateRoutingTableCalculator::isNotExplored(int *Q, 
-                                                   int u,int start, int element)
-{
-	int ret=0;
-	for(int i=start; i< element; i++)
-	{
-		if ( Q[i] == u )
-		{
-			ret=1;
-			break;
-		}
-	}
-	return ret;
-}
+        cout<<" "<<destRouter;
+    }
 
-void 
-LinkStateRoutingTableCalculator::allocateParent()
-{
-	parent=new int[numOfRouter];
-}
+    void
+    LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
+            double *dist,int start,int element)
+    {
+        for ( int i=start ; i < element ; i ++)
+        {
+            for( int j=i+1; j<element; j ++)
+            {
+                if (dist[Q[j]] < dist[Q[i]])
+                {
+                    int tempU=Q[j];
+                    Q[j]=Q[i];
+                    Q[i]=tempU;
+                }
+            }
+        }
 
-void 
-LinkStateRoutingTableCalculator::allocateDistance()
-{
-	distance= new double[numOfRouter];
-}
+    }
 
-void 
-LinkStateRoutingTableCalculator::freeParent()
-{
-	delete [] parent;
-}
+    int
+    LinkStateRoutingTableCalculator::isNotExplored(int *Q,
+            int u,int start, int element)
+    {
+        int ret=0;
+        for(int i=start; i< element; i++)
+        {
+            if ( Q[i] == u )
+            {
+                ret=1;
+                break;
+            }
+        }
+        return ret;
+    }
 
-void LinkStateRoutingTableCalculator::freeDistance()
-{
-	delete [] distance;
-}
+    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();
+    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);
+        getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
 
-	for(int i=0 ; i < numOfRouter ; ++i)
-	{
-			int k=0;
-			if ( i != sourceRouter)
-			{
-				allocateLinkFaces();
-				allocateDistanceToNeighbor();
-				allocateDistFromNbrToDest();
+        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++;
-					}
-				}
+                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);
+                addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
 
-				freeLinkFaces();
-				freeDistanceToNeighbor();
-				freeDistFromNbrToDest();	
-			}
-	}
+                freeLinkFaces();
+                freeDistanceToNeighbor();
+                freeDistFromNbrToDest();
+            }
+        }
 
-	freeLinks();
-	freeLinksCosts();
-	freeAdjMatrix();
-}
+        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);
-		}
-	}
-	
-} 
+    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
+    HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
+            Map& pMap, int src, int dest)
+    {
+        double distance=0.0;
 
-	double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
-	double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
+        string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
+        string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
 
-	double destRadius=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorRadius();
-	double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
+        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);
+        double diffTheta = fabs (srcTheta - destTheta);
 
-	if (diffTheta > MATH_PI)
-	{
-		diffTheta = 2 * MATH_PI - diffTheta; 	
-	}
+        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;
-	}
+        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;
-}
+        return distance;
+    }
 
-void 
-HypRoutingTableCalculator::allocateLinkFaces()
-{
-	linkFaces=new int[vNoLink];
-}
+    void
+    HypRoutingTableCalculator::allocateLinkFaces()
+    {
+        linkFaces=new int[vNoLink];
+    }
 
-void 
-HypRoutingTableCalculator::allocateDistanceToNeighbor()
-{
-	distanceToNeighbor=new double[vNoLink];
-}
+    void
+    HypRoutingTableCalculator::allocateDistanceToNeighbor()
+    {
+        distanceToNeighbor=new double[vNoLink];
+    }
 
-void 
-HypRoutingTableCalculator::allocateDistFromNbrToDest()
-{
-	distFromNbrToDest=new double[vNoLink];
-}
+    void
+    HypRoutingTableCalculator::allocateDistFromNbrToDest()
+    {
+        distFromNbrToDest=new double[vNoLink];
+    }
 
-void 
-HypRoutingTableCalculator::freeLinkFaces()
-{
-	delete [] linkFaces;
-}
+    void
+    HypRoutingTableCalculator::freeLinkFaces()
+    {
+        delete [] linkFaces;
+    }
 
-void 
-HypRoutingTableCalculator::freeDistanceToNeighbor()
-{
-	delete [] distanceToNeighbor;
-}
+    void
+    HypRoutingTableCalculator::freeDistanceToNeighbor()
+    {
+        delete [] distanceToNeighbor;
+    }
 
-void 
-HypRoutingTableCalculator::freeDistFromNbrToDest()
-{
-	delete [] distFromNbrToDest;
-}
+    void
+    HypRoutingTableCalculator::freeDistFromNbrToDest()
+    {
+        delete [] distFromNbrToDest;
+    }
 
 }//namespace nlsr
