private void appendChosenAnnotationsRoot(
     @NotNull final OrderEntry entry, @NotNull final VirtualFile vFile) {
   if (entry instanceof LibraryOrderEntry) {
     Library library = ((LibraryOrderEntry) entry).getLibrary();
     LOG.assertTrue(library != null);
     final ModifiableRootModel rootModel =
         ModuleRootManager.getInstance(entry.getOwnerModule()).getModifiableModel();
     final Library.ModifiableModel model = library.getModifiableModel();
     model.addRoot(vFile, AnnotationOrderRootType.getInstance());
     model.commit();
     rootModel.commit();
   } else if (entry instanceof ModuleSourceOrderEntry) {
     final ModifiableRootModel model =
         ModuleRootManager.getInstance(entry.getOwnerModule()).getModifiableModel();
     final JavaModuleExternalPaths extension =
         model.getModuleExtension(JavaModuleExternalPaths.class);
     extension.setExternalAnnotationUrls(
         ArrayUtil.mergeArrays(extension.getExternalAnnotationsUrls(), vFile.getUrl()));
     model.commit();
   } else if (entry instanceof JdkOrderEntry) {
     final SdkModificator sdkModificator = ((JdkOrderEntry) entry).getJdk().getSdkModificator();
     sdkModificator.addRoot(vFile, AnnotationOrderRootType.getInstance());
     sdkModificator.commitChanges();
   }
   myExternalAnnotations.clear();
 }
  @Override
  public void annotateExternally(
      @NotNull final PsiModifierListOwner listOwner,
      @NotNull final String annotationFQName,
      @NotNull final PsiFile fromFile,
      @Nullable final PsiNameValuePair[] value) {
    final Project project = myPsiManager.getProject();
    final PsiFile containingFile = listOwner.getContainingFile();
    if (!(containingFile instanceof PsiJavaFile)) {
      notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
      return;
    }
    final String packageName = ((PsiJavaFile) containingFile).getPackageName();
    final VirtualFile containingVirtualFile = containingFile.getVirtualFile();
    LOG.assertTrue(containingVirtualFile != null);
    final List<OrderEntry> entries =
        ProjectRootManager.getInstance(project)
            .getFileIndex()
            .getOrderEntriesForFile(containingVirtualFile);
    if (entries.isEmpty()) {
      notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
      return;
    }
    for (final OrderEntry entry : entries) {
      if (entry instanceof ModuleOrderEntry) continue;
      VirtualFile[] roots = AnnotationOrderRootType.getFiles(entry);
      roots = filterByReadOnliness(roots);

      if (roots.length > 0) {
        chooseRootAndAnnotateExternally(
            listOwner, annotationFQName, fromFile, project, packageName, roots, value);
      } else {
        if (ApplicationManager.getApplication().isUnitTestMode()
            || ApplicationManager.getApplication().isHeadlessEnvironment()) {
          notifyAfterAnnotationChanging(listOwner, annotationFQName, false);
          return;
        }
        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                setupRootAndAnnotateExternally(
                    entry, project, listOwner, annotationFQName, fromFile, packageName, value);
              }
            });
      }
      break;
    }
  }
  @Override
  @NotNull
  public AnnotationPlace chooseAnnotationsPlace(@NotNull final PsiElement element) {
    if (!element.isPhysical()) return AnnotationPlace.IN_CODE; // element just created
    if (!element.getManager().isInProject(element)) return AnnotationPlace.EXTERNAL;
    final Project project = myPsiManager.getProject();
    final PsiFile containingFile = element.getContainingFile();
    final VirtualFile virtualFile = containingFile.getVirtualFile();
    LOG.assertTrue(virtualFile != null);
    final List<OrderEntry> entries =
        ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(virtualFile);
    if (!entries.isEmpty()) {
      for (OrderEntry entry : entries) {
        if (!(entry instanceof ModuleOrderEntry)) {
          if (AnnotationOrderRootType.getUrls(entry).length > 0) {
            return AnnotationPlace.EXTERNAL;
          }
          break;
        }
      }
    }
    final MyExternalPromptDialog dialog =
        ApplicationManager.getApplication().isUnitTestMode()
                || ApplicationManager.getApplication().isHeadlessEnvironment()
            ? null
            : new MyExternalPromptDialog(project);
    if (dialog != null && dialog.isToBeShown()) {
      final PsiElement highlightElement =
          element instanceof PsiNameIdentifierOwner
              ? ((PsiNameIdentifierOwner) element).getNameIdentifier()
              : element.getNavigationElement();
      LOG.assertTrue(highlightElement != null);
      final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
      final List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
      final boolean highlight =
          editor != null
              && editor.getDocument()
                  == PsiDocumentManager.getInstance(project).getDocument(containingFile);
      try {
        if (highlight) { // do not highlight for batch inspections
          final EditorColorsManager colorsManager = EditorColorsManager.getInstance();
          final TextAttributes attributes =
              colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
          final TextRange textRange = highlightElement.getTextRange();
          HighlightManager.getInstance(project)
              .addRangeHighlight(
                  editor,
                  textRange.getStartOffset(),
                  textRange.getEndOffset(),
                  attributes,
                  true,
                  highlighters);
          final LogicalPosition logicalPosition =
              editor.offsetToLogicalPosition(textRange.getStartOffset());
          editor.getScrollingModel().scrollTo(logicalPosition, ScrollType.CENTER);
        }

        dialog.show();
        if (dialog.getExitCode() == 2) {
          return AnnotationPlace.EXTERNAL;
        } else if (dialog.getExitCode() == 1) {
          return AnnotationPlace.NOWHERE;
        }

      } finally {
        if (highlight) {
          HighlightManager.getInstance(project)
              .removeSegmentHighlighter(editor, highlighters.get(0));
        }
      }
    } else if (dialog != null) {
      dialog.close(DialogWrapper.OK_EXIT_CODE);
    }
    return AnnotationPlace.IN_CODE;
  }