public boolean commitTransaction(final Document document) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final DocumentChangeTransaction documentChangeTransaction = removeTransaction(document);
    if (documentChangeTransaction == null) return false;
    final PsiElement changeScope = documentChangeTransaction.getChangeScope();
    try {
      mySyncDocument = document;

      final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager());
      fakeEvent.setParent(changeScope);
      fakeEvent.setFile(changeScope.getContainingFile());
      doSync(
          fakeEvent,
          true,
          new DocSyncAction() {
            @Override
            public void syncDocument(Document document, PsiTreeChangeEventImpl event) {
              doCommitTransaction(document, documentChangeTransaction);
            }
          });
      myBus
          .syncPublisher(PsiDocumentTransactionListener.TOPIC)
          .transactionCompleted(document, (PsiFile) changeScope);
    } finally {
      mySyncDocument = null;
    }
    return true;
  }
  public boolean commitTransaction(final Document document) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final DocumentChangeTransaction documentChangeTransaction = removeTransaction(document);
    if (documentChangeTransaction == null) return false;
    final PsiFile changeScope = documentChangeTransaction.myChangeScope;
    try {
      mySyncDocument = document;

      final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager());
      fakeEvent.setParent(changeScope);
      fakeEvent.setFile(changeScope);
      checkPsiModificationAllowed(fakeEvent);
      doSync(
          fakeEvent,
          true,
          new DocSyncAction() {
            @Override
            public void syncDocument(
                @NotNull Document document, @NotNull PsiTreeChangeEventImpl event) {
              doCommitTransaction(document, documentChangeTransaction);
            }
          });
      myBus
          .syncPublisher(PsiDocumentTransactionListener.TOPIC)
          .transactionCompleted(document, changeScope);
    } catch (Throwable e) {
      myPsiDocumentManager.forceReload(
          changeScope.getViewProvider().getVirtualFile(), changeScope.getViewProvider());
      ExceptionUtil.rethrowAllAsUnchecked(e);
    } finally {
      mySyncDocument = null;
    }
    return true;
  }
 @Override
 public void childRemoved(@NotNull final PsiTreeChangeEvent event) {
   if (!(event.getChild() instanceof ForeignLeafPsiElement)) {
     doSync(
         event,
         false,
         new DocSyncAction() {
           @Override
           public void syncDocument(Document document, PsiTreeChangeEventImpl event) {
             deleteString(document, event.getOffset(), event.getOffset() + event.getOldLength());
           }
         });
   }
 }
 @Override
 public void childAdded(@NotNull final PsiTreeChangeEvent event) {
   if (!(event.getChild() instanceof ForeignLeafPsiElement)) {
     doSync(
         event,
         false,
         new DocSyncAction() {
           @Override
           public void syncDocument(
               @NotNull Document document, @NotNull PsiTreeChangeEventImpl event) {
             insertString(document, event.getOffset(), event.getChild().getText());
           }
         });
   }
 }
 @Override
 public void childrenChanged(@NotNull final PsiTreeChangeEvent event) {
   doSync(
       event,
       false,
       new DocSyncAction() {
         @Override
         public void syncDocument(Document document, PsiTreeChangeEventImpl event) {
           replaceString(
               document,
               event.getOffset(),
               event.getOffset() + event.getOldLength(),
               event.getParent().getText());
         }
       });
 }
 @Override
 public void childReplaced(@NotNull final PsiTreeChangeEvent event) {
   doSync(
       event,
       false,
       new DocSyncAction() {
         @Override
         public void syncDocument(Document document, PsiTreeChangeEventImpl event) {
           int oldLength =
               event.getOldChild() instanceof ForeignLeafPsiElement ? 0 : event.getOldLength();
           String newText =
               event.getNewChild() instanceof ForeignLeafPsiElement
                   ? ""
                   : event.getNewChild().getText();
           replaceString(document, event.getOffset(), event.getOffset() + oldLength, newText);
         }
       });
 }