public static ASTNode addChildren(@NotNull ASTNode parent, @NotNull ASTNode first, @NotNull ASTNode last, @Nullable ASTNode anchorBefore) {
    ASTNode lastChild = last.getTreeNext();
    ASTNode current = first;
    while (current != lastChild) {
      saveWhitespacesInfo(current);
      current = current.getTreeNext();
    }

    if (anchorBefore != null && isComment(anchorBefore.getElementType())) {
      ASTNode anchorPrev = anchorBefore.getTreePrev();
      if (anchorPrev != null && anchorPrev.getElementType() == TokenType.WHITE_SPACE) {
        anchorBefore = anchorPrev;
      }
    }

    parent.addChildren(first, lastChild, anchorBefore);
    ASTNode firstAddedLeaf = findFirstLeaf(first, last);
    ASTNode prevLeaf = TreeUtil.prevLeaf(first);
    ASTNode result = first;
    if (firstAddedLeaf != null) {
      ASTNode placeHolderEnd = makePlaceHolderBetweenTokens(prevLeaf, firstAddedLeaf, isFormattingRequired(prevLeaf, first), false);
      if (placeHolderEnd != prevLeaf && first == firstAddedLeaf || result.getTreeParent() != parent) {
        result = placeHolderEnd;
      }
      ASTNode lastAddedLeaf = findLastLeaf(first, last);
      placeHolderEnd = makePlaceHolderBetweenTokens(lastAddedLeaf, TreeUtil.nextLeaf(last), true, false);
      if (placeHolderEnd != lastAddedLeaf && lastAddedLeaf == first) {
        result = placeHolderEnd;
      }
    }
    else {
      makePlaceHolderBetweenTokens(prevLeaf, TreeUtil.nextLeaf(last), isFormattingRequired(prevLeaf, first), false);
    }
    return result;
  }
public static ASTNode addChildren(@NotNull ASTNode parent, @NotNull ASTNode first, @NotNull ASTNode last, @Nullable ASTNode anchorBefore)