@SuppressWarnings("unchecked")
 private P run(AStarStorage storage, AStarGoal<N> goal, N start, int maxIterations) {
   Preconditions.checkNotNull(goal);
   Preconditions.checkNotNull(start);
   Preconditions.checkNotNull(storage);
   N node;
   int iterations = 0;
   while (true) {
     node = (N) storage.removeBestNode();
     if (node == null) {
       return null;
     }
     if (goal.isFinished(node)) {
       return (P) node.buildPlan();
     }
     storage.close(node);
     for (AStarNode neighbour : node.getNeighbours()) {
       f(goal, node, (N) neighbour);
       if (!storage.shouldExamine(neighbour)) continue;
       storage.open(neighbour);
       neighbour.parent = node;
     }
     if (maxIterations >= 0 && iterations++ >= maxIterations) {
       return null;
     }
   }
 }
 private AStarStorage getInitialisedStorage(AStarGoal<N> goal, N start) {
   AStarStorage storage = storageSupplier.get();
   storage.open(start);
   start.f = goal.getInitialCost(start);
   return storage;
 }
 @SuppressWarnings("unchecked")
 public N getBestNode() {
   return (N) storage.getBestNode();
 }