private void doIteration(@NotNull State state) {
    List<Block> subBlocks = state.parentBlock.getSubBlocks();
    final int subBlocksCount = subBlocks.size();
    int childBlockIndex = state.getIndexOfChildBlockToProcess();
    final Block block = subBlocks.get(childBlockIndex);
    if (state.previousBlock != null
        || (myCurrentWhiteSpace != null && myCurrentWhiteSpace.isIsFirstWhiteSpace())) {
      myCurrentSpaceProperty =
          (SpacingImpl) state.parentBlock.getSpacing(state.previousBlock, block);
    }

    boolean childBlockIsRightBlock = false;

    if (childBlockIndex == subBlocksCount - 1 && state.parentBlockIsRightBlock) {
      childBlockIsRightBlock = true;
    }

    final AbstractBlockWrapper wrapper =
        buildFrom(
            block,
            childBlockIndex,
            state.wrappedBlock,
            state.parentBlockWrap,
            state.parentBlock,
            childBlockIsRightBlock);
    registerExpandableIndents(block, wrapper);

    if (wrapper.getIndent() == null) {
      wrapper.setIndent((IndentImpl) block.getIndent());
    }
    if (!state.readOnly) {
      try {
        subBlocks.set(childBlockIndex, null); // to prevent extra strong refs during model building
      } catch (Throwable ex) {
        // read-only blocks
      }
    }

    if (state.childBlockProcessed(block, wrapper)) {
      while (!myStates.isEmpty() && myStates.peek().isProcessed()) {
        myStates.pop();
      }
    }
  }