private void setDefaultIndents(final List<AbstractBlockWrapper> list) {
   if (!list.isEmpty()) {
     for (AbstractBlockWrapper wrapper : list) {
       if (wrapper.getIndent() == null) {
         wrapper.setIndent(
             (IndentImpl)
                 Indent.getContinuationWithoutFirstIndent(myOptions.USE_RELATIVE_INDENTS));
       }
     }
   }
 }
  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();
      }
    }
  }
  /**
   * Wraps given root block and all of its descendants and returns root block wrapper.
   *
   * <p>This method performs necessary infrastructure actions and delegates actual processing to
   * {@link #buildCompositeBlock(Block, CompositeBlockWrapper, int, WrapImpl, boolean)} and {@link
   * #processSimpleBlock(Block, CompositeBlockWrapper, boolean, int, Block)}.
   *
   * @param rootBlock block to wrap
   * @param index index of the current block at its parent block. <code>-1</code> may be used here
   *     if we don't have information about parent block
   * @param parent parent block wrapper. <code>null</code> may be used here we no parent block
   *     wrapper exists
   * @param currentWrapParent parent wrap if any; <code>null</code> otherwise
   * @param parentBlock parent block of the block to wrap
   * @param rootBlockIsRightBlock flag that shows if target block is the right-most block
   * @return wrapper for the given <code>'rootBlock'</code>
   */
  private AbstractBlockWrapper buildFrom(
      final Block rootBlock,
      final int index,
      @Nullable final CompositeBlockWrapper parent,
      @Nullable WrapImpl currentWrapParent,
      @Nullable final Block parentBlock,
      boolean rootBlockIsRightBlock) {
    final WrapImpl wrap = (WrapImpl) rootBlock.getWrap();
    if (wrap != null) {
      wrap.registerParent(currentWrapParent);
      currentWrapParent = wrap;
    }
    TextRange textRange = rootBlock.getTextRange();
    final int blockStartOffset = textRange.getStartOffset();

    if (parent != null) {
      if (textRange.getStartOffset() < parent.getStartOffset()) {
        assertInvalidRanges(
            textRange.getStartOffset(),
            parent.getStartOffset(),
            myModel,
            "child block start is less than parent block start");
      }

      if (textRange.getEndOffset() > parent.getEndOffset()) {
        assertInvalidRanges(
            textRange.getEndOffset(),
            parent.getEndOffset(),
            myModel,
            "child block end is after parent block end");
      }
    }

    myCurrentWhiteSpace.append(blockStartOffset, myModel, myOptions);

    if (myCollectAlignmentsInsideFormattingRange
        && rootBlock.getAlignment() != null
        && isAffectedByFormatting(rootBlock)
        && !myInsideFormatRestrictingTag) {
      myAlignmentsInsideRangeToModify.add(rootBlock.getAlignment());
    }

    if (rootBlock.getAlignment() != null) {
      myBlocksToAlign.putValue(rootBlock.getAlignment(), rootBlock);
    }

    ReadOnlyBlockInformationProvider previousProvider = myReadOnlyBlockInformationProvider;
    try {
      if (rootBlock instanceof ReadOnlyBlockInformationProvider) {
        myReadOnlyBlockInformationProvider = (ReadOnlyBlockInformationProvider) rootBlock;
      }
      if (isInsideFormattingRanges(rootBlock, rootBlockIsRightBlock)
          || myCollectAlignmentsInsideFormattingRange && isInsideExtendedAffectedRange(rootBlock)) {
        final List<Block> subBlocks = rootBlock.getSubBlocks();
        if (subBlocks.isEmpty()
            || myReadOnlyBlockInformationProvider != null
                && myReadOnlyBlockInformationProvider.isReadOnly(rootBlock)) {
          final AbstractBlockWrapper wrapper =
              processSimpleBlock(rootBlock, parent, false, index, parentBlock);
          if (!subBlocks.isEmpty()) {
            wrapper.setIndent((IndentImpl) subBlocks.get(0).getIndent());
          }
          return wrapper;
        }
        return buildCompositeBlock(
            rootBlock, parent, index, currentWrapParent, rootBlockIsRightBlock);
      } else {
        // block building is skipped
        return processSimpleBlock(rootBlock, parent, true, index, parentBlock);
      }
    } finally {
      myReadOnlyBlockInformationProvider = previousProvider;
    }
  }