@Override
  public void search(Board board, Writer out) {
    open = Queues.newPriorityQueue();
    open.add(board);
    
    while (!open.isEmpty()) {
      Board top = open.remove();
      
      if (top.isComplete()) {
        write(out, top.getMoves().toString());
        return;
      }
      
      closed.add(top);
      
      for (Direction d: DIRECTIONS) {
        Board successor;
        if (d == top.getLastPosition()
            || !top.canMove(d)
            || closed.contains(successor = top.move(d))
            ) continue;
        
        if (closed.contains(successor)) continue;
        
        if (open.contains(successor)) {
          // Hack to remove longer path when 2 of same state in open
          // Because two boards of the same configuration are "equal()",
          // Board.compareTo will cause the longer path-ed Board to float
          // above and get removed by remove()
          open.add(successor);
          open.remove(successor);
        } else {
          open.add(successor);
        }
        
      }
    }
  }