private void annotateExternally(@NotNull VirtualFile root, @NotNull List<? extends ExternalAnnotation> annotations) {
    Project project = myPsiManager.getProject();

    Map<Optional<VirtualFile>, List<ExternalAnnotation>> annotationsByFiles = annotations.stream()
      .collect(Collectors.groupingBy(annotation -> Optional.ofNullable(getFileForAnnotations(root, annotation.getOwner(), project))
        .map(xmlFile -> xmlFile.getVirtualFile())));

    List<VirtualFile> files = StreamEx.ofKeys(annotationsByFiles).flatMap(StreamEx::of).nonNull().toList();
    ReadonlyStatusHandler.OperationStatus status = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(files);
    if (status.hasReadonlyFiles()) {
      VirtualFile[] readonlyFiles = status.getReadonlyFiles();
      annotationsByFiles.keySet()
        .removeIf(opt -> opt.filter(f -> ArrayUtil.contains(f, readonlyFiles)).isPresent());
    }

    if (annotationsByFiles.isEmpty()) return;

    WriteCommandAction.writeCommandAction(project).run(new ThrowableRunnable<>() {
      @Override
      public void run() throws RuntimeException {
        if (project.isDisposed()) return;
        if (DumbService.isDumb(project)) {
          DumbService.getInstance(project).runWhenSmart(() -> WriteCommandAction.writeCommandAction(project).run(this));
          return;
        }
        try {
          for (Map.Entry<Optional<VirtualFile>, List<ExternalAnnotation>> entry : annotationsByFiles.entrySet()) {
            VirtualFile annotationsFile = entry.getKey().orElse(null);
            if (annotationsFile == null) continue;
            List<ExternalAnnotation> fileAnnotations = entry.getValue();
            PsiFile file = PsiManager.getInstance(project).findFile(annotationsFile);
            if (file instanceof XmlFile) {
              annotateExternally((XmlFile)file, fileAnnotations);
            }
          }

          UndoManager.getInstance(project).undoableActionPerformed(new BasicUndoableAction() {
            @Override
            public void undo() {
              dropAnnotationsCache();
              notifyChangedExternally();
            }

            @Override
            public void redo() {
              dropAnnotationsCache();
              notifyChangedExternally();
            }
          });
        }
        finally {
          dropAnnotationsCache();
        }
      }
    });
  }
private void annotateExternally(@NotNull VirtualFile root, @NotNull List<? extends ExternalAnnotation> annotations)