// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/config/AbstractPatch.java
// public abstract class AbstractPatch implements Serializable {
//     private static final long serialVersionUID = 4178101927323891639L;
//     private String name;
//     private int statementCount = -1;
//     private File file;
// 
//     public enum DbState {
//         COMMITTED, IN_PROGRESS, NOT_AVAILABLE
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public int getStatementCount() {
//         return statementCount;
//     }
// 
//     public void setStatementCount(int statementCount) {
//         this.statementCount = statementCount;
//     }
// 
//     public File getFile() {
//         return file;
//     }
// 
//     public void setFile(File file) {
//         this.file = file;
//     }
// 
//     public abstract void setDbDate(Date dbDate);
// 
//     public abstract void setDbState(DbState dbState);
// 
//     public abstract Date getDbDate();
// 
//     public abstract DbState getDbState();
// 
//     public abstract boolean canApply();
// 
//     public String toString() {
//         return super.toString() + "-" + name;
//     }
// 
//     public static String normalizeName(String name) {
//         String nameLC = name.toLowerCase();
//         while (nameLC.endsWith(".sql") || nameLC.endsWith(".undo") || nameLC.endsWith(".rollback")) {
//             int dot = nameLC.lastIndexOf('.');
//             nameLC = nameLC.substring(0, dot);
//         }
//         return name.substring(0, nameLC.length());
//     }
// 
// }
// 
// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/config/PatchScanner.java
// public interface PatchScanner extends Serializable {
// 
//     /**
//      * @param directory base dir
//      * @param paths to scan (add directory if not absolute)
//      * @return list of found patches
//      * @throws DuplicatePatchNameException when duplicated patch names were found
//      * @throws IOException io problem
//      */
//     List<Patch> scan(File directory, String[] paths) throws DuplicatePatchNameException, IOException;
// 
//     /**
//      * @param patch rollbacks for this patch
//      * @param directory base dir
//      * @param paths to scan (add directory if not absolute)
//      * @return null if no file was found
//      * @throws DuplicatePatchNameException when duplicated patch names were found
//      * @throws IOException io problem
//      */
//     File findRollbackFile(File directory, String[] paths, Patch patch) throws DuplicatePatchNameException, IOException;
// }
// 
// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/log/Log.java
// public interface Log {
// 
//     void trace(String msg, Throwable e);
// 
//     void debug(String msg);
// 
//     void info(String msg);
// 
//     void warn(String msg);
// 
//     void fatal(String msg);
// 
//     void warn(String msg, Throwable e);
// 
//     void fatal(String msg, Throwable e);
// }


import org.apache.commons.io.FilenameUtils;
import org.jsoftware.dbpatch.config.AbstractPatch;
import org.jsoftware.dbpatch.config.Patch;
import org.jsoftware.dbpatch.config.PatchScanner;
import org.jsoftware.dbpatch.log.Log;
import org.jsoftware.dbpatch.log.LogFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
package org.jsoftware.dbpatch.impl;



/**
 * Abstract directory scanner that looks for patch files.
 */
public abstract class SimplePatchScanner implements PatchScanner {
    private final Log log = LogFactory.getInstance();

    public List<Patch> scan(File baseDir, String[] paths) throws DuplicatePatchNameException, IOException {
        List<DirMask> dirMasks = parsePatchDirs(baseDir, paths);
        LinkedList<Patch> list = new LinkedList<Patch>();
        for (DirMask dm : dirMasks) {
            log.debug("Scan for patches " + dm.getDir().getAbsolutePath() + " with " + dm.getMask());
            LinkedList<Patch> dirList = new LinkedList<Patch>();
            notADirectoryCheck(dm.getDir());
            File[] fList = dm.getDir().listFiles(new WildcardMaskFileFilter(dm.getMask()));
            if (fList != null) {
                for (File f : fList) {
                    Patch p = new Patch();
                    p.setFile(f);
// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/config/AbstractPatch.java
// public abstract class AbstractPatch implements Serializable {
//     private static final long serialVersionUID = 4178101927323891639L;
//     private String name;
//     private int statementCount = -1;
//     private File file;
// 
//     public enum DbState {
//         COMMITTED, IN_PROGRESS, NOT_AVAILABLE
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public int getStatementCount() {
//         return statementCount;
//     }
// 
//     public void setStatementCount(int statementCount) {
//         this.statementCount = statementCount;
//     }
// 
//     public File getFile() {
//         return file;
//     }
// 
//     public void setFile(File file) {
//         this.file = file;
//     }
// 
//     public abstract void setDbDate(Date dbDate);
// 
//     public abstract void setDbState(DbState dbState);
// 
//     public abstract Date getDbDate();
// 
//     public abstract DbState getDbState();
// 
//     public abstract boolean canApply();
// 
//     public String toString() {
//         return super.toString() + "-" + name;
//     }
// 
//     public static String normalizeName(String name) {
//         String nameLC = name.toLowerCase();
//         while (nameLC.endsWith(".sql") || nameLC.endsWith(".undo") || nameLC.endsWith(".rollback")) {
//             int dot = nameLC.lastIndexOf('.');
//             nameLC = nameLC.substring(0, dot);
//         }
//         return name.substring(0, nameLC.length());
//     }
// 
// }
// 
// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/config/PatchScanner.java
// public interface PatchScanner extends Serializable {
// 
//     /**
//      * @param directory base dir
//      * @param paths to scan (add directory if not absolute)
//      * @return list of found patches
//      * @throws DuplicatePatchNameException when duplicated patch names were found
//      * @throws IOException io problem
//      */
//     List<Patch> scan(File directory, String[] paths) throws DuplicatePatchNameException, IOException;
// 
//     /**
//      * @param patch rollbacks for this patch
//      * @param directory base dir
//      * @param paths to scan (add directory if not absolute)
//      * @return null if no file was found
//      * @throws DuplicatePatchNameException when duplicated patch names were found
//      * @throws IOException io problem
//      */
//     File findRollbackFile(File directory, String[] paths, Patch patch) throws DuplicatePatchNameException, IOException;
// }
// 
// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/log/Log.java
// public interface Log {
// 
//     void trace(String msg, Throwable e);
// 
//     void debug(String msg);
// 
//     void info(String msg);
// 
//     void warn(String msg);
// 
//     void fatal(String msg);
// 
//     void warn(String msg, Throwable e);
// 
//     void fatal(String msg, Throwable e);
// }


// Path: dbpatch-core/src/main/java/org/jsoftware/dbpatch/impl/SimplePatchScanner.java
import org.apache.commons.io.FilenameUtils;
import org.jsoftware.dbpatch.config.AbstractPatch;
import org.jsoftware.dbpatch.config.Patch;
import org.jsoftware.dbpatch.config.PatchScanner;
import org.jsoftware.dbpatch.log.Log;
import org.jsoftware.dbpatch.log.LogFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

package org.jsoftware.dbpatch.impl;



/**
 * Abstract directory scanner that looks for patch files.
 */
public abstract class SimplePatchScanner implements PatchScanner {
    private final Log log = LogFactory.getInstance();

    public List<Patch> scan(File baseDir, String[] paths) throws DuplicatePatchNameException, IOException {
        List<DirMask> dirMasks = parsePatchDirs(baseDir, paths);
        LinkedList<Patch> list = new LinkedList<Patch>();
        for (DirMask dm : dirMasks) {
            log.debug("Scan for patches " + dm.getDir().getAbsolutePath() + " with " + dm.getMask());
            LinkedList<Patch> dirList = new LinkedList<Patch>();
            notADirectoryCheck(dm.getDir());
            File[] fList = dm.getDir().listFiles(new WildcardMaskFileFilter(dm.getMask()));
            if (fList != null) {
                for (File f : fList) {
                    Patch p = new Patch();
                    p.setFile(f);
                    p.setName(AbstractPatch.normalizeName(f.getName()));