@Override
  public @Nullable Element getState() {
    Element element = new Element("state");

    Set<String> urls = new TreeSet<>();
    for (Map<String, String> map : myResources.values()) {
      urls.addAll(map.keySet());
    }

    for (String url : urls) {
      if (url == null) {
        continue;
      }

      String location = getResourceLocation(url);
      if (location == null) {
        continue;
      }

      Element e = new Element(RESOURCE_ELEMENT);
      e.setAttribute(URL_ATTR, url);
      e.setAttribute(LOCATION_ATTR, location.replace(File.separatorChar, '/'));
      element.addContent(e);
    }

    myIgnoredResources.removeAll(myStandardIgnoredResources);
    for (String ignoredResource : myIgnoredResources) {
      Element e = new Element(IGNORED_RESOURCE_ELEMENT);
      e.setAttribute(URL_ATTR, ignoredResource);
      element.addContent(e);
    }

    if (myDefaultHtmlDoctype != null && !HTML5_DOCTYPE_ELEMENT.equals(myDefaultHtmlDoctype)) {
      Element e = new Element(HTML_DEFAULT_DOCTYPE_ELEMENT);
      e.setText(myDefaultHtmlDoctype);
      element.addContent(e);
    }
    if (myXMLSchemaVersion != XMLSchemaVersion.XMLSchema_1_0) {
      Element e = new Element(XML_SCHEMA_VERSION);
      e.setText(myXMLSchemaVersion.toString());
      element.addContent(e);
    }
    if (myCatalogPropertiesFile != null) {
      Element properties = new Element(CATALOG_PROPERTIES_ELEMENT);
      properties.setText(myCatalogPropertiesFile);
      element.addContent(properties);
    }

    ReplacePathToMacroMap macroReplacements = new ReplacePathToMacroMap();
    PathMacrosImpl.getInstanceEx().addMacroReplacements(macroReplacements);
    macroReplacements.substitute(element, SystemInfo.isFileSystemCaseSensitive);
    return element;
  }
@Override
  public @Nullable Element getState()