private TetrisStateBuffer search(TetrisStateBuffer in) {
    stateDistQueue.clear();
    veryFirstPiece = withVeryFirstPiece;

    TetrisStateBuffer result = null;

    addState(search.stateSet.get(search.getInitialState()), in);
    int counter = 0;
    while (!stateDistQueue.isEmpty()) {
      StateDist stateDist = stateDistQueue.poll();
      SearchState oldState = stateDist.state;
      int oldDist = stateDistMap.get(oldState);
      if (stateDist.dist > oldDist + estimateDistToGoal(oldState))
        continue;
      if (counter++ % 1 == 0) {
        System.out.println("Board:");
        oldState.board.print();
        System.out.println("Est: " + stateDist.dist + " Dist: " + oldDist + " size: " + stateDistMap.size() + " unexplored: " + stateDistQueue.size());
      }

      if (oldState.rowsToGo <= 0 && search.isExpectedBoard(oldState.board)) {
//        return stateBufferMap.get(oldState);
        if (result == null)
          result = stateBufferMap.get(oldState);
      } else {
        expandChildren(oldState, oldDist);
        stateBufferMap.put(oldState, null);
      }
      veryFirstPiece = false;
    }
    return result;
  }