@Override
 public void documentChanged(DocumentEvent e) {
   UndoManager undoManager = UndoManager.getInstance(myProject);
   boolean undoOrRedo = undoManager.isUndoInProgress() || undoManager.isRedoInProgress();
   if (undoOrRedo) {
     // allow undo/redo up until 'creation stamp' back in time
     // and check it after action is completed
     if (e.getDocument() == myOrigDocument) {
       //noinspection SSBasedInspection
       SwingUtilities.invokeLater(
           () -> {
             if (myOrigCreationStamp > myOrigDocument.getModificationStamp()) {
               closeEditor();
             }
           });
     }
   } else if (e.getDocument() == myNewDocument) {
     commitToOriginal(e);
     if (!isValid()) {
       ApplicationManager.getApplication()
           .invokeLater(() -> closeEditor(), myProject.getDisposed());
     }
   } else if (e.getDocument() == myOrigDocument) {
     if (myCommittingToOriginal || myAltFullRange != null && myAltFullRange.isValid()) return;
     ApplicationManager.getApplication().invokeLater(() -> closeEditor(), myProject.getDisposed());
   }
 }
 static void chooseAmbiguousTargetAndPerform(
     @NotNull final Project project,
     final Editor editor,
     @NotNull PsiElementProcessor<PsiElement> processor) {
   if (editor == null) {
     Messages.showMessageDialog(
         project,
         FindBundle.message("find.no.usages.at.cursor.error"),
         CommonBundle.getErrorTitle(),
         Messages.getErrorIcon());
   } else {
     int offset = editor.getCaretModel().getOffset();
     boolean chosen =
         GotoDeclarationAction.chooseAmbiguousTarget(
             editor,
             offset,
             processor,
             FindBundle.message("find.usages.ambiguous.title", "crap"),
             null);
     if (!chosen) {
       ApplicationManager.getApplication()
           .invokeLater(
               new Runnable() {
                 @Override
                 public void run() {
                   if (editor.isDisposed() || !editor.getComponent().isShowing()) return;
                   HintManager.getInstance()
                       .showErrorHint(
                           editor, FindBundle.message("find.no.usages.at.cursor.error"));
                 }
               },
               project.getDisposed());
     }
   }
 }
  public void setChangeLists(final List<CommittedChangeList> receivedChanges) {
    final boolean hasEmptyCaches = CommittedChangesCache.getInstance(myProject).hasEmptyCaches();

    ApplicationManager.getApplication()
        .invokeLater(
            new Runnable() {
              public void run() {
                if (myLoadingChangeListsLabel != null) {
                  remove(myLoadingChangeListsLabel);
                  myLoadingChangeListsLabel = null;
                }
                myCommittedChangeLists = receivedChanges;
                myTreeBrowser.setItems(
                    myCommittedChangeLists, CommittedChangesBrowserUseCase.UPDATE);
                if (hasEmptyCaches) {
                  myTreeBrowser
                      .getEmptyText()
                      .appendText("Click ")
                      .appendText(
                          "Refresh",
                          SimpleTextAttributes.LINK_ATTRIBUTES,
                          new ActionListener() {
                            public void actionPerformed(final ActionEvent e) {
                              RefreshIncomingChangesAction.doRefresh(myProject);
                            }
                          })
                      .appendText(" to initialize repository changes cache");
                }
              }
            },
            myProject.getDisposed());
  }
  public void scheduleRestart() {
    ApplicationManager.getApplication().assertIsDispatchThread();
    cancel();

    final CompletionProgressIndicator current =
        CompletionServiceImpl.getCompletionService().getCurrentCompletion();
    if (this != current) {
      LOG.error(current + "!=" + this);
    }

    if (isAutopopupCompletion() && !myLookup.isShown()) {
      if (CompletionServiceImpl.getCompletionService().getCurrentCompletion() == this) {
        closeAndFinish(true);
      }

      AutoPopupController.getInstance(getProject()).scheduleAutoPopup(myEditor, null);
      return;
    }

    hideAutopopupIfMeaningless();

    CompletionPhase oldPhase = CompletionServiceImpl.getCompletionPhase();
    if (oldPhase instanceof CompletionPhase.CommittingDocuments) {
      ((CompletionPhase.CommittingDocuments) oldPhase).replaced = true;
    }

    final CompletionPhase.CommittingDocuments phase =
        new CompletionPhase.CommittingDocuments(this, myEditor);
    CompletionServiceImpl.setCompletionPhase(phase);

    final Project project = getProject();
    ApplicationManager.getApplication()
        .invokeLater(
            new Runnable() {
              @Override
              public void run() {
                CompletionAutoPopupHandler.runLaterWithCommitted(
                    project,
                    myEditor.getDocument(),
                    new Runnable() {
                      @Override
                      public void run() {
                        if (phase.checkExpired()) return;

                        CompletionAutoPopupHandler.invokeCompletion(
                            myParameters.getCompletionType(),
                            isAutopopupCompletion(),
                            project,
                            myEditor,
                            myParameters.getInvocationCount(),
                            true);
                      }
                    });
              }
            },
            project.getDisposed());
  }
  public static void removeDuplicatingClasses(
      final Module module,
      @NotNull final String packageName,
      @NotNull String className,
      @Nullable File classFile,
      String sourceRootPath) {
    if (sourceRootPath == null) {
      return;
    }
    VirtualFile sourceRoot = LocalFileSystem.getInstance().findFileByPath(sourceRootPath);
    if (sourceRoot == null) {
      return;
    }
    final Project project = module.getProject();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    final String interfaceQualifiedName = packageName + '.' + className;
    PsiClass[] classes =
        facade.findClasses(interfaceQualifiedName, GlobalSearchScope.moduleScope(module));
    final ProjectFileIndex projectFileIndex =
        ProjectRootManager.getInstance(project).getFileIndex();
    for (PsiClass c : classes) {
      PsiFile psiFile = c.getContainingFile();
      if (className.equals(FileUtil.getNameWithoutExtension(psiFile.getName()))) {
        VirtualFile virtualFile = psiFile.getVirtualFile();
        if (virtualFile != null
            && projectFileIndex.getSourceRootForFile(virtualFile) == sourceRoot) {
          final String path = virtualFile.getPath();
          File f = new File(path);

          try {
            f = f.getCanonicalFile();
            classFile = classFile != null ? classFile.getCanonicalFile() : null;
            if (f != null && !f.equals(classFile) && f.exists()) {
              if (f.delete()) {
                virtualFile.refresh(true, false);
              } else {
                ApplicationManager.getApplication()
                    .invokeLater(
                        new Runnable() {
                          public void run() {
                            Messages.showErrorDialog(
                                project, "Can't delete file " + path, CommonBundle.getErrorTitle());
                          }
                        },
                        project.getDisposed());
              }
            }
          } catch (IOException e) {
            LOG.info(e);
          }
        }
      }
    }
  }
  private static void checkAnnotationsJarAttached(@NotNull LocalInspectionToolSession session) {
    PsiFile file = session.getFile();
    final Project project = file.getProject();
    PsiClass event =
        JavaPsiFacade.getInstance(project)
            .findClass("java.awt.event.InputEvent", GlobalSearchScope.allScope(project));
    if (event == null) return; // no jdk to attach
    PsiMethod[] methods = event.findMethodsByName("getModifiers", false);
    if (methods.length != 1) return; // no jdk to attach
    PsiMethod getModifiers = methods[0];
    PsiAnnotation annotation =
        ExternalAnnotationsManager.getInstance(project)
            .findExternalAnnotation(getModifiers, MagicConstant.class.getName());
    if (annotation != null) return;
    final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(getModifiers);
    if (virtualFile == null) return; // no jdk to attach
    final List<OrderEntry> entries =
        ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(virtualFile);
    Sdk jdk = null;
    for (OrderEntry orderEntry : entries) {
      if (orderEntry instanceof JdkOrderEntry) {
        jdk = ((JdkOrderEntry) orderEntry).getJdk();
        if (jdk != null) break;
      }
    }
    if (jdk == null) return; // no jdk to attach

    if (!ApplicationManager.getApplication().isUnitTestMode()) {
      final Sdk finalJdk = jdk;
      ApplicationManager.getApplication()
          .invokeLater(
              new Runnable() {
                @Override
                public void run() {
                  ApplicationManager.getApplication()
                      .runWriteAction(
                          new Runnable() {
                            public void run() {
                              attachJdkAnnotations(finalJdk);
                            }
                          });
                }
              },
              ModalityState.NON_MODAL,
              project.getDisposed());
    }
  }
 static Void cancelAndRestartDaemonLater(
     ProgressIndicator progress, final Project project, TextEditorHighlightingPass pass) {
   PassExecutorService.log(progress, pass, "Cancel and restart");
   progress.cancel();
   ApplicationManager.getApplication()
       .invokeLater(
           new Runnable() {
             @Override
             public void run() {
               try {
                 Thread.sleep(new Random().nextInt(100));
               } catch (InterruptedException e) {
                 LOG.error(e);
               }
               DaemonCodeAnalyzer.getInstance(project).restart();
             }
           },
           project.getDisposed());
   throw new ProcessCanceledException();
 }
  GitRepositoryUpdater(GitRepository repository) {
    VirtualFile gitDir = repository.getGitDir();
    myWatchRequest = LocalFileSystem.getInstance().addRootToWatch(gitDir.getPath(), true);

    myRepositoryFiles = GitRepositoryFiles.getInstance(gitDir);
    visitGitDirVfs(gitDir);
    myHeadsDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsHeadsPath());
    myRemotesDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsRemotesPath());

    Project project = repository.getProject();
    myUpdateQueue =
        new QueueProcessor<GitRepository.TrackedTopic>(
            new Updater(repository), project.getDisposed());
    if (!project.isDisposed()) {
      myMessageBusConnection = project.getMessageBus().connect();
      myMessageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, this);
    } else {
      myMessageBusConnection = null;
    }
  }
 @Override
 protected void showError(
     @Nullable final String error,
     @Nullable final WebBrowser browser,
     @Nullable final Project project,
     final String title,
     @Nullable final Runnable launchTask) {
   AppUIUtil.invokeOnEdt(
       new Runnable() {
         @Override
         public void run() {
           if (Messages.showYesNoDialog(
                   project,
                   StringUtil.notNullize(error, "Unknown error"),
                   title == null ? IdeBundle.message("browser.error") : title,
                   Messages.OK_BUTTON,
                   IdeBundle.message("button.fix"),
                   null)
               == Messages.NO) {
             final BrowserSettings browserSettings = new BrowserSettings();
             if (ShowSettingsUtil.getInstance()
                 .editConfigurable(
                     project,
                     browserSettings,
                     browser == null
                         ? null
                         : new Runnable() {
                           @Override
                           public void run() {
                             browserSettings.selectBrowser(browser);
                           }
                         })) {
               if (launchTask != null) {
                 launchTask.run();
               }
             }
           }
         }
       },
       project == null ? null : project.getDisposed());
 }
  private void updateChangesForDocument(@NotNull final Document document) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    if (DaemonListeners.isUnderIgnoredAction(null) || myProject.isDisposed()) return;
    List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document);
    if (toUpdate == null) {
      // The document has been changed, but psi hasn't
      // We may still need to rehighlight the file if there were changes inside highlighted ranges.
      if (UpdateHighlightersUtil.isWhitespaceOptimizationAllowed(document)) return;

      // don't create PSI for files in other projects
      PsiElement file = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(document);
      if (file == null) return;

      toUpdate = Collections.singletonList(Pair.create(file, true));
    }
    Application application = ApplicationManager.getApplication();
    final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
    if (editor != null && !application.isUnitTestMode()) {
      application.invokeLater(
          () -> {
            if (!editor.isDisposed()) {
              EditorMarkupModel markupModel = (EditorMarkupModel) editor.getMarkupModel();
              PsiFile file =
                  PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
              TrafficLightRenderer.setOrRefreshErrorStripeRenderer(
                  markupModel, myProject, editor.getDocument(), file);
            }
          },
          ModalityState.stateForComponent(editor.getComponent()),
          myProject.getDisposed());
    }

    for (Pair<PsiElement, Boolean> changedElement : toUpdate) {
      PsiElement element = changedElement.getFirst();
      Boolean whiteSpaceOptimizationAllowed = changedElement.getSecond();
      updateByChange(element, document, whiteSpaceOptimizationAllowed);
    }
    changedElements.remove(document);
  }
  private void updateContext(final String qName) {
    ApplicationManager.getApplication()
        .runReadAction(
            new Runnable() {
              public void run() {
                final Project project = myProject;
                final PsiClass psiClass =
                    project != null
                        ? DebuggerUtils.findClass(
                            qName, project, GlobalSearchScope.allScope(project))
                        : null;
                myLabelEditor.setContext(psiClass);
                myChildrenEditor.setContext(psiClass);
                myChildrenExpandedEditor.setContext(psiClass);
                myListChildrenEditor.setContext(psiClass);

                PsiType type = DebuggerUtils.getType(qName, project);
                myLabelEditor.setThisType(type);
                myChildrenEditor.setThisType(type);
                myChildrenExpandedEditor.setThisType(type);
                myListChildrenEditor.setThisType(type);
              }
            });

    // Need to recreate fields documents with the new context
    ApplicationManager.getApplication()
        .invokeLater(
            new Runnable() {
              @Override
              public void run() {
                myLabelEditor.setText(myLabelEditor.getText());
                myChildrenEditor.setText(myChildrenEditor.getText());
                myChildrenExpandedEditor.setText(myChildrenExpandedEditor.getText());
                myListChildrenEditor.setText(myListChildrenEditor.getText());
              }
            },
            ModalityState.any(),
            myProject.getDisposed());
  }
    @Override
    public void itemSelected(LookupEvent event) {
      LookupElement item = event.getItem();
      if (item == null) return;

      char c = event.getCompletionChar();
      if (myCheckCompletionChar && !LookupEvent.isSpecialCompletionChar(c)) {
        return;
      }

      final Project project = myContext.getProject();
      if (project == null) {
        return;
      }

      Runnable runnable =
          () ->
              new WriteCommandAction(project) {
                @Override
                protected void run(@NotNull com.intellij.openapi.application.Result result)
                    throws Throwable {
                  Editor editor = myContext.getEditor();
                  if (editor != null) {
                    TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
                    if (templateState != null) {
                      templateState.considerNextTabOnLookupItemSelected(item);
                    }
                  }
                }
              }.execute();
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        runnable.run();
      } else {
        ApplicationManager.getApplication()
            .invokeLater(runnable, ModalityState.current(), project.getDisposed());
      }
    }