protected void runOverEditor(
      @NotNull final Project project,
      @NotNull final Editor editor,
      @NotNull final PsiFile psiFile) {
    final Document document = editor.getDocument();
    if (!ReadonlyStatusHandler.ensureDocumentWritable(project, document)) return;

    final Runnable runnable =
        () -> {
          final int caretOffset = editor.getCaretModel().getOffset();
          final int lineLength = getRightMargin(project);

          DartAnalysisServerService.getInstance().updateFilesContent();
          DartAnalysisServerService.FormatResult formatResult =
              DartAnalysisServerService.getInstance()
                  .edit_format(psiFile.getVirtualFile(), caretOffset, 0, lineLength);

          if (formatResult == null) {
            showHintLater(editor, DartBundle.message("dart.style.hint.failed"), true);
            LOG.warn("Unexpected response from edit_format, formatResult is null");
            return;
          }

          final List<SourceEdit> edits = formatResult.getEdits();
          if (edits == null || edits.size() == 0) {
            showHintLater(editor, DartBundle.message("dart.style.hint.already.good"), false);
          } else if (edits.size() == 1) {
            final String replacement =
                StringUtil.convertLineSeparators(edits.get(0).getReplacement());
            document.replaceString(0, document.getTextLength(), replacement);
            final int offset =
                DartAnalysisServerService.getInstance()
                    .getConvertedOffset(psiFile.getVirtualFile(), formatResult.getOffset());
            editor.getCaretModel().moveToOffset(offset);
            showHintLater(editor, DartBundle.message("dart.style.hint.success"), false);
          } else {
            showHintLater(editor, DartBundle.message("dart.style.hint.failed"), true);
            LOG.warn(
                "Unexpected response from edit_format, formatResult.getEdits().size() = "
                    + edits.size());
          }
        };

    ApplicationManager.getApplication()
        .runWriteAction(
            () ->
                CommandProcessor.getInstance()
                    .executeCommand(
                        project, runnable, DartBundle.message("dart.style.action.name"), null));
  }
  private void analyzeFile(
      @NotNull final VirtualFile virtualFile,
      @NotNull final Project project,
      final double progressFraction) {
    updateIndicator("Analyzing " + virtualFile.getName() + "...", progressFraction);

    final DartAnalysisServerAnnotator annotator = new DartAnalysisServerAnnotator();

    final DartAnalysisServerAnnotator.AnnotatorInfo annotatorInfo =
        ApplicationManager.getApplication()
            .runReadAction(
                new NullableComputable<DartAnalysisServerAnnotator.AnnotatorInfo>() {
                  @Nullable
                  public DartAnalysisServerAnnotator.AnnotatorInfo compute() {
                    final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
                    if (psiFile == null) return null;
                    return annotator.collectInformation(psiFile, null, false);
                  }
                });
    if (annotatorInfo == null) return;

    annotatorInfo.setLongerAnalysisTimeout(true);

    final AnalysisError[] errors =
        DartAnalysisServerService.getInstance().analysis_getErrors(annotatorInfo);
    if (errors == null || errors.length == 0) return;

    myVirtualFile2ErrorsMap.put(virtualFile, errors);
  }
  protected void runOverFiles(
      @NotNull final Project project, @NotNull final List<VirtualFile> dartFiles) {
    if (dartFiles.isEmpty()) {
      Messages.showInfoMessage(
          project,
          DartBundle.message("dart.style.files.no.dart.files"),
          DartBundle.message("dart.style.action.name"));
      return;
    }

    if (Messages.showOkCancelDialog(
            project,
            DartBundle.message("dart.style.files.dialog.question", dartFiles.size()),
            DartBundle.message("dart.style.action.name"),
            null)
        != Messages.OK) {
      return;
    }

    final Map<VirtualFile, String> fileToNewContentMap = new THashMap<VirtualFile, String>();
    final int lineLength = getRightMargin(project);

    final Runnable runnable =
        () -> {
          double fraction = 0.0;
          for (final VirtualFile virtualFile : dartFiles) {
            fraction += 1.0;
            final ProgressIndicator indicator =
                ProgressManager.getInstance().getProgressIndicator();
            if (indicator != null) {
              indicator.checkCanceled();
              indicator.setFraction(fraction / dartFiles.size());
              indicator.setText2(FileUtil.toSystemDependentName(virtualFile.getPath()));
            }

            final DartAnalysisServerService.FormatResult formatResult =
                DartAnalysisServerService.getInstance().edit_format(virtualFile, 0, 0, lineLength);
            if (formatResult != null
                && formatResult.getEdits() != null
                && formatResult.getEdits().size() == 1) {
              final String replacement =
                  StringUtil.convertLineSeparators(formatResult.getEdits().get(0).getReplacement());
              fileToNewContentMap.put(virtualFile, replacement);
            }
          }
        };

    DartAnalysisServerService.getInstance().updateFilesContent();

    final boolean ok =
        ApplicationManagerEx.getApplicationEx()
            .runProcessWithProgressSynchronously(
                runnable, DartBundle.message("dart.style.action.name"), true, project);

    if (ok) {
      final Runnable onSuccessRunnable =
          () -> {
            CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);

            for (Map.Entry<VirtualFile, String> entry : fileToNewContentMap.entrySet()) {
              final VirtualFile file = entry.getKey();
              final Document document = FileDocumentManager.getInstance().getDocument(file);
              final String newContent = entry.getValue();

              if (document != null && newContent != null) {
                document.setText(newContent);
              }
            }
          };

      ApplicationManager.getApplication()
          .runWriteAction(
              () ->
                  CommandProcessor.getInstance()
                      .executeCommand(
                          project,
                          onSuccessRunnable,
                          DartBundle.message("dart.style.action.name"),
                          null));
    }
  }
  protected void runOverFiles(
      @NotNull final Project project, @NotNull final List<VirtualFile> dartFiles) {
    if (dartFiles.isEmpty()) {
      Messages.showInfoMessage(
          project,
          DartBundle.message("dart.sort.members.files.no.dart.files"),
          DartBundle.message("dart.sort.members.action.name"));
      return;
    }

    if (Messages.showOkCancelDialog(
            project,
            DartBundle.message("dart.sort.members.files.dialog.question", dartFiles.size()),
            DartBundle.message("dart.sort.members.action.name"),
            null)
        != Messages.OK) {
      return;
    }

    final Map<VirtualFile, SourceFileEdit> fileToFileEditMap = Maps.newHashMap();

    final Runnable runnable =
        new Runnable() {
          public void run() {
            double fraction = 0.0;
            for (final VirtualFile virtualFile : dartFiles) {
              fraction += 1.0;
              final ProgressIndicator indicator =
                  ProgressManager.getInstance().getProgressIndicator();
              if (indicator != null) {
                indicator.checkCanceled();
                indicator.setFraction(fraction / dartFiles.size());
                indicator.setText2(FileUtil.toSystemDependentName(virtualFile.getPath()));
              }

              final String path = virtualFile.getPath();
              final SourceFileEdit fileEdit =
                  DartAnalysisServerService.getInstance().edit_sortMembers(path);
              if (fileEdit != null) {
                fileToFileEditMap.put(virtualFile, fileEdit);
              }
            }
          }
        };

    DartAnalysisServerService.getInstance().updateFilesContent();

    final boolean ok =
        ApplicationManagerEx.getApplicationEx()
            .runProcessWithProgressSynchronously(
                runnable, DartBundle.message("dart.sort.members.action.name"), true, project);

    if (ok) {
      final Runnable onSuccessRunnable =
          new Runnable() {
            @Override
            public void run() {
              CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);

              for (Map.Entry<VirtualFile, SourceFileEdit> entry : fileToFileEditMap.entrySet()) {
                final VirtualFile file = entry.getKey();
                final Document document = FileDocumentManager.getInstance().getDocument(file);
                final SourceFileEdit fileEdit = entry.getValue();
                if (document != null) {
                  AssistUtils.applySourceEdits(document, fileEdit.getEdits());
                }
              }
            }
          };

      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  CommandProcessor.getInstance()
                      .executeCommand(
                          project,
                          onSuccessRunnable,
                          DartBundle.message("dart.sort.members.action.name"),
                          null);
                }
              });
    }
  }