@NotNull
  public static TreeMap<String, Element> load(
      @NotNull Element rootElement,
      @Nullable PathMacroSubstitutor pathMacroSubstitutor,
      boolean intern) {
    if (pathMacroSubstitutor != null) {
      pathMacroSubstitutor.expandPaths(rootElement);
    }

    StringInterner interner = intern ? new StringInterner() : null;
    List<Element> children = rootElement.getChildren(COMPONENT);
    TreeMap<String, Element> map = new TreeMap<String, Element>();
    for (Element element : children) {
      String name = getComponentNameIfValid(element);
      if (name == null
          || !(element.getAttributes().size() > 1 || !element.getChildren().isEmpty())) {
        continue;
      }

      if (interner != null) {
        JDOMUtil.internElement(element, interner);
      }

      map.put(name, element);

      if (pathMacroSubstitutor instanceof TrackingPathMacroSubstitutor) {
        ((TrackingPathMacroSubstitutor) pathMacroSubstitutor)
            .addUnknownMacros(name, PathMacrosCollector.getMacroNames(element));
      }

      // remove only after "getMacroNames" - some PathMacroFilter requires element name attribute
      element.removeAttribute(NAME);
    }
    return map;
  }
  @Nullable
  @Override
  public Element getSerializedState(
      @NotNull Boolean storageData,
      Object component,
      @NotNull String componentName,
      boolean archive) {
    if (storageData) {
      return null;
    }

    Element element = new Element("component");
    ModifiableRootModel model = null;
    AccessToken token = ReadAction.start();
    try {
      model = ((ModuleRootManagerImpl) component).getModifiableModel();
      // IDEA-137969 Eclipse integration: external remove of classpathentry is not synchronized
      model.clear();
      try {
        myConverter.readClasspath(model);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
      ((RootModelImpl) model).writeExternal(element);
    } catch (WriteExternalException e) {
      LOG.error(e);
    } finally {
      try {
        token.finish();
      } finally {
        if (model != null) {
          model.dispose();
        }
      }
    }

    if (myPathMacroSubstitutor != null) {
      myPathMacroSubstitutor.expandPaths(element);
      myPathMacroSubstitutor.addUnknownMacros(
          "NewModuleRootManager", PathMacrosCollector.getMacroNames(element));
    }

    getStorageDataRef().set(true);
    return element;
  }