Index: jakarta-ant/src/main/org/apache/tools/ant/DirectoryScanner.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/DirectoryScanner.java,v
retrieving revision 1.11
diff -u -r1.11 DirectoryScanner.java
--- jakarta-ant/src/main/org/apache/tools/ant/DirectoryScanner.java	2001/03/15 08:32:12	1.11
+++ jakarta-ant/src/main/org/apache/tools/ant/DirectoryScanner.java	2001/03/24 03:39:00
@@ -57,6 +57,9 @@
 import java.io.*;
 import java.util.*;
 
+import org.apache.tools.ant.types.CullerSet;
+import org.apache.tools.ant.types.DirectoryCullerSource;
+
 /**
  * Class for scanning a directory for files/directories that match a certain
  * criteria.
@@ -132,6 +135,9 @@
  * .class files in all directories under a directory called "modules"
  *
  * @author Arnout J. Kuiper <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
+ *
+ * Added culler functionality and did minor refactoring.
+ * @author David Rees <a href="mailto:dave@ubiqsoft.com">dave@ubiqsoft.com</a>
  */
 public class DirectoryScanner implements FileScanner {
 
@@ -160,6 +166,17 @@
      * The patterns for the files that should be included.
      */
     protected String[] includes;
+    
+    /**
+    The culler set that I apply after patterns have been checked to determine if a file/dir
+    should be excluded.
+    */
+    private CullerSet cullerSet;
+
+    /**
+     * The CullerSource object that is passed to cullers. It simply wraps my basedir.
+     */
+    protected DirectoryCullerSource cullerSource;
 
     /**
      * The patterns for the files that should be excluded.
@@ -223,7 +240,7 @@
      * @param pattern the (non-null) pattern to match against
      * @param str     the (non-null) string (path) to match
      */
-    protected static boolean matchPatternStart(String pattern, String str) {
+    public static boolean matchPatternStart(String pattern, String str) {
         // When str starts with a File.separator, pattern has to start with a
         // File.separator.
         // When pattern starts with a File.separator, str has to start with a
@@ -285,7 +302,7 @@
      * @return <code>true</code> when the pattern matches against the string.
      *         <code>false</code> otherwise.
      */
-    protected static boolean matchPath(String pattern, String str) {
+    public static boolean matchPath(String pattern, String str) {
         // When str starts with a File.separator, pattern has to start with a
         // File.separator.
         // When pattern starts with a File.separator, str has to start with a
@@ -425,7 +442,7 @@
      * @return <code>true</code> when the string matches against the pattern,
      *         <code>false</code> otherwise.
      */
-    protected static boolean match(String pattern, String str) {
+    public static boolean match(String pattern, String str) {
         char[] patArr = pattern.toCharArray();
         char[] strArr = str.toCharArray();
         int patIdxStart = 0;
@@ -573,6 +590,7 @@
      */
     public void setBasedir(File basedir) {
         this.basedir = basedir;
+        cullerSource = new DirectoryCullerSource(basedir);
     }
 
 
@@ -676,18 +694,11 @@
         dirsNotIncluded  = new Vector();
         dirsExcluded     = new Vector();
 
-        if (isIncluded("")) {
-            if (!isExcluded("")) {
-                dirsIncluded.addElement("");
-            } else {
-                dirsExcluded.addElement("");
-            }
-        } else {
-            dirsNotIncluded.addElement("");
+        // If scanName returns false then there is no reason to continue scanning
+        if (scanName("", dirsNotIncluded, dirsExcluded, dirsIncluded, true)) {
+            scandir(basedir, "", true);
         }
-        scandir(basedir, "", true);
     }
-
     /**
      * Toplevel invocation for the scan.
      *
@@ -755,40 +766,16 @@
             String name = vpath+newfiles[i];
             File   file = new File(dir,newfiles[i]);
             if (file.isDirectory()) {
-                if (isIncluded(name)) {
-                    if (!isExcluded(name)) {
-                        dirsIncluded.addElement(name);
-                        if (fast) {
-                            scandir(file, name+File.separator, fast);
-                        }
-                    } else {
-                        dirsExcluded.addElement(name);
-                    }
-                } else {
-                    dirsNotIncluded.addElement(name);
-                    if (fast && couldHoldIncluded(name)) {
-                        scandir(file, name+File.separator, fast);
-                    }
-                }
-                if (!fast) {
+                boolean couldHoldIncluded = scanName(name, dirsNotIncluded, dirsExcluded, dirsIncluded, true);
+                // Scan if it couldHoldIncluded or if we are doing a slow (full) scan
+                if (couldHoldIncluded || !fast) {
                     scandir(file, name+File.separator, fast);
                 }
             } else if (file.isFile()) {
-                if (isIncluded(name)) {
-                    if (!isExcluded(name)) {
-                        filesIncluded.addElement(name);
-                    } else {
-                        filesExcluded.addElement(name);
-                    }
-                } else {
-                    filesNotIncluded.addElement(name);
-                }
+                scanName(name, filesNotIncluded, filesExcluded, filesIncluded, false);
             }
         }
     }
-
-
-
     /**
      * Tests whether a name matches against at least one include pattern.
      *
@@ -966,5 +953,41 @@
         }
         excludes = newExcludes;
     }
-
+    /**
+     * See if the passed name passes my set of cullers.
+     *
+     * @param name the name to match
+     * @return <code>true</code> when the name passes all the cullers
+     */
+    protected boolean shouldCull(String name) {
+        return cullerSet.shouldCull(cullerSource, name);
+    }
+    /**
+    Scan the file and place it correctly in the passed notIncluded, included or excluded buckets.
+    Returns true if this is a directory and could hold additional files (according to patterns);
+    */
+    protected boolean scanName(String name, Vector notIncluded, Vector excluded, Vector included, boolean isDirectory) {
+        if (isIncluded(name)) {
+                if (!isExcluded(name)) {
+                    // Culling effects if a directory is included or excluded, but not if it is scanned.
+                    if (shouldCull(name)) {
+                        included.addElement(name);
+                    } else {
+                        excluded.addElement(name);
+                    }
+                    return isDirectory;
+                } else {
+                    excluded.addElement(name);
+                }
+            } else {
+                notIncluded.addElement(name);
+                if (isDirectory && couldHoldIncluded(name)) {
+                    return true;
+                }
+            }
+        return false;
+    }
+    public void setCullerSet(CullerSet newCullerSet) {
+        cullerSet = newCullerSet;
+    }
 }
Index: jakarta-ant/src/main/org/apache/tools/ant/FileScanner.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/FileScanner.java,v
retrieving revision 1.4
diff -u -r1.4 FileScanner.java
--- jakarta-ant/src/main/org/apache/tools/ant/FileScanner.java	2001/01/03 14:18:26	1.4
+++ jakarta-ant/src/main/org/apache/tools/ant/FileScanner.java	2001/03/24 03:39:00
@@ -55,6 +55,8 @@
 
 import java.io.*;
 
+import org.apache.tools.ant.types.CullerSet;
+
 /**
  * An interface used to describe the actions required by any type of 
  * directory scanner.
@@ -152,4 +154,8 @@
      * @param includes list of include patterns
      */
     public void setIncludes(String[] includes);
+    /**
+     * Sets the set of cullers to use.
+     */
+    public void setCullerSet(CullerSet newCullers);
 }
Index: jakarta-ant/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java,v
retrieving revision 1.2
diff -u -r1.2 EnumeratedAttribute.java
--- jakarta-ant/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java	2000/11/29 16:11:33	1.2
+++ jakarta-ant/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java	2001/03/24 03:39:05
@@ -78,10 +78,15 @@
 
     public EnumeratedAttribute() {}
 
-    /**
+    public EnumeratedAttribute(String newValue) {
+        this();
+        setValue(newValue);
+    }
+
+/**
      * Invoked by {@link org.apache.tools.ant.IntrospectionHelper IntrospectionHelper}.
      */
-    public final void setValue(String value) throws BuildException {
+    public void setValue(String value) throws BuildException {
         if (!containsValue(value)) {
             throw new BuildException(value+" is not a legal value for this attribute");
         }
@@ -110,5 +115,16 @@
      */
     public final String getValue() {
         return value;
+    }
+
+    /**
+    * Compares the passed value to my value. Returns true if they are equal.
+    */
+    public boolean isValue(String aValue) {
+        return value.equals(aValue);
+    }
+
+    public String toString() {
+        return getClass().getName() + "[" +  value + "]";
     }
 }
Index: jakarta-ant/src/main/org/apache/tools/ant/types/FileSet.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/FileSet.java,v
retrieving revision 1.15
diff -u -r1.15 FileSet.java
--- jakarta-ant/src/main/org/apache/tools/ant/types/FileSet.java	2001/03/14 12:48:32	1.15
+++ jakarta-ant/src/main/org/apache/tools/ant/types/FileSet.java	2001/03/24 03:39:05
@@ -77,6 +77,7 @@
     
     private PatternSet defaultPatterns = new PatternSet();
     private Vector additionalPatterns = new Vector();
+    private CullerSet cullerSet = new CullerSet();
 
     private File dir;
     private boolean useDefaultExcludes = true;
@@ -90,8 +91,9 @@
         this.defaultPatterns = fileset.defaultPatterns;
         this.additionalPatterns = fileset.additionalPatterns;
         this.useDefaultExcludes = fileset.useDefaultExcludes;
+        this.cullerSet = fileset.cullerSet;
     }
-    
+
     
 
     /**
@@ -196,7 +198,7 @@
          defaultPatterns.setIncludesfile(incl);
      }
 
-    /**
+   /**
      * Sets the name of the file containing the includes patterns.
      *
      * @param excl The file to fetch the exclude patterns from.  
@@ -210,7 +212,7 @@
      }
 
     /**
-     * Sets whether default exclusions should be used or not.
+  * Sets whether default exclusions should be used or not.
      *
      * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions 
      *                           should be used, "false"|"off"|"no" when they
@@ -236,14 +238,7 @@
             throw new BuildException("No directory specified for fileset.");
         }
 
-        if (!dir.exists()) {
-            throw new BuildException(dir.getAbsolutePath()+" not found.");
-        }
-        if (!dir.isDirectory()) {
-            throw new BuildException(dir.getAbsolutePath()+" is not a directory.");
-        }
-
-        DirectoryScanner ds = new DirectoryScanner();
+        DirectoryScanner ds = newDirectoryScanner();
         setupDirectoryScanner(ds, p);
         ds.scan();
         return ds;
@@ -264,6 +259,8 @@
         ds.setIncludes(defaultPatterns.getIncludePatterns(p));
         ds.setExcludes(defaultPatterns.getExcludePatterns(p));
         if (useDefaultExcludes) ds.addDefaultExcludes();
+
+        ds.setCullerSet(cullerSet);
     }
 
     /**
@@ -285,5 +282,36 @@
             return (FileSet) o;
         }
     }
+    
+    /**
+    Create a new instance of directory scanner and return it. Allows subclasses to override the scanner type.
+     */
+    protected DirectoryScanner newDirectoryScanner() {
+        return new DirectoryScanner();
+    }
+
+ 
+
 
+    public void addCuller(Culler aCuller) { 
+        if (isReference()) {
+            throw noChildrenAllowed(); 
+        }
+        cullerSet.addCuller(aCuller);
+    }
+
+
+    public void addCullerSet(CullerSet aCuller) {
+        addCuller(aCuller);
+    }
+
+
+    public void addFileAttributeCuller(FileAttributeCuller aCuller) {
+        addCuller(aCuller);
+    }
+
+
+    public void addFileCompareCuller(FileCompareCuller aCuller) {
+        addCuller(aCuller);
+    }
 }
Index: src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java,v
retrieving revision 1.3
diff -u -r1.3 VAJWorkspaceScanner.java
--- src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java	2001/01/03 14:18:42	1.3
+++ src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java	2001/03/24 03:45:33
@@ -190,7 +190,7 @@
      * @return <code>true</code> when the string matches against the pattern,
      *         <code>false</code> otherwise.
      */
-    protected static boolean match(String pattern, String str) {
+    public static boolean match(String pattern, String str) {
         return DirectoryScanner.match(pattern, str);
     }
     /**
