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
    }