// Path: cassandra-migration/src/main/java/org/cognitor/cassandra/migration/util/Ensure.java
// public static <T> T notNull(T argument, String argumentName) {
//     if (argument == null) {
//         throw new IllegalArgumentException("Argument " + argumentName + " must not be null.");
//     }
//     return argument;
// }
// 
// Path: cassandra-migration/src/main/java/org/cognitor/cassandra/migration/util/Ensure.java
// public static String notNullOrEmpty(String argument, String argumentName) {
//     if (argument == null || argument.trim().isEmpty()) {
//         throw new IllegalArgumentException("Argument " + argumentName + " must not be null or empty.");
//     }
//     return argument;
// }


import java.util.HashMap;
import java.util.Map;
import static org.cognitor.cassandra.migration.util.Ensure.notNull;
import static org.cognitor.cassandra.migration.util.Ensure.notNullOrEmpty;
package org.cognitor.cassandra.migration.scanner;



/**
 * The <code>ScannerRegistry</code> is used to provide a {@link LocationScanner}
 * depending on the scheme that is provided. This default implementation
 * knows two types:
 * <ul>
 *     <li>Jar scanning</li>
 *     <li>Filesystem scanning</li>
 * </ul>
 * In case the provided scheme is "jar", the {@link JarLocationScanner} is returned. For
 * the scheme "file" the {@link FileSystemLocationScanner} is returned. If you want to include
 * you own scanner implementation you can register it here with the appropriate
 * scheme. If you need to overwrite on existing one you can do this as well by providing
 * the scheme you want to overwrite. You can use the constants of this class for convenience.
 *
 * The scheme names are considered case-insensitive, therefore "JAR" and "jar" will return
 * the same entry.
 *
 * @author Patrick Kranz
 */
public class ScannerRegistry {
    /**
     * The scheme used to register scanners for jar files
     */
    public static final String JAR_SCHEME = "jar";
    /**
     * The scheme used to register scanners for file locations
     */
    public static final String FILE_SCHEME = "file";

    private final Map<String, LocationScanner> scanners;

    public ScannerRegistry() {
        this.scanners = new HashMap<>();
        this.scanners.put(JAR_SCHEME, new JarLocationScanner());
        this.scanners.put(FILE_SCHEME, new FileSystemLocationScanner());
    }

    /**
     * Returns the correct implementation of a {@link LocationScanner}
     * depending on the scheme or null of no scanner for this scheme is
     * registered.
     *
     * @param scheme the scheme that should be supported
     * @return {@link JarLocationScanner} if scheme is "jar", {@link FileSystemLocationScanner}
     *      if the scheme is "file" or null if an unknown scheme is given
     * @throws IllegalArgumentException in case scheme is null or empty
     */
    public LocationScanner getScanner(String scheme) {
// Path: cassandra-migration/src/main/java/org/cognitor/cassandra/migration/util/Ensure.java
// public static <T> T notNull(T argument, String argumentName) {
//     if (argument == null) {
//         throw new IllegalArgumentException("Argument " + argumentName + " must not be null.");
//     }
//     return argument;
// }
// 
// Path: cassandra-migration/src/main/java/org/cognitor/cassandra/migration/util/Ensure.java
// public static String notNullOrEmpty(String argument, String argumentName) {
//     if (argument == null || argument.trim().isEmpty()) {
//         throw new IllegalArgumentException("Argument " + argumentName + " must not be null or empty.");
//     }
//     return argument;
// }


// Path: cassandra-migration/src/main/java/org/cognitor/cassandra/migration/scanner/ScannerRegistry.java
import java.util.HashMap;
import java.util.Map;
import static org.cognitor.cassandra.migration.util.Ensure.notNull;
import static org.cognitor.cassandra.migration.util.Ensure.notNullOrEmpty;

package org.cognitor.cassandra.migration.scanner;



/**
 * The <code>ScannerRegistry</code> is used to provide a {@link LocationScanner}
 * depending on the scheme that is provided. This default implementation
 * knows two types:
 * <ul>
 *     <li>Jar scanning</li>
 *     <li>Filesystem scanning</li>
 * </ul>
 * In case the provided scheme is "jar", the {@link JarLocationScanner} is returned. For
 * the scheme "file" the {@link FileSystemLocationScanner} is returned. If you want to include
 * you own scanner implementation you can register it here with the appropriate
 * scheme. If you need to overwrite on existing one you can do this as well by providing
 * the scheme you want to overwrite. You can use the constants of this class for convenience.
 *
 * The scheme names are considered case-insensitive, therefore "JAR" and "jar" will return
 * the same entry.
 *
 * @author Patrick Kranz
 */
public class ScannerRegistry {
    /**
     * The scheme used to register scanners for jar files
     */
    public static final String JAR_SCHEME = "jar";
    /**
     * The scheme used to register scanners for file locations
     */
    public static final String FILE_SCHEME = "file";

    private final Map<String, LocationScanner> scanners;

    public ScannerRegistry() {
        this.scanners = new HashMap<>();
        this.scanners.put(JAR_SCHEME, new JarLocationScanner());
        this.scanners.put(FILE_SCHEME, new FileSystemLocationScanner());
    }

    /**
     * Returns the correct implementation of a {@link LocationScanner}
     * depending on the scheme or null of no scanner for this scheme is
     * registered.
     *
     * @param scheme the scheme that should be supported
     * @return {@link JarLocationScanner} if scheme is "jar", {@link FileSystemLocationScanner}
     *      if the scheme is "file" or null if an unknown scheme is given
     * @throws IllegalArgumentException in case scheme is null or empty
     */
    public LocationScanner getScanner(String scheme) {
        notNullOrEmpty(scheme, "scheme");