private PFResult findNextOptimalRoad(AID sourceNodeAID, AID finalNodeAID)
	{
		PFNode currentNode = endNodeNameToNodeMap.get(sourceNodeAID).get(0);
		close(currentNode);

		while (!(currentNode.nodeAID).equals(finalNodeAID))
		{
			ArrayList<PFNode> children = childNodeMap.get(currentNode);

			for (PFNode child : children)
			{
				if (child.closed)
				{
					// ignore
				}
				else if (!child.opened)
				{
					// open child with parent
					open(child, currentNode);
					// set the final position for F calculation
					child.setFinalPosition(nodePositionMap.get(finalNodeAID));
				}
				else
				{
					// check to see if this path to that square is better, using G cost as the measure.
					if (currentNode.G  + child.C < child.G)
					{
						ArrayList<PFNode> nodes = endNodeNameToNodeMap.get(child.nodeAID);
						for (PFNode node : nodes)
						{
							openNodes.remove(node);
							node.setParentNode(currentNode);
						}
						openNodes.add(child);
					}
				}
			}

			int index = findLowestCost();

			currentNode = openNodes.get(index);
			close(currentNode);
		}
		
		double cost = currentNode.C;
		// loopback
		while (currentNode.parentNode.parentNode != null)
		{
			currentNode = currentNode.parentNode;
			cost += currentNode.C;
		}
		
		// cleanup
		cleanup();

		return new PFResult(currentNode.roadAID, cost);
	}