// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/PluginException.java
// public class PluginException extends Exception {
// 
//     private Optional<DependencyProblem> dependencyProblem = Optional.empty();
// 
//     private Optional<PluginMetadata> pluginMetadata = Optional.empty();
// 
//     public PluginException(Exception e) {
//         super(e);
//     }
// 
//     public PluginException(String message) {
//         super(message);
//     }
// 
//     public PluginException(String message, Exception e) {
//         super(message, e);
//     }
// 
//     public PluginException withDependencyProblem(DependencyProblem dependencyProblem) {
//         this.dependencyProblem = Optional.ofNullable(dependencyProblem);
//         return this;
//     }
// 
//     public PluginException withPlugin(PluginMetadata pluginMetadata) {
//         this.pluginMetadata = Optional.ofNullable(pluginMetadata);
//         return this;
//     }
// 
//     /**
//      * Returns dependency problem if any
//      *
//      * @return dependency problem
//      */
//     public Optional<DependencyProblem> getDependencyProblem() {
//         return dependencyProblem;
//     }
// 
//     /**
//      * Returns plugin affected
//      *
//      * @return plugin metadata
//      */
//     public Optional<PluginMetadata> getPluginMetadata() {
//         return pluginMetadata;
//     }
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/PluginMetadata.java
// public interface PluginMetadata {
// 
//     /**
//      * Returns unique plugin name
//      *
//      * @return free-form string with name
//      */
//     String getName();
// 
//     /**
//      * Returns plugin version
//      *
//      * @return free-form string with version
//      */
//     String getVersion();
// 
//     /**
//      * Returns {@link Path} object corresponding to plugin file
//      *
//      * @return plugin {@link Path} object
//      */
//     Path getPath();
// 
//     /**
//      * Returns {@link org.meridor.stecker.interfaces.Dependency} object corresponding to this plugin
//      *
//      * @return dependency object
//      */
//     Dependency getDependency();
// 
//     /**
//      * Returns date when plugin was released
//      *
//      * @return local date or empty if not set
//      */
//     Optional<ZonedDateTime> getDate();
// 
//     /**
//      * Returns detailed plugin description
//      *
//      * @return description or empty if not set
//      */
//     Optional<String> getDescription();
// 
//     /**
//      * Returns maintainer email and name
//      *
//      * @return email and name in the format: <b>John Smith &lt;john.smith@example.com&gt;</b> or empty if not set
//      */
//     Optional<String> getMaintainer();
// 
//     /**
//      * Returns a list of plugins required to make this plugin work
//      *
//      * @return possibly empty list with dependencies
//      */
//     List<Dependency> getRequiredDependencies();
// 
//     /**
//      * Returns a list of plugins that should be never installed simultaneously with this plugin
//      *
//      * @return possibly empty list with conflicting dependencies
//      */
//     List<Dependency> getConflictingDependencies();
// 
//     /**
//      * Returns a meta dependency which is provided by this plugin
//      *
//      * @return meta dependency or empty if not set
//      */
//     Optional<Dependency> getProvidedDependency();
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/PluginRegistry.java
// public interface PluginRegistry extends PluginsAware, ImplementationsAware, ResourcesAware, ClassLoaderAware {
// 
//     /**
//      * Add extension point implementations to registry
//      *
//      * @param pluginMetadata        plugin metadata object
//      * @param extensionPoint        extension point class
//      * @param implementationClasses a list of implementation classes
//      */
//     void addImplementations(PluginMetadata pluginMetadata, Class extensionPoint, List<Class> implementationClasses);
// 
//     /**
//      * Adds information about new plugin
//      *
//      * @param pluginMetadata plugin metadata object
//      * @throws PluginException when another plugin provides the same virtual dependency
//      */
//     void addPlugin(PluginMetadata pluginMetadata) throws PluginException;
// 
//     /**
//      * Add resources for specific plugin
//      *
//      * @param pluginMetadata plugin metadata object
//      * @param resources      plugin resources
//      */
//     void addResources(PluginMetadata pluginMetadata, List<Path> resources);
// 
//     /**
//      * Adds class loader instance for specific plugin
//      *
//      * @param pluginMetadata plugin metadata object
//      * @param classLoader    class loader instance corresponding to current plugin
//      */
//     void addClassLoader(PluginMetadata pluginMetadata, ClassLoader classLoader);
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/Dependency.java
// public interface Dependency {
// 
//     /**
//      * Returns dependency name
//      *
//      * @return dependency name
//      */
//     String getName();
// 
//     /**
//      * Returns dependency version if present
//      *
//      * @return dependency version if present and empty otherwise
//      */
//     Optional<String> getVersion();
// 
//     /**
//      * Forces to override {@link Object#equals(Object)}
//      *
//      * @param anotherDependency dependency to compare to
//      * @return true if equal and false otherwise
//      */
//     boolean equals(Object anotherDependency);
// 
//     /**
//      * Forces to override {@link Object#hashCode()}
//      *
//      * @return instance hash code
//      */
//     int hashCode();
// 
//     /**
//      * Returns dependency string representation
//      *
//      * @return dependency string representation
//      */
//     String toString();
// 
// }


import org.meridor.stecker.PluginException;
import org.meridor.stecker.PluginMetadata;
import org.meridor.stecker.PluginRegistry;
import org.meridor.stecker.interfaces.Dependency;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
package org.meridor.stecker.impl;



public class PluginRegistryContainer implements PluginRegistry {

    private final Map<String, ClassesRegistry> registry = new HashMap<>();

