Adds the ant-style filtering to the source and super-source elements of the module XML file.

Notes:
1) Classes on the source path include their module package path as part of their logical name; updated the includes/excludes rules for this case.
2) If no include rules are specified for source or super-source elements, the default of **/*.java will be used.

Patch by: mmendez
Review by: me


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1606 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
index 48db5a8..13940e2 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
@@ -48,12 +48,11 @@
  * XML for unit tests.
  */
 public class ModuleDef {
-
-  private static final FileFilter JAVA_ACCEPTOR = new FileFilter() {
-    public boolean accept(String name) {
-      return name.endsWith(".java");
-    }
-  };
+  /**
+   * Default to recursive inclusion of java files if no explicit include
+   * directives are specified.
+   */
+  private static final String[] DEFAULT_SOURCE_FILE_INCLUDES_LIST = new String[] {"**/*.java"};
 
   private static final Comparator<Map.Entry<String, ?>> REV_NAME_CMP = new Comparator<Map.Entry<String, ?>>() {
     public int compare(Map.Entry<String, ?> entry1, Map.Entry<String, ?> entry2) {
@@ -132,23 +131,8 @@
       throw new IllegalStateException("Already normalized");
     }
 
-    /*
-     * Hijack Ant's ZipScanner to handle inclusions/exclusions exactly as Ant
-     * does. We're only using its pattern-matching capabilities; the code path
-     * I'm using never tries to hit the filesystem in Ant 1.6.5.
-     */
-    final ZipScanner scanner = new ZipScanner();
-    if (includeList.length > 0) {
-      scanner.setIncludes(includeList);
-    }
-    if (excludeList.length > 0) {
-      scanner.setExcludes(excludeList);
-    }
-    if (defaultExcludes) {
-      scanner.addDefaultExcludes();
-    }
-    scanner.setCaseSensitive(caseSensitive);
-    scanner.init();
+    final ZipScanner scanner = getScanner(includeList, excludeList,
+        defaultExcludes, caseSensitive);
 
     // index from this package down
     publicPathEntries.addRootPackage(publicPackage, new FileFilter() {
@@ -158,22 +142,47 @@
     });
   }
 
-  public synchronized void addSourcePackage(String sourcePackage) {
-    if (lazySourceOracle != null) {
-      throw new IllegalStateException("Already normalized");
-    }
-
-    // index from from the base package
-    sourcePathEntries.addPackage(sourcePackage, JAVA_ACCEPTOR);
+  public void addSourcePackage(String sourcePackage, String[] includeList,
+      String[] excludeList, boolean defaultExcludes, boolean caseSensitive) {
+    addSourcePackageImpl(sourcePackage, includeList, excludeList,
+        defaultExcludes, caseSensitive, false);
   }
 
-  public synchronized void addSuperSourcePackage(String superSourcePackage) {
+  public void addSourcePackageImpl(String sourcePackage, String[] includeList,
+      String[] excludeList, boolean defaultExcludes, boolean caseSensitive,
+      boolean isSuperSource) {
     if (lazySourceOracle != null) {
       throw new IllegalStateException("Already normalized");
     }
 
-    // index from this package down
-    sourcePathEntries.addRootPackage(superSourcePackage, JAVA_ACCEPTOR);
+    if (includeList.length == 0) {
+      /*
+       * If no includes list was provided then, use the default.
+       */
+      includeList = DEFAULT_SOURCE_FILE_INCLUDES_LIST;
+    }
+
+    final ZipScanner scanner = getScanner(includeList, excludeList,
+        defaultExcludes, caseSensitive);
+
+    final FileFilter sourceFileFilter = new FileFilter() {
+      public boolean accept(String name) {
+        return scanner.match(name);
+      }
+    };
+
+    if (isSuperSource) {
+      sourcePathEntries.addRootPackage(sourcePackage, sourceFileFilter);
+    } else {
+      sourcePathEntries.addPackage(sourcePackage, sourceFileFilter);
+    }
+  }
+
+  public void addSuperSourcePackage(String superSourcePackage,
+      String[] includeList, String[] excludeList, boolean defaultExcludes,
+      boolean caseSensitive) {
+    addSourcePackageImpl(superSourcePackage, includeList, excludeList,
+        defaultExcludes, caseSensitive, true);
   }
 
   public void clearEntryPoints() {
@@ -360,6 +369,19 @@
   }
 
   /**
+   * Returns the URL for a source file if it is found; <code>false</code>
+   * otherwise.
+   * 
+   * NOTE: this method is for testing only.
+   * 
+   * @param partialPath
+   * @return
+   */
+  synchronized URL findSourceFile(String partialPath) {
+    return lazySourceOracle.find(partialPath);
+  }
+
+  /**
    * The final method to call when everything is setup. Before calling this
    * method, several of the getter methods may not be called. After calling this
    * method, the add methods may not be called.
@@ -426,4 +448,27 @@
     lazyPublicOracle = publicPathEntries.create(branch);
   }
 
+  private ZipScanner getScanner(String[] includeList, String[] excludeList,
+      boolean defaultExcludes, boolean caseSensitive) {
+    /*
+     * Hijack Ant's ZipScanner to handle inclusions/exclusions exactly as Ant
+     * does. We're only using its pattern-matching capabilities; the code path
+     * I'm using never tries to hit the filesystem in Ant 1.6.5.
+     */
+    ZipScanner scanner = new ZipScanner();
+    if (includeList.length > 0) {
+      scanner.setIncludes(includeList);
+    }
+    if (excludeList.length > 0) {
+      scanner.setExcludes(excludeList);
+    }
+    if (defaultExcludes) {
+      scanner.addDefaultExcludes();
+    }
+    scanner.setCaseSensitive(caseSensitive);
+    scanner.init();
+
+    return scanner;
+  }
+
 }
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
index 7e9a53c..fce97d3 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
@@ -86,10 +86,26 @@
 
     protected final String __source_1_path = "";
 
+    protected final String __source_2_includes = "";
+
+    protected final String __source_3_excludes = "";
+
+    protected final String __source_4_defaultexcludes = "yes";
+
+    protected final String __source_5_casesensitive = "true";
+
     protected final String __stylesheet_1_src = null;
 
     protected final String __super_source_1_path = "";
 
+    protected final String __super_source_2_includes = "";
+
+    protected final String __super_source_3_excludes = "";
+
+    protected final String __super_source_4_defaultexcludes = "yes";
+
+    protected final String __super_source_5_casesensitive = "true";
+
     private Schema fChild;
 
     protected Schema __define_property_begin(PropertyName name,
@@ -178,18 +194,16 @@
       IncludeExcludeSchema childSchema = ((IncludeExcludeSchema) fChild);
       foundAnyPublic = true;
 
-      Set includeSet = childSchema.getIncludes();
+      Set<String> includeSet = childSchema.getIncludes();
       addDelimitedStringToSet(includes, "[ ,]", includeSet);
-      String[] includeList = (String[]) includeSet.toArray(new String[includeSet.size()]);
+      String[] includeList = includeSet.toArray(new String[includeSet.size()]);
 
-      Set excludeSet = childSchema.getExcludes();
+      Set<String> excludeSet = childSchema.getExcludes();
       addDelimitedStringToSet(excludes, "[ ,]", excludeSet);
-      String[] excludeList = (String[]) excludeSet.toArray(new String[excludeSet.size()]);
+      String[] excludeList = excludeSet.toArray(new String[excludeSet.size()]);
 
-      boolean doDefaultExcludes = "yes".equalsIgnoreCase(defaultExcludes)
-          || "true".equalsIgnoreCase(defaultExcludes);
-      boolean doCaseSensitive = "yes".equalsIgnoreCase(caseSensitive)
-          || "true".equalsIgnoreCase(caseSensitive);
+      boolean doDefaultExcludes = toPrimitiveBoolean(defaultExcludes);
+      boolean doCaseSensitive = toPrimitiveBoolean(caseSensitive);
 
       addPublicPackage(modulePackageAsPath, path, includeList, excludeList,
           doDefaultExcludes, doCaseSensitive);
@@ -258,13 +272,15 @@
      * Indicates which subdirectories contain translatable source without
      * necessarily adding a sourcepath entry.
      */
-    protected Schema __source_begin(String path) {
-      foundExplicitSourceOrSuperSource = true;
+    protected Schema __source_begin(String path, String includes,
+        String excludes, String defaultExcludes, String caseSensitive) {
+      return fChild = new IncludeExcludeSchema();
+    }
 
-      // Build a new path entry rooted at the classpath base.
-      //
-      addSourcePackage(modulePackageAsPath, path, false);
-      return null;
+    protected void __source_end(String path, String includes, String excludes,
+        String defaultExcludes, String caseSensitive) {
+      addSourcePackage(path, includes, excludes, defaultExcludes,
+          caseSensitive, false);
     }
 
     /**
@@ -280,17 +296,19 @@
      * Like adding a translatable source package, but such that it uses the
      * module's package itself as its sourcepath root entry.
      */
-    protected Schema __super_source_begin(String path) {
-      foundExplicitSourceOrSuperSource = true;
+    protected Schema __super_source_begin(String path, String includes,
+        String excludes, String defaultExcludes, String caseSensitive) {
+      return fChild = new IncludeExcludeSchema();
+    }
 
-      // Build a new path entry rooted at this module's dir.
-      //
-      addSourcePackage(modulePackageAsPath, path, true);
-      return null;
+    protected void __super_source_end(String path, String includes,
+        String excludes, String defaultExcludes, String caseSensitive) {
+      addSourcePackage(path, includes, excludes, defaultExcludes,
+          caseSensitive, true);
     }
 
     private void addDelimitedStringToSet(String delimited, String delimiter,
-        Set toSet) {
+        Set<String> toSet) {
       if (delimited.length() > 0) {
         String[] split = delimited.split(delimiter);
         for (int i = 0; i < split.length; ++i) {
@@ -325,8 +343,30 @@
           defaultExcludes, caseSensitive);
     }
 
-    private void addSourcePackage(String parentDir, String relDir,
+    private void addSourcePackage(String relDir, String includes,
+        String excludes, String defaultExcludes, String caseSensitive,
         boolean isSuperSource) {
+      IncludeExcludeSchema childSchema = ((IncludeExcludeSchema) fChild);
+      foundExplicitSourceOrSuperSource = true;
+
+      Set<String> includeSet = childSchema.getIncludes();
+      addDelimitedStringToSet(includes, "[ ,]", includeSet);
+      String[] includeList = includeSet.toArray(new String[includeSet.size()]);
+
+      Set<String> excludeSet = childSchema.getExcludes();
+      addDelimitedStringToSet(excludes, "[ ,]", excludeSet);
+      String[] excludeList = excludeSet.toArray(new String[excludeSet.size()]);
+
+      boolean doDefaultExcludes = toPrimitiveBoolean(defaultExcludes);
+      boolean doCaseSensitive = toPrimitiveBoolean(caseSensitive);
+
+      addSourcePackage(modulePackageAsPath, relDir, includeList, excludeList,
+          doDefaultExcludes, doCaseSensitive, isSuperSource);
+    }
+
+    private void addSourcePackage(String modulePackagePath, String relDir,
+        String[] includeList, String[] excludeList, boolean defaultExcludes,
+        boolean caseSensitive, boolean isSuperSource) {
       String normChildDir = normalizePathEntry(relDir);
       if (normChildDir.startsWith("/")) {
         logger.log(TreeLogger.WARN, "Non-relative source package: "
@@ -344,11 +384,26 @@
         return;
       }
 
-      String fullDir = parentDir + normChildDir;
+      String fullPackagePath = modulePackagePath + normChildDir;
+
       if (isSuperSource) {
-        moduleDef.addSuperSourcePackage(fullDir);
+        /*
+         * Super source does not include the module package path as part of the
+         * logical class names.
+         */
+        moduleDef.addSuperSourcePackage(fullPackagePath, includeList,
+            excludeList, defaultExcludes, caseSensitive);
       } else {
-        moduleDef.addSourcePackage(fullDir);
+        /*
+         * Add the full package path to the include and exclude lists since the
+         * logical name of classes on the source path includes the package path
+         * but the include and exclude lists do not.
+         */
+        addPrefix(includeList, fullPackagePath);
+        addPrefix(excludeList, fullPackagePath);
+
+        moduleDef.addSourcePackage(fullPackagePath, includeList, excludeList,
+            defaultExcludes, caseSensitive);
       }
     }
 
@@ -442,15 +497,15 @@
 
     protected final String __include_1_name = null;
 
-    private final Set excludes = new HashSet();
+    private final Set<String> excludes = new HashSet<String>();
 
-    private final Set includes = new HashSet();
+    private final Set<String> includes = new HashSet<String>();
 
-    public Set getExcludes() {
+    public Set<String> getExcludes() {
       return excludes;
     }
 
-    public Set getIncludes() {
+    public Set<String> getIncludes() {
       return includes;
     }
 
@@ -671,6 +726,20 @@
 
   private static final Map singletonsByName = new HashMap();
 
+  private static void addPrefix(String[] strings, String prefix) {
+    for (int i = 0; i < strings.length; ++i) {
+      strings[i] = prefix + strings[i];
+    }
+  }
+
+  /**
+   * Returns <code>true</code> if the string equals "true" or "yes" using a
+   * case insensitive comparison.
+   */
+  private static boolean toPrimitiveBoolean(String s) {
+    return "yes".equalsIgnoreCase(s) || "true".equalsIgnoreCase(s);
+  }
+
   private final BodySchema bodySchema;
 
   private boolean foundAnyPublic;
@@ -678,7 +747,6 @@
   private boolean foundExplicitSourceOrSuperSource;
 
   private final ObjAttrCvt genAttrCvt = new ObjAttrCvt(Generator.class);
-
   private final JsParser jsParser = new JsParser();
   private final JsProgram jsPgm = new JsProgram();
   private final ModuleDefLoader loader;
@@ -716,7 +784,8 @@
     // Maybe infer source and public.
     //
     if (!foundExplicitSourceOrSuperSource) {
-      bodySchema.addSourcePackage(modulePackageAsPath, "client", false);
+      bodySchema.addSourcePackage(modulePackageAsPath, "client", Empty.STRINGS,
+          Empty.STRINGS, true, true, false);
     }
 
     if (!foundAnyPublic) {
diff --git a/user/test/com/google/gwt/dev/cfg/PublicTagTest.java b/user/test/com/google/gwt/dev/cfg/PublicTagTest.java
index 6f0b54c..1af2ad6 100644
--- a/user/test/com/google/gwt/dev/cfg/PublicTagTest.java
+++ b/user/test/com/google/gwt/dev/cfg/PublicTagTest.java
@@ -32,7 +32,7 @@
 public class PublicTagTest extends TestCase {
 
   /**
-   * Provides a convienent interface to the {@link GWTCompiler}. This test
+   * Provides a convenient interface to the {@link GWTCompiler}. This test
    * cannot simply call {@link GWTCompiler#main(String[])} since it always
    * terminates with a call to {@link System#exit(int)}.
    */
@@ -68,14 +68,15 @@
     String moduleName = PublicTagTest.class.getName();
 
     // Find our module output directory and delete it
-    File moduleDir = new File(curDir, moduleName);
+    File moduleDir = new File(curDir, "www/" + moduleName);
     if (moduleDir.exists()) {
       Util.recursiveDelete(moduleDir, false);
     }
     assertFalse(moduleDir.exists());
 
     // Compile the dummy app; suppress output to stdout
-    Compiler.compile(new String[] {moduleName, "-logLevel", "ERROR"});
+    Compiler.compile(new String[] {
+        moduleName, "-logLevel", "ERROR", "-out", "www"});
 
     // Check the output folder
     assertTrue(new File(moduleDir, "good0.html").exists());
diff --git a/user/test/com/google/gwt/dev/cfg/SourceTagTest.gwt.xml b/user/test/com/google/gwt/dev/cfg/SourceTagTest.gwt.xml
new file mode 100644
index 0000000..74b2719
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/SourceTagTest.gwt.xml
@@ -0,0 +1,37 @@
+<!--                                                                        -->
+<!-- Copyright 2007 Google Inc.                                             -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); you    -->
+<!-- may not use this file except in compliance with the License. You may   -->
+<!-- may obtain a copy of the License at                                    -->
+<!--                                                                        -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0                             -->
+<!--                                                                        -->
+<!-- Unless required by applicable law or agreed to in writing, software    -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS,      -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        -->
+<!-- implied. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<module>
+	<inherits name="com.google.gwt.core.Core"/>
+
+	<source path="test/caseinsensitive" includes="Go*.java" casesensitive="false"/>
+
+	<source path="test/casesensitive" includes="CaseSensitive_A_*.java"/>
+
+	<source path="test/excludes" excludes="Excludes_Exclude1.java Excludes_Exclude2.java">
+		<exclude name="Excludes_Exclude3.java"/>
+	</source>
+	
+	<source path="test/includeexclude" includes="*.java" 
+		excludes="IncludeExclude_Exclude1.java IncludeExclude_Exclude2.java">
+		<exclude name="IncludeExclude_Exclude3.java"/>
+	</source>
+
+	<source path="test/includes" includes="Includes_Include1.java, Includes_Include2.java">
+		<include name="Includes_Include3.java"/>
+	</source>
+
+	<source path="test/recursive" includes="**/good/*.java"/>
+
+</module>
diff --git a/user/test/com/google/gwt/dev/cfg/SourceTagTest.java b/user/test/com/google/gwt/dev/cfg/SourceTagTest.java
new file mode 100644
index 0000000..1939a32
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/SourceTagTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+
+/**
+ * 
+ */
+public class SourceTagTest extends TestSuperAndSourceTags {
+
+  public SourceTagTest() throws UnableToCompleteException {
+    super();
+  }
+
+  public void testSourceTag() {
+    validateTags();
+  }
+
+  /**
+   * Return the logical path for a given class. For example, java.lang.Object's
+   * logical path would be java/lang/Object.
+   */
+  protected String getLogicalPath(Class<?> clazz) {
+    return clazz.getCanonicalName().replace('.', '/') + ".java";
+  }
+}
diff --git a/user/test/com/google/gwt/dev/cfg/SuperSourceTagTest.gwt.xml b/user/test/com/google/gwt/dev/cfg/SuperSourceTagTest.gwt.xml
new file mode 100644
index 0000000..e9069ec
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/SuperSourceTagTest.gwt.xml
@@ -0,0 +1,36 @@
+<!--                                                                        -->
+<!-- Copyright 2007 Google Inc.                                             -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); you    -->
+<!-- may not use this file except in compliance with the License. You may   -->
+<!-- may obtain a copy of the License at                                    -->
+<!--                                                                        -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0                             -->
+<!--                                                                        -->
+<!-- Unless required by applicable law or agreed to in writing, software    -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS,      -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        -->
+<!-- implied. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<module>
+	<inherits name="com.google.gwt.core.Core"/>
+
+	<super-source path="test/caseinsensitive" includes="Go*.java" casesensitive="false"/>
+
+	<super-source path="test/casesensitive" includes="CaseSensitive_A_*.java"/>
+
+	<super-source path="test/excludes" excludes="Excludes_Exclude1.java Excludes_Exclude2.java">
+		<exclude name="Excludes_Exclude3.java"/>
+	</super-source>
+	
+	<super-source path="test/includeexclude" includes="*.java" excludes="IncludeExclude_Exclude1.java IncludeExclude_Exclude2.java">
+		<exclude name="IncludeExclude_Exclude3.java"/>
+	</super-source>
+
+	<super-source path="test/includes" includes="Includes_Include1.java, Includes_Include2.java">
+		<include name="Includes_Include3.java"/>
+	</super-source>
+
+	<super-source path="test/recursive" includes="**/good/*.java"/>
+
+</module>
diff --git a/user/test/com/google/gwt/dev/cfg/SuperSourceTagTest.java b/user/test/com/google/gwt/dev/cfg/SuperSourceTagTest.java
new file mode 100644
index 0000000..7fdc6af
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/SuperSourceTagTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+
+/**
+ * 
+ */
+public class SuperSourceTagTest extends TestSuperAndSourceTags {
+
+  public SuperSourceTagTest() throws UnableToCompleteException {
+    super();
+  }
+  
+  public void testSuperSourceTag() {
+    validateTags();
+  }
+  
+  /**
+   * Return the logical path for a given class.  For super source, the logical
+   * path does not include the path component from the tag.
+   */
+  protected String getLogicalPath(Class<?> clazz) {
+    String name = clazz.getCanonicalName();
+    name = name.substring(getClass().getPackage().getName().length() + 1);
+    name = name.replace('.', '/') + ".java";
+    name = name.replaceFirst("test/\\w+/", "");
+    return name;
+  }
+}
diff --git a/user/test/com/google/gwt/dev/cfg/TagSuite.java b/user/test/com/google/gwt/dev/cfg/TagSuite.java
new file mode 100644
index 0000000..db56ebf
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/TagSuite.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Tests all classes in GWT JRE emulation library.
+ */
+public class TagSuite {
+
+  public static Test suite() {
+    TestSuite suite = new TestSuite(
+        "Tests for public, source, and super-source tags");
+
+    // $JUnit-BEGIN$
+    suite.addTestSuite(PublicTagTest.class);
+    suite.addTestSuite(SourceTagTest.class);
+    suite.addTestSuite(SuperSourceTagTest.class);
+    // $JUnit-END$
+
+    return suite;
+  }
+
+}
diff --git a/user/test/com/google/gwt/dev/cfg/TestSuperAndSourceTags.java b/user/test/com/google/gwt/dev/cfg/TestSuperAndSourceTags.java
new file mode 100644
index 0000000..e4c326c
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/TestSuperAndSourceTags.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.cfg.test.caseinsensitive.GOO;
+import com.google.gwt.dev.cfg.test.caseinsensitive.Good;
+import com.google.gwt.dev.cfg.test.casesensitive.CaseSensitive_A_Foo;
+import com.google.gwt.dev.cfg.test.casesensitive.CaseSensitive_a_Bar;
+import com.google.gwt.dev.cfg.test.excludes.Excludes_Exclude1;
+import com.google.gwt.dev.cfg.test.excludes.Excludes_Exclude2;
+import com.google.gwt.dev.cfg.test.excludes.Excludes_Exclude3;
+import com.google.gwt.dev.cfg.test.excludes.Excludes_Include1;
+import com.google.gwt.dev.cfg.test.excludes.Excludes_Include2;
+import com.google.gwt.dev.cfg.test.excludes.Excludes_Include3;
+import com.google.gwt.dev.cfg.test.includeexclude.IncludeExclude_Exclude1;
+import com.google.gwt.dev.cfg.test.includeexclude.IncludeExclude_Exclude2;
+import com.google.gwt.dev.cfg.test.includeexclude.IncludeExclude_Exclude3;
+import com.google.gwt.dev.cfg.test.includeexclude.IncludeExclude_Include1;
+import com.google.gwt.dev.cfg.test.includeexclude.IncludeExclude_Include2;
+import com.google.gwt.dev.cfg.test.includes.Includes_Exclude1;
+import com.google.gwt.dev.cfg.test.includes.Includes_Exclude2;
+import com.google.gwt.dev.cfg.test.includes.Includes_Exclude3;
+import com.google.gwt.dev.cfg.test.includes.Includes_Include1;
+import com.google.gwt.dev.cfg.test.includes.Includes_Include2;
+import com.google.gwt.dev.cfg.test.includes.Includes_Include3;
+import com.google.gwt.dev.cfg.test.recursive.bar.Recursive_Excluded1;
+import com.google.gwt.dev.cfg.test.recursive.good.Recursive_Include1;
+import com.google.gwt.dev.cfg.test.recursive.good.bar.Recursive_Excluded2;
+import com.google.gwt.dev.cfg.test.recursive.good.bar.good.Recursive_Include2;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import junit.framework.TestCase;
+
+import java.io.PrintWriter;
+
+/**
+ * Common test code for testing the various permutations of GWT module's
+ * &lt;source&gt; and &lt;super-source&gt; source tags, specifically their
+ * ant-like inclusion support.
+ */
+public abstract class TestSuperAndSourceTags extends TestCase {
+  private static TreeLogger getRootLogger() {
+    PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
+        System.err, true));
+    logger.setMaxDetail(TreeLogger.ERROR);
+    return logger;
+  }
+
+  private final ModuleDef moduleDef;
+
+  public TestSuperAndSourceTags() throws UnableToCompleteException {
+    // Module has the same name as this class.
+    String moduleName = getClass().getCanonicalName();
+    moduleDef = ModuleDefLoader.loadFromClassPath(getRootLogger(), moduleName);
+  }
+
+  /**
+   * Returns the logical path for a class.  This method is implemented by the 
+   * subclasses because source and super-source compute logical paths 
+   * differently.
+   */
+  protected abstract String getLogicalPath(Class<?> clazz);
+
+  /**
+   * Validate that the source or super-source tags .
+   */
+  protected void validateTags() {
+    // Test case insensitive
+    validateIncluded(Good.class);
+    validateIncluded(GOO.class);
+
+    // Test case sensitive
+    validateIncluded(CaseSensitive_A_Foo.class);
+    validateExcluded(CaseSensitive_a_Bar.class);
+
+    // Test excludes
+    validateExcluded(Excludes_Exclude1.class);
+    validateExcluded(Excludes_Exclude2.class);
+    validateExcluded(Excludes_Exclude3.class);
+    validateIncluded(Excludes_Include1.class);
+    validateIncluded(Excludes_Include2.class);
+    validateIncluded(Excludes_Include3.class);
+
+    // Test include and exclude
+    validateExcluded(IncludeExclude_Exclude1.class);
+    validateExcluded(IncludeExclude_Exclude2.class);
+    validateExcluded(IncludeExclude_Exclude3.class);
+    validateIncluded(IncludeExclude_Include1.class);
+    validateIncluded(IncludeExclude_Include2.class);
+
+    // Test includes
+    validateExcluded(Includes_Exclude1.class);
+    validateExcluded(Includes_Exclude2.class);
+    validateExcluded(Includes_Exclude3.class);
+    validateIncluded(Includes_Include1.class);
+    validateIncluded(Includes_Include2.class);
+    validateIncluded(Includes_Include3.class);
+
+    // Test recursive behavior
+    validateExcluded(Recursive_Excluded1.class);
+    validateExcluded(Recursive_Excluded2.class);
+    validateIncluded(Recursive_Include1.class);
+    validateIncluded(Recursive_Include2.class);
+  }
+
+  private void validateExcluded(Class<?> clazz) {
+    assertNull(moduleDef.findSourceFile(getLogicalPath(clazz)));
+  }
+
+  private void validateIncluded(Class<?> clazz) {
+    assertNotNull(moduleDef.findSourceFile(getLogicalPath(clazz)));
+  }
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/caseinsensitive/GOO.java b/user/test/com/google/gwt/dev/cfg/test/caseinsensitive/GOO.java
new file mode 100644
index 0000000..665098d
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/caseinsensitive/GOO.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.caseinsensitive;
+
+/**
+ *
+ */
+public class GOO {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/caseinsensitive/Good.java b/user/test/com/google/gwt/dev/cfg/test/caseinsensitive/Good.java
new file mode 100644
index 0000000..07c2eeb
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/caseinsensitive/Good.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.caseinsensitive;
+
+/**
+ *
+ */
+public class Good {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/casesensitive/CaseSensitive_A_Foo.java b/user/test/com/google/gwt/dev/cfg/test/casesensitive/CaseSensitive_A_Foo.java
new file mode 100644
index 0000000..cb4d72b
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/casesensitive/CaseSensitive_A_Foo.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.casesensitive;
+
+/**
+ * Should be included by a case sensitive filter.
+ */
+public class CaseSensitive_A_Foo {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/casesensitive/CaseSensitive_a_Bar.java b/user/test/com/google/gwt/dev/cfg/test/casesensitive/CaseSensitive_a_Bar.java
new file mode 100644
index 0000000..fff9472
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/casesensitive/CaseSensitive_a_Bar.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.casesensitive;
+
+/**
+ * Should not be included by the case sensitive filter.
+ */
+public class CaseSensitive_a_Bar {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude1.java b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude1.java
new file mode 100644
index 0000000..368ba13
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.excludes;
+
+/**
+ *
+ */
+public class Excludes_Exclude1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude2.java b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude2.java
new file mode 100644
index 0000000..4a6559e
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.excludes;
+
+/**
+ *
+ */
+public class Excludes_Exclude2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude3.java b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude3.java
new file mode 100644
index 0000000..b8696db
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Exclude3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.excludes;
+
+/**
+ *
+ */
+public class Excludes_Exclude3 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include1.java b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include1.java
new file mode 100644
index 0000000..ae21680
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.excludes;
+
+/**
+ *
+ */
+public class Excludes_Include1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include2.java b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include2.java
new file mode 100644
index 0000000..662077b
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.excludes;
+
+/**
+ *
+ */
+public class Excludes_Include2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include3.java b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include3.java
new file mode 100644
index 0000000..2c9277b
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/excludes/Excludes_Include3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.excludes;
+
+/**
+ *
+ */
+public class Excludes_Include3 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude1.java b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude1.java
new file mode 100644
index 0000000..47373e4
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includeexclude;
+
+/**
+ * Should be excluded by the include, exclude rule.
+ */
+public class IncludeExclude_Exclude1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude2.java b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude2.java
new file mode 100644
index 0000000..b2bf2d3
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includeexclude;
+
+/**
+ * Should be excluded by the include, exclude rule.
+ */
+public class IncludeExclude_Exclude2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude3.java b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude3.java
new file mode 100644
index 0000000..754e01f
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Exclude3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includeexclude;
+
+/**
+ * Should be excluded by the include, exclude rule.
+ */
+public class IncludeExclude_Exclude3 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Include1.java b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Include1.java
new file mode 100644
index 0000000..36031e3
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Include1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includeexclude;
+
+/**
+ * Should be included by the include, exclude rule.
+ */
+public class IncludeExclude_Include1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Include2.java b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Include2.java
new file mode 100644
index 0000000..1fba700
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includeexclude/IncludeExclude_Include2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includeexclude;
+
+/**
+ * Should be included by the include, exclude rule.
+ */
+public class IncludeExclude_Include2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude1.java b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude1.java
new file mode 100644
index 0000000..3214d92
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includes;
+
+/**
+ * Should be excluded by the includes rule.
+ */
+public class Includes_Exclude1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude2.java b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude2.java
new file mode 100644
index 0000000..e1ee3f1f
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includes;
+
+/**
+ * Should be excluded by the includes rule.
+ */
+public class Includes_Exclude2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude3.java b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude3.java
new file mode 100644
index 0000000..ce1b11a
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Exclude3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includes;
+
+/**
+ * Should be excluded by the includes rule.
+ */
+public class Includes_Exclude3 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include1.java b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include1.java
new file mode 100644
index 0000000..369cfb0
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includes;
+
+/**
+ * Should be included by the includes rule.
+ */
+public class Includes_Include1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include2.java b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include2.java
new file mode 100644
index 0000000..53c502c
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includes;
+
+/**
+ * Should be included by the includes rule.
+ */
+public class Includes_Include2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include3.java b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include3.java
new file mode 100644
index 0000000..d1fd1a8
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/includes/Includes_Include3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.includes;
+
+/**
+ * Should be included by the includes rule.
+ */
+public class Includes_Include3 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/recursive/bar/Recursive_Excluded1.java b/user/test/com/google/gwt/dev/cfg/test/recursive/bar/Recursive_Excluded1.java
new file mode 100644
index 0000000..5062299
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/recursive/bar/Recursive_Excluded1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.recursive.bar;
+
+/**
+ * Should be excluded by the recursive rule.
+ */
+public class Recursive_Excluded1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/recursive/good/Recursive_Include1.java b/user/test/com/google/gwt/dev/cfg/test/recursive/good/Recursive_Include1.java
new file mode 100644
index 0000000..a9a0831
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/recursive/good/Recursive_Include1.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.recursive.good;
+
+/**
+ * Should be included by the recursive include rule.
+ */
+public class Recursive_Include1 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/recursive/good/bar/Recursive_Excluded2.java b/user/test/com/google/gwt/dev/cfg/test/recursive/good/bar/Recursive_Excluded2.java
new file mode 100644
index 0000000..ecb1fe9
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/recursive/good/bar/Recursive_Excluded2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.recursive.good.bar;
+
+/**
+ * Should be excluded by the recursive include rule.
+ */
+public class Recursive_Excluded2 {
+}
diff --git a/user/test/com/google/gwt/dev/cfg/test/recursive/good/bar/good/Recursive_Include2.java b/user/test/com/google/gwt/dev/cfg/test/recursive/good/bar/good/Recursive_Include2.java
new file mode 100644
index 0000000..c701673
--- /dev/null
+++ b/user/test/com/google/gwt/dev/cfg/test/recursive/good/bar/good/Recursive_Include2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.cfg.test.recursive.good.bar.good;
+
+/**
+ * Should be included by the recursive include rule.
+ */
+public class Recursive_Include2 {
+}