private void balanceWhiteSpaces() {
    RelativeTokenTypesView wsTokens = new RelativeTokenTypesView();
    RelativeTokenTextView tokenTextGetter = new RelativeTokenTextView();
    int lastIndex = 0;

    int[] productions = myProduction.elements();
    for (int i = 1, size = myProduction.size() - 1; i < size; i++) {
      int id = productions[i];
      ProductionMarker starting = id > 0 ? pool.get(id) : null;
      if (starting instanceof StartMarker) {
        assertMarkersBalanced(((StartMarker)starting).isDone(), starting);
      }
      boolean done = starting == null;
      ProductionMarker item = starting != null ? starting : pool.get(-id);

      WhitespacesAndCommentsBinder binder;
      if (item instanceof ErrorItem) {
        assert !done;
        binder = DEFAULT_RIGHT_BINDER;
      }
      else {
        binder = myOptionalData.getBinder(item.markerId, done);
      }
      int lexemeIndex = item.getLexemeIndex(done);

      boolean recursive = binder instanceof WhitespacesAndCommentsBinder.RecursiveBinder;
      int prevProductionLexIndex;
      if (recursive) {
        prevProductionLexIndex = 0;
      }
      else {
        int prevId = productions[i - 1];
        prevProductionLexIndex = pool.get(Math.abs(prevId)).getLexemeIndex(prevId < 0);
      }
      int wsStartIndex = Math.max(lexemeIndex, lastIndex);
      while (wsStartIndex > prevProductionLexIndex && isWhitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--;

      int wsEndIndex = shiftOverWhitespaceForward(lexemeIndex);

      if (wsStartIndex != wsEndIndex) {
        wsTokens.configure(wsStartIndex, wsEndIndex);
        tokenTextGetter.configure(wsStartIndex);
        boolean atEnd = wsStartIndex == 0 || wsEndIndex == myLexemeCount;
        lexemeIndex = wsStartIndex + binder.getEdgePosition(wsTokens, atEnd, tokenTextGetter);
        item.setLexemeIndex(lexemeIndex, done);
        if (recursive) {
          myProduction.confineMarkersToMaxLexeme(i, lexemeIndex);
        }
      }
      else if (lexemeIndex < wsStartIndex) {
        lexemeIndex = wsStartIndex;
        item.setLexemeIndex(wsStartIndex, done);
      }

      lastIndex = lexemeIndex;
    }
  }
private void balanceWhiteSpaces()