    private final Map<String, PluginMetadata> plugins = new HashMap<>();

// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/PluginException.java
// public class PluginException extends Exception {
// 
//     private Optional<DependencyProblem> dependencyProblem = Optional.empty();
// 
//     private Optional<PluginMetadata> pluginMetadata = Optional.empty();
// 
//     public PluginException(Exception e) {
//         super(e);
//     }
// 
//     public PluginException(String message) {
//         super(message);
//     }
// 
//     public PluginException(String message, Exception e) {
//         super(message, e);
//     }
// 
//     public PluginException withDependencyProblem(DependencyProblem dependencyProblem) {
//         this.dependencyProblem = Optional.ofNullable(dependencyProblem);
//         return this;
//     }
// 
//     public PluginException withPlugin(PluginMetadata pluginMetadata) {
//         this.pluginMetadata = Optional.ofNullable(pluginMetadata);
//         return this;
//     }
// 
//     /**
//      * Returns dependency problem if any
//      *
//      * @return dependency problem
//      */
//     public Optional<DependencyProblem> getDependencyProblem() {
//         return dependencyProblem;
//     }
// 
//     /**
//      * Returns plugin affected
//      *
//      * @return plugin metadata
//      */
//     public Optional<PluginMetadata> getPluginMetadata() {
//         return pluginMetadata;
//     }
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/PluginMetadata.java
// public interface PluginMetadata {
// 
//     /**
//      * Returns unique plugin name
//      *
//      * @return free-form string with name
//      */
//     String getName();
// 
//     /**
//      * Returns plugin version
//      *
//      * @return free-form string with version
//      */
//     String getVersion();
// 
//     /**
//      * Returns {@link Path} object corresponding to plugin file
//      *
//      * @return plugin {@link Path} object
//      */
//     Path getPath();
// 
//     /**
//      * Returns {@link org.meridor.stecker.interfaces.Dependency} object corresponding to this plugin
//      *
//      * @return dependency object
//      */
//     Dependency getDependency();
// 
//     /**
//      * Returns date when plugin was released
//      *
//      * @return local date or empty if not set
//      */
//     Optional<ZonedDateTime> getDate();
// 
//     /**
//      * Returns detailed plugin description
//      *
//      * @return description or empty if not set
//      */
//     Optional<String> getDescription();
// 
//     /**
//      * Returns maintainer email and name
//      *
//      * @return email and name in the format: <b>John Smith &lt;john.smith@example.com&gt;</b> or empty if not set
//      */
//     Optional<String> getMaintainer();
// 
//     /**
//      * Returns a list of plugins required to make this plugin work
//      *
//      * @return possibly empty list with dependencies
//      */
//     List<Dependency> getRequiredDependencies();
// 
//     /**
//      * Returns a list of plugins that should be never installed simultaneously with this plugin
//      *
//      * @return possibly empty list with conflicting dependencies
//      */
//     List<Dependency> getConflictingDependencies();
// 
//     /**
//      * Returns a meta dependency which is provided by this plugin
//      *
//      * @return meta dependency or empty if not set
//      */
//     Optional<Dependency> getProvidedDependency();
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/PluginRegistry.java
// public interface PluginRegistry extends PluginsAware, ImplementationsAware, ResourcesAware, ClassLoaderAware {
// 
//     /**
//      * Add extension point implementations to registry
//      *
//      * @param pluginMetadata        plugin metadata object
//      * @param extensionPoint        extension point class
//      * @param implementationClasses a list of implementation classes
//      */
//     void addImplementations(PluginMetadata pluginMetadata, Class extensionPoint, List<Class> implementationClasses);
// 
//     /**
//      * Adds information about new plugin
//      *
//      * @param pluginMetadata plugin metadata object
//      * @throws PluginException when another plugin provides the same virtual dependency
//      */
//     void addPlugin(PluginMetadata pluginMetadata) throws PluginException;
// 
//     /**
//      * Add resources for specific plugin
//      *
//      * @param pluginMetadata plugin metadata object
//      * @param resources      plugin resources
//      */
//     void addResources(PluginMetadata pluginMetadata, List<Path> resources);
// 
//     /**
//      * Adds class loader instance for specific plugin
//      *
//      * @param pluginMetadata plugin metadata object
//      * @param classLoader    class loader instance corresponding to current plugin
//      */
//     void addClassLoader(PluginMetadata pluginMetadata, ClassLoader classLoader);
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/Dependency.java
// public interface Dependency {
// 
//     /**
//      * Returns dependency name
//      *
//      * @return dependency name
//      */
//     String getName();
// 
//     /**
//      * Returns dependency version if present
//      *
//      * @return dependency version if present and empty otherwise
//      */
//     Optional<String> getVersion();
// 
//     /**
//      * Forces to override {@link Object#equals(Object)}
//      *
//      * @param anotherDependency dependency to compare to
//      * @return true if equal and false otherwise
//      */
//     boolean equals(Object anotherDependency);
// 
//     /**
//      * Forces to override {@link Object#hashCode()}
//      *
//      * @return instance hash code
//      */
//     int hashCode();
// 
//     /**
//      * Returns dependency string representation
//      *
//      * @return dependency string representation
//      */
//     String toString();
// 
// }


// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/impl/PluginRegistryContainer.java
import org.meridor.stecker.PluginException;
import org.meridor.stecker.PluginMetadata;
import org.meridor.stecker.PluginRegistry;
import org.meridor.stecker.interfaces.Dependency;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

package org.meridor.stecker.impl;



public class PluginRegistryContainer implements PluginRegistry {

    private final Map<String, ClassesRegistry> registry = new HashMap<>();

    private final Map<String, PluginMetadata> plugins = new HashMap<>();

    private final Map<String, List<Path>> resources = new HashMap<>();