private void annotateExternally(@Nullable XmlFile annotationsFile, @NotNull List<ExternalAnnotation> annotations) {
    XmlTag rootTag = extractRootTag(annotationsFile);

    Map<String, List<ExternalAnnotation>> ownerToAnnotations = StreamEx.of(annotations)
      .mapToEntry(annotation -> {
        String externalName = getExternalName(annotation.getOwner());
        return externalName == null ? null : StringUtil.escapeXmlEntities(externalName);
      }, Function.identity())
      .distinct()
      .grouping(() -> new TreeMap<>(Comparator.nullsFirst(Comparator.naturalOrder())));

    if (rootTag == null) {
      ownerToAnnotations.values().stream().flatMap(List::stream).forEach(annotation ->
                                                                           notifyAfterAnnotationChanging(annotation.getOwner(),
                                                                                                         annotation.getAnnotationFQName(),
                                                                                                         false));
      return;
    }

    List<ExternalAnnotation> savedAnnotations = new ArrayList<>();
    XmlTag startTag = null;

    for (Map.Entry<String, List<ExternalAnnotation>> entry : ownerToAnnotations.entrySet()) {
      @NonNls String ownerName = entry.getKey();
      List<ExternalAnnotation> annotationList = entry.getValue();
      for (ExternalAnnotation annotation : annotationList) {

        if (ownerName == null) {
          notifyAfterAnnotationChanging(annotation.getOwner(), annotation.getAnnotationFQName(), false);
          continue;
        }

        try {
          startTag = addAnnotation(rootTag, ownerName, annotation, startTag);
          savedAnnotations.add(annotation);
        }
        catch (IncorrectOperationException e) {
          LOG.error(e);
          notifyAfterAnnotationChanging(annotation.getOwner(), annotation.getAnnotationFQName(), false);
        }
        finally {
          dropAnnotationsCache();
          markForUndo(annotation.getOwner().getContainingFile());
        }
      }
    }

    commitChanges(annotationsFile);
    savedAnnotations.forEach(annotation ->
                               notifyAfterAnnotationChanging(annotation.getOwner(), annotation.getAnnotationFQName(), true));
  }
private void annotateExternally(@Nullable XmlFile annotationsFile, @NotNull List<ExternalAnnotation> annotations)