public Vector AStarSearch(Agent agent) {

		PQ openQ = new PQ();

		// initialize a start node
		Node startNode = new Node();
		startNode.location = startLoc;
		startNode.costFromStart = 0;
		startNode.costToGoal = pathCostEstimate(startLoc, goalLoc, agent);
		startNode.totalCost = startNode.costFromStart + startNode.costToGoal;
		startNode.parent = null;

		openQ.add(startNode);
		open.put(startNode.location, startNode);

		// process the list until success or failure
		while (openQ.size() > 0) {

			Node node = openQ.pop();
			open.remove(node.location);

			// if at a goal, we're done
			if (node.location.equals(goalLoc)) {
				return solve(node);
			} else {
				Vector neighbors = getNeighbors(node);
				for (int i = 0; i < neighbors.size(); i++) {
					Node newNode = (Node) neighbors.elementAt(i);
					double newCostEstimate = pathCostEstimate(newNode.location,
							goalLoc, agent);
					double newCost = node.costFromStart
							+ traverseCost(node, newNode, agent);
					double newTotal = newCost + newCostEstimate;

					Location nnLoc = newNode.location;
					Node holderO, holderC;
					holderO = (Node) open.get(nnLoc);
					holderC = (Node) closed.get(nnLoc);
					if (holderO != null && holderO.totalCost <= newTotal) {
						continue;
					} else if (holderC != null && holderC.totalCost <= newTotal) {
						continue;
					} else {
						// store the new or improved info
						newNode.parent = node;
						newNode.costFromStart = newCost;
						newNode.costToGoal = newCostEstimate;
						newNode.totalCost = newNode.costFromStart
								+ newNode.costToGoal;
						if (closed.get(nnLoc) != null) {
							closed.remove(nnLoc);
						}
						Node check = (Node) open.get(nnLoc);
						if (check != null) {
							openQ.remove(check);
							open.remove(nnLoc);
						}
						openQ.add(newNode);
						open.put(nnLoc, newNode);

					} // now done with node
				}
				closed.put(node.location, node);
			}
		}
		return null; // failure
	}