@NotNull
  public static RawRuntimeModuleRepositoryData loadFromJar(@NotNull Path jarPath) throws IOException, XMLStreamException {
    Map<String, RawRuntimeModuleDescriptor> rawData = new HashMap<>();
    String mainPluginModuleId;
    try (JarInputStream input = new JarInputStream(new BufferedInputStream(Files.newInputStream(jarPath)))) {
      Manifest manifest = input.getManifest();
      if (manifest == null) {
        throw new IOException("Manifest not found in " + jarPath);
      }
      Attributes mainAttributes = manifest.getMainAttributes();
      String version = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
      if (version == null) {
        throw new IOException("'" + Attributes.Name.SPECIFICATION_VERSION.toString() + "' attribute is not specified in " + jarPath);
      }
      if (!version.equals(SPECIFICATION_VERSION)) {
        throw new IOException("'" + jarPath + "' has unsupported version '" + version + "' ('" + SPECIFICATION_VERSION + "' is expected)");
      }
      mainPluginModuleId = mainAttributes.getValue(MAIN_PLUGIN_MODULE_ATTRIBUTE_NAME);
      JarEntry entry;
      XMLInputFactory factory = XMLInputFactory.newDefaultFactory();
      while ((entry = input.getNextJarEntry()) != null) {
        String name = entry.getName();
        if (name.endsWith(".xml")) {
          RawRuntimeModuleDescriptor data = ModuleXmlSerializer.parseModuleXml(factory, input);
          rawData.put(data.getId(), data);
        }
      }
    }
    return new RawRuntimeModuleRepositoryData(rawData, jarPath.getParent(), mainPluginModuleId);
  }
@NotNull
  public static RawRuntimeModuleRepositoryData loadFromJar(@NotNull Path jarPath)