public IndentData getChildOffset(AbstractBlockWrapper child, CommonCodeStyleSettings.IndentOptions options, int targetBlockStartOffset) {
    final boolean childStartsNewLine = child.getWhiteSpace().containsLineFeeds();
    IndentImpl.Type childIndentType = child.getIndent().getType();
    IndentData childIndent;

    // Calculate child indent.
    if (childStartsNewLine
        || (!getWhiteSpace().containsLineFeeds() && RELATIVE_INDENT_TYPES.contains(childIndentType) && indentAlreadyUsedBefore(child)))
    {
      childIndent = CoreFormatterUtil.getIndent(options, child, targetBlockStartOffset);
    }
    else if (child.getIndent().isEnforceIndentToChildren() && !child.getWhiteSpace().containsLineFeeds()) {
      // Enforce indent if child doesn't start new line, e.g. prefer the code below:
      //    void test() {
      //        foo("test", new Runnable() {
      //                public void run() {
      //                }
      //            },
      //            new Runnable() {
      //                public void run() {
      //                }
      //            }
      //        );
      //    }
      // to this one:
      //    void test() {
      //        foo("test", new Runnable() {
      //            public void run() {
      //            }
      //        },
      //            new Runnable() {
      //                public void run() {
      //                }
      //            }
      //        );
      //    }
      AlignmentImpl alignment = child.getAlignment();
      if (alignment != null) {
        AbstractBlockWrapper anchorBlock = getAnchorBlock(child, targetBlockStartOffset, alignment);
        return anchorBlock.getNumberOfSymbolsBeforeBlock();
      }

      childIndent = CoreFormatterUtil.getIndent(options, child, getStartOffset());
      if (child.getIndent().isEnforceChildrenToBeRelativeToMe()) {
        return childIndent.add(child.getNumberOfSymbolsBeforeBlock());
      }
    }
    else {
      childIndent = new IndentData(0);
    }

    // Use child indent if it's absolute and the child is contained on new line.
    if (childStartsNewLine) {
      if (child.getIndent().isAbsolute()) {
        myFlags &= ~CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
        AbstractBlockWrapper current = this;
        while (current != null && current.getStartOffset() == getStartOffset()) {
          current.myFlags &= ~CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
          current = current.myParent;
        }
        return childIndent;
      }      
      else if (child.getIndent().isRelativeToDirectParent() && child.getStartOffset() > getStartOffset()) {
        return childIndent.add(getNumberOfSymbolsBeforeBlock());
      }
    }

    if (child.getStartOffset() == getStartOffset()) {
      final boolean newValue = (myFlags & CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT) != 0 &&
                               (child.myFlags & CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT) != 0 && childIndent.isEmpty();
      setCanUseFirstChildIndentAsBlockIndent(newValue);
    }

    if (getStartOffset() == targetBlockStartOffset) {
      if (myParent == null) {
        return childIndent;
      }
      else {
        return childIndent.add(myParent.getChildOffset(this, options, targetBlockStartOffset));
      }
    }
    else if (!getWhiteSpace().containsLineFeeds()) {
      final IndentData indent = createAlignmentIndent(childIndent, child);
      if (indent != null) {
        return indent;
      }
      return childIndent.add(myParent.getChildOffset(this, options, targetBlockStartOffset));
    }
    else {
      if (myParent == null) return  childIndent.add(getWhiteSpace());
      if (getIndent().isAbsolute()) {
        if (myParent.myParent != null) {
          return childIndent.add(myParent.myParent.getChildOffset(myParent, options, targetBlockStartOffset));
        }
        else {
          return  childIndent.add(getWhiteSpace());
        }
      }
      if ((myFlags & CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT) != 0) {
        final IndentData indent = createAlignmentIndent(childIndent, child);
        if (indent != null) {
          return indent;
        }
        return childIndent.add(getWhiteSpace());
      }
      else {
        return childIndent.add(myParent.getChildOffset(this, options, targetBlockStartOffset));
      }
    }
  }
public IndentData getChildOffset(AbstractBlockWrapper child, CommonCodeStyleSettings.IndentOptions options, int targetBlockStartOffset)