public static @NotNull DiffLog mergeTrees(@NotNull PsiFileImpl fileImpl,
                                            @NotNull ASTNode oldRoot,
                                            @NotNull ASTNode newRoot,
                                            @NotNull ProgressIndicator indicator,
                                            @NotNull CharSequence lastCommittedText) {
    PsiUtilCore.ensureValid(fileImpl);
    if (newRoot instanceof FileElement) {
      FileElement fileImplElement = fileImpl.getTreeElement();
      if (fileImplElement != null) {
        ((FileElement)newRoot).setCharTable(fileImplElement.getCharTable());
      }
    }

    try {
      newRoot.putUserData(TREE_TO_BE_REPARSED, Pair.create(oldRoot, lastCommittedText));
      if (isReplaceWholeNode(fileImpl, newRoot)) {
        DiffLog treeChangeEvent = replaceElementWithEvents(oldRoot, newRoot);
        fileImpl.putUserData(TREE_DEPTH_LIMIT_EXCEEDED, Boolean.TRUE);

        return treeChangeEvent;
      }
      newRoot.getFirstChildNode();  // maybe reparsed in PsiBuilderImpl and have thrown exception here
    }
    catch (ReparsedSuccessfullyException e) {
      // reparsed in PsiBuilderImpl
      return e.getDiffLog();
    }
    finally {
      newRoot.putUserData(TREE_TO_BE_REPARSED, null);
    }

    ASTShallowComparator comparator = new ASTShallowComparator(indicator);
    ASTStructure treeStructure = createInterruptibleASTStructure(newRoot, indicator);

    DiffLog diffLog = new DiffLog();
    diffTrees(oldRoot, diffLog, comparator, treeStructure, indicator, lastCommittedText);
    return diffLog;
  }
public static @NotNull DiffLog mergeTrees(@NotNull PsiFileImpl fileImpl,
                                            @NotNull ASTNode oldRoot,
                                            @NotNull ASTNode newRoot,
                                            @NotNull ProgressIndicator indicator,
                                            @NotNull CharSequence lastCommittedText)