// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/impl/ManifestField.java
// public enum ManifestField {
// 
//     NAME("Plugin-Name"),
//     VERSION("Plugin-Version"),
//     DATE("Plugin-Date"),
//     DESCRIPTION("Plugin-Description"),
//     MAINTAINER("Plugin-Maintainer"),
//     DEPENDS("Plugin-Depends"),
//     CONFLICTS("Plugin-Conflicts"),
//     PROVIDES("Plugin-Provides");
// 
//     private final String fieldName;
// 
//     private ManifestField(String fieldName) {
//         this.fieldName = fieldName;
//     }
// 
//     public String getFieldName() {
//         return fieldName;
//     }
// }
// 
// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/impl/data/AnnotatedImpl.java
// @TestAnnotation
// public class AnnotatedImpl {
// }
// 
// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/impl/data/TestExtensionPoint.java
// public interface TestExtensionPoint {
// 
//     void doSomething();
// 
// }
// 
// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/impl/data/TestExtensionPointImpl.java
// public class TestExtensionPointImpl implements TestExtensionPoint {
// 
//     @Override
//     public void doSomething() {
//         new LibraryClass().act();
//     }
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/ClassesScanner.java
// public interface ClassesScanner {
// 
//     /**
//      * Returns a mapping between extension point classes and plugin file classes. E.g. if extension point is
//      * an interface <b>A</b> and some plugin implements it in classes B and C then the mapping will be: A -&gt; (B, C).
//      *
//      * @param pluginFile      plugin file to process
//      * @param extensionPoints a list of extension point classes
//      * @return mapping from extension point to implementations from a plugin
//      * @throws org.meridor.stecker.PluginException when something goes wrong during classes scanning
//      */
//     ScanResult scan(Path pluginFile, List<Class> extensionPoints) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/DependencyChecker.java
// public interface DependencyChecker {
// 
//     /**
//      * Checks dependencies and throws {@link org.meridor.stecker.PluginException} with {@link DependencyProblem} in case of issues
//      *
//      * @param pluginRegistry plugin registry object filled with data about all plugins
//      * @param pluginMetadata checked plugin metadata
//      * @throws org.meridor.stecker.PluginException when dependency issues occur
//      */
//     void check(PluginsAware pluginRegistry, PluginMetadata pluginMetadata) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/ManifestReader.java
// public interface ManifestReader {
// 
//     /**
//      * Reads jar file manifest and returns plugin information stored there
//      *
//      * @param pluginFile plugin file to process
//      * @return plugin information in {@link org.meridor.stecker.PluginMetadata} format
//      * @throws org.meridor.stecker.PluginException when something goes wrong during manifest reading
//      */
//     PluginMetadata read(Path pluginFile) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/PluginsProvider.java
// public interface PluginsProvider {
// 
//     /**
//      * Provides a list of plugins paths
//      *
//      * @param baseDirectory root directory to scan for plugins
//      * @return list of paths that seems to be plugins
//      * @throws org.meridor.stecker.PluginException when something goes wrong during base directory scanning
//      */
//     List<Path> provide(Path baseDirectory) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/ResourcesScanner.java
// public interface ResourcesScanner {
// 
//     /**
//      * Does the scanning
//      *
//      * @param path depending on context can be a file or directory path
//      * @return a list of matching resources
//      * @throws org.meridor.stecker.PluginException when something goes wrong during resources scanning
//      */
//     List<Path> scan(Path path) throws PluginException;
// 
// }


import org.junit.Rule;
import org.junit.Test;
import org.meridor.stecker.impl.ManifestField;
import org.meridor.stecker.impl.data.AnnotatedImpl;
import org.meridor.stecker.impl.data.TestAnnotation;
import org.meridor.stecker.impl.data.TestExtensionPoint;
import org.meridor.stecker.impl.data.TestExtensionPointImpl;
import org.meridor.stecker.interfaces.ClassesScanner;
import org.meridor.stecker.interfaces.DependencyChecker;
import org.meridor.stecker.interfaces.ManifestReader;
import org.meridor.stecker.interfaces.PluginsProvider;
import org.meridor.stecker.interfaces.ResourcesScanner;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
package org.meridor.stecker;




public class PluginLoaderTest {

    @Rule
    public TemporaryDirectory temporaryDirectory = new TemporaryDirectory();

