@Contract("_,null -> null")
  private @Nullable Document startTransaction(@NotNull PomTransaction transaction, @Nullable PsiFile psiFile) {
    final PsiDocumentManagerBase manager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject);
    final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer();
    final PsiElement changeScope = transaction.getChangeScope();

    if (psiFile != null && !(psiFile instanceof DummyHolder) && !manager.isCommitInProgress()) {
      PsiUtilCore.ensureValid(psiFile);
    }

    boolean physical = changeScope.isPhysical();
    if (synchronizer.toProcessPsiEvent()) {
      // fail-fast to prevent any psi modifications that would cause psi/document text mismatch
      if (isDocumentUncommitted(psiFile)) {
        throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
      }
      CommandProcessor commandProcessor = CommandProcessor.getInstance();
      if (physical && !commandProcessor.isUndoTransparentActionInProgress() && commandProcessor.getCurrentCommand() == null) {
        throw new IncorrectOperationException("Must not change PSI outside command or undo-transparent action. See com.intellij.openapi.command.WriteCommandAction or com.intellij.openapi.command.CommandProcessor");
      }
    }

    VirtualFile vFile = psiFile == null ? null : psiFile.getViewProvider().getVirtualFile();
    if (psiFile != null) {
      ((SmartPointerManagerImpl) SmartPointerManager.getInstance(myProject)).fastenBelts(vFile);
      if (psiFile instanceof PsiFileImpl) {
        ((PsiFileImpl)psiFile).beforeAstChange();
      }
    }

    sendBeforeChildrenChangeEvent(changeScope);
    Document document = psiFile == null || psiFile instanceof DummyHolder ? null :
                        physical ? FileDocumentManager.getInstance().getDocument(vFile) :
                        FileDocumentManager.getInstance().getCachedDocument(vFile);
    if (document != null) {
      synchronizer.startTransaction(myProject, document, psiFile);
    }
    return document;
  }
@Contract("_,null -> null")
  private @Nullable Document startTransaction(@NotNull PomTransaction transaction, @Nullable PsiFile psiFile)