    @Test
    public void testFluentApi() throws PluginException {
        Path pluginDirectory = Paths.get("plugin-directory");
        String fileGlob = "some-glob";
        PluginsProvider pluginsProvider = mock(PluginsProvider.class);
        Path cacheDirectory = Paths.get("cache-directory");
        Class[] extensionPointsArray = new Class[]{TestExtensionPoint.class, TestExtensionPoint.class}; //We intentionally duplicate extension points
        ManifestReader manifestReader = mock(ManifestReader.class);
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/impl/ManifestField.java
// public enum ManifestField {
// 
//     NAME("Plugin-Name"),
//     VERSION("Plugin-Version"),
//     DATE("Plugin-Date"),
//     DESCRIPTION("Plugin-Description"),
//     MAINTAINER("Plugin-Maintainer"),
//     DEPENDS("Plugin-Depends"),
//     CONFLICTS("Plugin-Conflicts"),
//     PROVIDES("Plugin-Provides");
// 
//     private final String fieldName;
// 
//     private ManifestField(String fieldName) {
//         this.fieldName = fieldName;
//     }
// 
//     public String getFieldName() {
//         return fieldName;
//     }
// }
// 
// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/impl/data/AnnotatedImpl.java
// @TestAnnotation
// public class AnnotatedImpl {
// }
// 
// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/impl/data/TestExtensionPoint.java
// public interface TestExtensionPoint {
// 
//     void doSomething();
// 
// }
// 
// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/impl/data/TestExtensionPointImpl.java
// public class TestExtensionPointImpl implements TestExtensionPoint {
// 
//     @Override
//     public void doSomething() {
//         new LibraryClass().act();
//     }
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/ClassesScanner.java
// public interface ClassesScanner {
// 
//     /**
//      * Returns a mapping between extension point classes and plugin file classes. E.g. if extension point is
//      * an interface <b>A</b> and some plugin implements it in classes B and C then the mapping will be: A -&gt; (B, C).
//      *
//      * @param pluginFile      plugin file to process
//      * @param extensionPoints a list of extension point classes
//      * @return mapping from extension point to implementations from a plugin
//      * @throws org.meridor.stecker.PluginException when something goes wrong during classes scanning
//      */
//     ScanResult scan(Path pluginFile, List<Class> extensionPoints) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/DependencyChecker.java
// public interface DependencyChecker {
// 
//     /**
//      * Checks dependencies and throws {@link org.meridor.stecker.PluginException} with {@link DependencyProblem} in case of issues
//      *
//      * @param pluginRegistry plugin registry object filled with data about all plugins
//      * @param pluginMetadata checked plugin metadata
//      * @throws org.meridor.stecker.PluginException when dependency issues occur
//      */
//     void check(PluginsAware pluginRegistry, PluginMetadata pluginMetadata) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/ManifestReader.java
// public interface ManifestReader {
// 
//     /**
//      * Reads jar file manifest and returns plugin information stored there
//      *
//      * @param pluginFile plugin file to process
//      * @return plugin information in {@link org.meridor.stecker.PluginMetadata} format
//      * @throws org.meridor.stecker.PluginException when something goes wrong during manifest reading
//      */
//     PluginMetadata read(Path pluginFile) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/PluginsProvider.java
// public interface PluginsProvider {
// 
//     /**
//      * Provides a list of plugins paths
//      *
//      * @param baseDirectory root directory to scan for plugins
//      * @return list of paths that seems to be plugins
//      * @throws org.meridor.stecker.PluginException when something goes wrong during base directory scanning
//      */
//     List<Path> provide(Path baseDirectory) throws PluginException;
// 
// }
// 
// Path: stecker-plugin-loader/src/main/java/org/meridor/stecker/interfaces/ResourcesScanner.java
// public interface ResourcesScanner {
// 
//     /**
//      * Does the scanning
//      *
//      * @param path depending on context can be a file or directory path
//      * @return a list of matching resources
//      * @throws org.meridor.stecker.PluginException when something goes wrong during resources scanning
//      */
//     List<Path> scan(Path path) throws PluginException;
// 
// }


// Path: stecker-plugin-loader/src/test/java/org/meridor/stecker/PluginLoaderTest.java
import org.junit.Rule;
import org.junit.Test;
import org.meridor.stecker.impl.ManifestField;
import org.meridor.stecker.impl.data.AnnotatedImpl;
import org.meridor.stecker.impl.data.TestAnnotation;
import org.meridor.stecker.impl.data.TestExtensionPoint;
import org.meridor.stecker.impl.data.TestExtensionPointImpl;
import org.meridor.stecker.interfaces.ClassesScanner;
import org.meridor.stecker.interfaces.DependencyChecker;
import org.meridor.stecker.interfaces.ManifestReader;
import org.meridor.stecker.interfaces.PluginsProvider;
import org.meridor.stecker.interfaces.ResourcesScanner;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;

package org.meridor.stecker;




public class PluginLoaderTest {

    @Rule
    public TemporaryDirectory temporaryDirectory = new TemporaryDirectory();

    @Test
    public void testFluentApi() throws PluginException {
        Path pluginDirectory = Paths.get("plugin-directory");
        String fileGlob = "some-glob";
        PluginsProvider pluginsProvider = mock(PluginsProvider.class);
        Path cacheDirectory = Paths.get("cache-directory");
        Class[] extensionPointsArray = new Class[]{TestExtensionPoint.class, TestExtensionPoint.class}; //We intentionally duplicate extension points
        ManifestReader manifestReader = mock(ManifestReader.class);
        DependencyChecker dependencyChecker = mock(DependencyChecker.class);