diff --git a/build.xml b/build.xml
index 308221f..9452540 100644
--- a/build.xml
+++ b/build.xml
@@ -299,7 +299,7 @@ $Date$
     <target name="-testInit" depends="-initHeadless">
         <property name="headlessArg" value=""/>
         <property name="junitJvmArgs"
-                  value="-Xms${groovyJUnit_ms} -XX:PermSize=${groovyJUnit_permSize} -XX:MaxPermSize=${groovyJUnit_maxPermSize} ${headlessArg} -Dgroovy.testdb.props=${groovy.testdb.props}"/>
+                  value="-Xms${groovyJUnit_ms} -XX:PermSize=${groovyJUnit_permSize} -XX:MaxPermSize=${groovyJUnit_maxPermSize} ${headlessArg} -Dgroovy.testdb.props=${groovy.testdb.props} -DjavadocAssertion.src.dir=./src/main"/>
     </target>
 
     <target name="-initHeadless" if="_shouldBeHeadless_">
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 430f1aa..5a22906 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -883,10 +883,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * 'Case' implementation for collections which tests if the 'switch'
      * operand is contained in any of the 'case' values.
      * For example:
-     * <pre>switch( item ) {
-     *   case firstList :
-     *     // item is contained in this list
-     *     // etc
+     * <pre class="groovyTestCase">switch( 3 ) {
+     *   case [1,3,5]:
+     *     assert true
+     *     break
+     *   default:
+     *     assert false
      * }</pre>
      *
      * @param caseValue   the case value
@@ -960,6 +962,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Modifies this collection to remove all duplicated items, using the
      * default comparator.
+     * <pre class="groovyTestCase">assert [1,3] == [1,3,3].unique()</pre>
      *
      * @param self a collection
      * @return the now modified collection
@@ -1033,6 +1036,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * If the closure takes two parameters, two items from the collection
      * will be passed as arguments, and the closure should return an
      * int value (with 0 indicating the items are not unique).
+     * <pre class="groovyTestCase">assert [1,4] == [1,3,4,5].unique { it % 2 }</pre>
+     * <pre class="groovyTestCase">assert [2,3,4] == [2,3,3,4].unique { a, b -> a <=> b }</pre>
      *
      * @param self    a Collection
      * @param closure a 1 or 2 arg Closure used to determine unique items
@@ -1071,14 +1076,14 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * by the given Collection's iterator is retained, but all other ones are removed.
      * The given Collection's original order is preserved.
      * <p/>
-     * <code><pre>
+     * <code><pre class="groovyTestCase">
      *     class Person {
      *         def fname, lname
      *         public String toString() {
      *             return fname + " " + lname
      *         }
      *     }
-     * <p/>
+     * 
      *     class PersonComparator implements Comparator {
      *         public int compare(Object o1, Object o2) {
      *             Person p1 = (Person) o1
@@ -1088,21 +1093,20 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *             else
      *                 return p1.fname.compareTo(p2.fname)
      *         }
-     * <p/>
+     * 
      *         public boolean equals(Object obj) {
      *             return this.equals(obj)
      *         }
      *     }
-     * <p/>
+     * 
      *     Person a = new Person(fname:"John", lname:"Taylor")
      *     Person b = new Person(fname:"Clark", lname:"Taylor")
      *     Person c = new Person(fname:"Tom", lname:"Cruz")
      *     Person d = new Person(fname:"Clark", lname:"Taylor")
-     * <p/>
+     * 
      *     def list = [a, b, c, d]
      *     List list2 = list.unique(new PersonComparator())
      *     assert( list2 == list && list == [a, b, c] )
-     * <p/>
      * </pre></code>
      *
      * @param self       a Collection
@@ -1419,6 +1423,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Counts the number of occurrences of the given value inside this collection.
      * Comparison is done using Groovy's == operator (using
      * <code>compareTo(value) == 0</code> or <code>equals(value)</code> ).
+     * <pre class="groovyTestCase">assert [2,4,2,1,3,5,2,4,3].count(4) == 2</pre>
      *
      * @param self  the collection within which we count the number of occurrences
      * @param value the value being searched for
@@ -1557,6 +1562,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Convert a collection to a List.
+     * <pre class="groovyTestCase">def x = [1,2,3] as HashSet
+     * assert x.class == HashSet
+     * assert x.toList() instanceof List</pre>
      *
      * @param self a collection
      * @return a List
@@ -1636,6 +1644,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Iterates through this collection transforming each entry into a new value using the closure
      * as a transformer, returning a list of transformed values.
+     * <pre class="groovyTestCase">assert [2,4,6] == [1,2,3].collect { it * 2 }</pre>
      *
      * @param self    a collection
      * @param closure the closure used for mapping
@@ -1649,6 +1658,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Iterates through this collection transforming each value into a new value using the closure
      * as a transformer, returning an initial collection plus the transformed values.
+     * <pre class="groovyTestCase">assert [1,2,3] as HashSet == [2,4,5,6].collect(new HashSet()) { (int)(it / 2) }</pre>
      *
      * @param self       a collection
      * @param collection an initial Collection to which the transformed values are added
@@ -1670,6 +1680,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Recursively iterates through this collection transforming each non-Collection value
      * into a new value using the closure as a transformer. Returns a potentially nested
      * list of transformed values.
+     * <pre class="groovyTestCase">assert [2,[4,6],[8],[]] == [1,[2,3],[4],[]].collectAll { it * 2 }</pre>
      *
      * @param self       a collection
      * @param closure    the closure used to transform each element of the collection
@@ -1684,6 +1695,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Recursively iterates through this collection transforming each non-Collection value
      * into a new value using the closure as a transformer. Returns a potentially nested
      * collection of transformed values.
+     * <pre class="groovyTestCase">def x = [1,[2,3],[4],[]].collectAll(new Vector()) { it * 2 }
+     * assert x == [2,[4,6],[8],[]]
+     * assert x instanceof Vector</pre>
      *
      * @param self       a collection
      * @param collection an initial Collection to which the transformed values are added
@@ -1763,8 +1777,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Finds the first value matching the closure condition.  Example:
-     * <pre>def list = [1,2,3]
-     * list.find { it > 1 } // returns 2
+     * <pre class="groovyTestCase">def list = [1,2,3]
+     * assert 2 == list.find { it > 1 }
      * </pre>
      *
      * @param self    a Collection
@@ -1802,6 +1816,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Finds all values matching the closure condition.
+     * <pre class="groovyTestCase">assert [2,4] == [1,2,3,4].findAll { it % 2 == 0 }</pre>
      *
      * @param self    a Collection
      * @param closure a closure condition
@@ -1858,6 +1873,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Splits all items into two collections based on the closure condition.
      * The first list contains all items which match the closure expression.
      * The second list all those that don't.
+     * <pre class="groovyTestCase">assert [[2,4],[1,3]] == [1,2,3,4].split { it % 2 == 0 }</pre>
      *
      * @param self    a Collection of values
      * @param closure a closure condition
@@ -1888,6 +1904,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Adds GroovyCollections#combinations(Collection) as a method on collections.
+     * <pre class="groovyTestCase">assert [['a', 'b'],[1, 2, 3]].combinations() == [['a', 1], ['b', 1], ['a', 2], ['b', 2], ['a', 3], ['b', 3]]</pre>
      *
      * @param self a Collection of lists
      * @return a List of the combinations found
@@ -1931,13 +1948,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Iterates over all permutations of a collection, running a closure for each iteration.
-     * E.g. <code>[1, 2, 3].eachPermutation{ println it }</code> would print:
-     * [1, 2, 3]
-     * [1, 3, 2]
-     * [2, 1, 3]
-     * [2, 3, 1]
-     * [3, 1, 2]
-     * [3, 2, 1]
+     * <pre class="groovyTestCase">def permutations = []
+     * [1, 2, 3].eachPermutation{ permutations << it }
+     * assert permutations == [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]</pre>
      *
      * @param self the Collection of items
      * @param closure the closure to call for each permutation
@@ -1995,6 +2008,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * item should be grouped by.  The returned LinkedHashMap will have an entry for each
      * distinct key returned from the closure, with each value being a list of
      * items for that group.
+     * <pre class="groovyTestCase">assert [0:[2,4,6], 1:[1,3,5]] == [1,2,3,4,5,6].groupBy { it % 2 }</pre>
      *
      * @param self    a collection to group (no map)
      * @param closure a closure mapping entries on keys
@@ -2114,6 +2128,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Iterates through the given collection, passing in the initial value to
      * the closure along with the current iterated item then passing into the
      * next iteration the value of the previous closure.
+     * <pre class="groovyTestCase">assert 1*1*2*3*4 == [1,2,3,4].inject(1) { acc, val -> acc * val }</pre>
      *
      * @param self    a Collection
      * @param value   a value
@@ -2188,6 +2203,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Sums the items in a collection.  This is equivalent to invoking the
      * "plus" method on all items in the collection.
+     * <pre class="groovyTestCase">assert 1+2+3+4 == [1,2,3,4].sum()</pre>
      *
      * @param self Collection of values to add together
      * @return The sum of all of the items
@@ -2225,6 +2241,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Sums the items in a collection, adding the result to some initial value.
+     * <pre class="groovyTestCase">assert 5+1+2+3+4 == [1,2,3,4].sum(5)</pre>
      *
      * @param self         a collection of values to sum
      * @param initialValue the items in the collection will be summed to this initial value
@@ -2281,6 +2298,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Sums the result of apply a closure to each item of a collection.
      * <code>coll.sum(closure)</code> is equivalent to:
      * <code>coll.collect(closure).sum()</code>.
+     * <pre class="groovyTestCase">assert 4+6+10+12 == [2,3,5,6].sum() { it * 2 }</pre>
      *
      * @param self    a Collection
      * @param closure a single parameter closure that returns a numeric value.
@@ -2327,6 +2345,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Sums the result of applying a closure to each item of a collection to some initial value.
      * <code>coll.sum(initVal, closure)</code> is equivalent to:
      * <code>coll.collect(closure).sum(initVal)</code>.
+     * <pre class="groovyTestCase">assert 50+4+6+10+12 == [2,3,5,6].sum(50) { it * 2 }</pre>
      *
      * @param self         a Collection
      * @param closure      a single parameter closure that returns a numeric value.
@@ -2409,6 +2428,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Concatenates the <code>toString()</code> representation of each
      * item in this collection, with the given String as a separator between
      * each item.
+     * <pre class="groovyTestCase">assert "1, 2, 3" == [1,2,3].join(", ")</pre>
      *
      * @param self      a Collection of objects
      * @param separator a String separator
@@ -2462,6 +2482,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Adds min() method to Collection objects.
+     * <pre class="groovyTestCase">assert 2 == [4,2,5].min()</pre>
      *
      * @param self a Collection
      * @return the minimum value
@@ -2499,6 +2520,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Selects the minimum value found in the collection using the given comparator.
+     * <pre class="groovyTestCase">assert "hi" == ["hello","hi","hey"].min( { a, b -> a.length() <=> b.length() } as Comparator )</pre>
      *
      * @param self       a Collection
      * @param comparator a Comparator
@@ -2553,6 +2575,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * the Closure is assumed to take a single parameter and return a
      * Comparable (typically an Integer) which is then used for
      * further comparison.
+     * <pre class="groovyTestCase">assert "hi" == ["hello","hi","hey"].min { it.length() } </pre>
      *
      * @param self    a Collection
      * @param closure a 1 or 2 arg Closure used to determine the correct ordering
@@ -2626,6 +2649,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Adds max() method to Collection objects.
+     * <pre class="groovyTestCase">assert 5 == [2,3,1,5,4].max()</pre>
      *
      * @param self a Collection
      * @return the maximum value
@@ -2673,6 +2697,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * the Closure is assumed to take a single parameter and return a
      * Comparable (typically an Integer) which is then used for
      * further comparison.
+     * <pre class="groovyTestCase">assert "hello" == ["hello","hi","hey"].max { it.length() }</pre>
+     * <pre class="groovyTestCase">assert "hello" == ["hello","hi","hey"].max { a, b -> a.length() <=> b.length() }</pre>
      *
      * @param self    a Collection
      * @param closure a 1 or 2 arg Closure used to determine the correct ordering
@@ -2745,6 +2771,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Selects the maximum value found in the collection using the given comparator.
+     * <pre class="groovyTestCase">assert "hello" == ["hello","hi","hey"].max( { a, b -> a.length() <=> b.length() } as Comparator )</pre>
      *
      * @param self       a Collection
      * @param comparator a Comparator
@@ -4221,6 +4248,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Support the subscript operator for List
+     * <pre class="groovyTestCase">assert [String, Long, Integer] == ["a",5L,2]["class"]</pre>
      *
      * @param coll     a Collection
      * @param property a String
@@ -4306,6 +4334,15 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * A convenience method for creating an immutable Collection.
+     * <pre class="groovyTestCase">def mutable = [1,2,3]
+     * def immutable = mutable.asImmutable()
+     * mutable << 4
+     * try {
+     *   immutable << 4
+     *   assert false
+     * } catch (UnsupportedOperationException) {
+     *   assert true
+     * }</pre>
      *
      * @param self a Collection
      * @return an immutable Collection
@@ -4443,6 +4480,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Sorts the given collection into a sorted list.  The collection items are
      * assumed to be comparable.
+     * <pre class="groovyTestCase">assert [1,2,3] == [3,1,2].sort()</pre>
      *
      * @param self the collection to be sorted
      * @return the sorted collection as a List
@@ -4516,6 +4554,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Sorts the Collection using the given comparator.  The elements are
      * sorted into a new list, and the existing collection is unchanged.
+     * <pre class="groovyTestCase">assert ["hi","hey","hello"] == ["hello","hi","hey"].sort( { a, b -> a.length() <=> b.length() } as Comparator )</pre>
      *
      * @param self       a collection to be sorted
      * @param comparator a Comparator used for the comparison
@@ -4599,6 +4638,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * the Closure is assumed to take a single parameter and return a
      * Comparable (typically an Integer) which is then used for
      * further comparison.
+     * <pre class="groovyTestCase">assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { it.length() }</pre>
+     * <pre class="groovyTestCase">assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { a, b -> a.length() <=> b.length() }</pre>
      *
      * @param self    a Collection to be sorted
      * @param closure a 1 or 2 arg Closure used to determine the correct ordering
@@ -4754,6 +4795,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Converts this collection to a List.
+     * <pre class="groovyTestCase">assert new HashSet().asList() instanceof List</pre>
      *
      * @param self a collection to be converted into a List
      * @return a newly created List if this collection is not already a List
@@ -4805,6 +4847,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Coerce a collection instance to a boolean value.
      * A collection is coerced to false if it's empty, and to true otherwise.
+     * <pre class="groovyTestCase">assert [1,2].asBoolean() == true</pre>
+     * <pre class="groovyTestCase">assert [].asBoolean() == false</pre>
      *
      * @param collection the collection
      * @return the boolean value
@@ -5087,6 +5131,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * is a Set, then the returned collection will be a Set otherwise a List.
      * This operation will always create a new object for the result,
      * while the operands remain unchanged.
+     * <pre class="groovyTestCase">assert [1,2,3,4] == [1,2] + [3,4]</pre>
      *
      * @param left  the left Collection
      * @param right the right Collection
@@ -5104,6 +5149,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * is a Set, then the returned collection will be a Set otherwise a List.
      * This operation will always create a new object for the result,
      * while the operands remain unchanged.
+     * <pre class="groovyTestCase">assert [1,2,3] == [1,2] + 3</pre>
      *
      * @param left  a Collection
      * @param right an object to add/append
@@ -5120,6 +5166,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Create a List composed of the elements of this list, repeated
      * a certain number of times.  Note that for non-primitive
      * elements, multiple references to the same instance will be added.
+     * <pre class="groovyTestCase">assert [1,2,3,1,2,3] == [1,2,3] * 2</pre>
      *
      * @param self   a Collection
      * @param factor the number of times to append
@@ -5138,6 +5185,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Create a Collection composed of the intersection of both collections.  Any
      * elements that exist in both collections are added to the resultant collection.
+     * <pre class="groovyTestCase">assert [4,5] == [1,2,3,4,5].intersect([4,5,6,7,8])</pre>
      *
      * @param left  a Collection
      * @param right a Collection
@@ -5171,6 +5219,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Returns <code>true</code> if the intersection of two collections is empty.
+     * <pre class="groovyTestCase">assert [1,2,3].disjoint([3,4,5]) == false</pre>
+     * <pre class="groovyTestCase">assert [1,2].disjoint([3,4]) == true</pre>
      *
      * @param left  a Collection
      * @param right a Collection
@@ -5565,6 +5615,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Flatten a collection.  This collection and any nested arrays or
      * collections have their contents (recursively) added to the new collection.
+     * <pre class="groovyTestCase">assert [1,2,3,4,5] == [1,[2,3],[[4]],[],5].flatten()</pre>
      *
      * @param self a Collection to flatten
      * @return a flattened Collection
@@ -5740,6 +5791,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Overloads the left shift operator to provide an easy way to append
      * objects to a Collection.
+     * <pre class="groovyTestCase">def list = [1,2]
+     * list << 3
+     * assert list == [1,2,3]</pre>
      *
      * @param self  a Collection
      * @param value an Object to be added to the collection.
diff --git a/src/test/UberTestCaseGroovySourceSubPackages.java b/src/test/UberTestCaseGroovySourceSubPackages.java
index 2d410ce..c007867 100644
--- a/src/test/UberTestCaseGroovySourceSubPackages.java
+++ b/src/test/UberTestCaseGroovySourceSubPackages.java
@@ -15,6 +15,7 @@
  */
 
 import groovy.util.AllTestSuite;
+import groovy.util.JavadocAssertionTestSuite;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -28,12 +29,14 @@ import junit.framework.TestSuite;
  */
 public class UberTestCaseGroovySourceSubPackages extends TestCase {
     private static final String EXCLUDES = "groovy/*/**/vm6/*Test.groovy";
-    private static final String BASE = "src/test";
+    private static final String CODE_BASE = "src/main";
+    private static final String TEST_BASE = "src/test";
     public static Test suite() {
         TestSuite suite = new TestSuite();
         String excludes = "true".equals(System.getProperty("java.awt.headless"))
                 ? EXCLUDES + ",groovy/*/**/SwingBuilderTest.groovy" : EXCLUDES;
-        suite.addTest(AllTestSuite.suite(BASE, "groovy/*/**/*Test.groovy", excludes));
+        suite.addTest(AllTestSuite.suite(TEST_BASE, "groovy/*/**/*Test.groovy", excludes));
+		suite.addTest(JavadocAssertionTestSuite.suite(CODE_BASE));
         return suite;
     }
 }
diff --git a/src/test/groovy/util/JavadocAssertionTestBuilder.groovy b/src/test/groovy/util/JavadocAssertionTestBuilder.groovy
new file mode 100644
index 0000000..baa2941
--- /dev/null
+++ b/src/test/groovy/util/JavadocAssertionTestBuilder.groovy
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2003-2007 the original author or authors.
+ *
+ * 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 groovy.util
+
+import java.util.regex.Pattern
+
+/**
+ * <code>JavadocAssertionTestBuilder</code> will dynamically create a test cases from Groovy assertions placed within
+ * the Javadoc comments of a source file. Assertions should be placed within an html tag with a <code>class="groovyTestCase"</code>
+ * attribute assignment. Example:
+ * <pre>&lt;pre class="groovyTestCase"&gt; assert "example".size() == 6 &lt;/pre&gt;</pre>
+ *
+ * @author Merlyn Albery-Speyer
+ */
+
+class JavadocAssertionTestBuilder {
+    private static Pattern javadocPattern =
+        Pattern.compile( /(?ims)\/\*\*.*?\*\// )
+    private static Pattern assertionPattern =
+        Pattern.compile( /(?ims)<([a-z]+)\s+class\s*=\s*['"]groovyTestCase['"]\s*>.*?<\s*\/\s*\1>/ )
+
+    Class buildTest(String filename, String code) {
+        Class test = null
+        
+        List assertionTags = getAssertionTags(code);
+        if (assertionTags) {
+            String testName = getTestName(filename)
+
+            Map lineNumberToAssertions = getLineNumberToAssertionsMap(code, assertionTags)                            
+            List testMethods = getTestMethods(lineNumberToAssertions)
+            String testCode = getTestCode(testName, testMethods)
+
+            test = createClass(testCode)
+        }
+
+        return test
+    }
+    
+    private List getAssertionTags(String code) {
+        List assertions = new ArrayList()
+
+        code.eachMatch(javadocPattern) { javadoc ->
+            assertions.addAll(javadoc.findAll(assertionPattern))
+        }
+        
+        return assertions
+    }
+    
+    private String getTestName(String filename) {
+        String filenameWithoutPath = new File(filename).name
+        String testName = filenameWithoutPath.substring(0, filenameWithoutPath.lastIndexOf(".")) +
+            "JavadocAssertionTest"
+        
+        return testName
+    }
+    
+    private Map getLineNumberToAssertionsMap(String code, List assertionTags) {
+        Map lineNumberToAssertions = [:] as LinkedHashMap
+
+        int codeIndex = 0
+        assertionTags.each { tag ->
+            codeIndex = code.indexOf(tag, codeIndex)
+            int lineNumber = code.substring(0, codeIndex).findAll("(?m)^").size()
+            codeIndex += tag.size()
+            
+            String assertion = getAssertion(tag)
+            
+            lineNumberToAssertions.get(lineNumber, []) << assertion
+        }
+
+        return lineNumberToAssertions
+    }
+    
+    private String getAssertion(String tag) {
+        String tagInner = tag.substring(tag.indexOf(">")+1, tag.lastIndexOf("<"))
+        String htmlAssertion = tagInner.replaceAll("(?m)^\\s*\\*", "")
+        String assertion = htmlAssertion
+        // TODO improve on this
+        [nbsp:' ', gt:'>', lt:'<', quot:'"', apos:"'", at:'@', ndash:'-', amp:'&'].each { key, value ->
+            assertion = assertion.replaceAll("(?i)&$key;", value)
+        }
+        
+        return assertion
+    }
+    
+    private List getTestMethods(Map lineNumberToAssertions) {
+        List testMethods = lineNumberToAssertions.collect { lineNumber, assertions ->
+            Character differentiator = 'a'
+            assertions.collect { assertion ->
+                String suffix = (assertions.size() > 1 ? "$lineNumber$differentiator" : lineNumber)
+                differentiator++
+                getTestMethodCodeForAssertion(suffix, assertion)
+            }
+        }.flatten()
+
+        return testMethods
+    }
+    
+    private String getTestMethodCodeForAssertion(String suffix, String assertion) {
+        return """
+            public void testAssertionFromLineNumber$suffix() {
+                byte[] bytes = [ ${(assertion.getBytes("UTF-8") as List).join(", ")} ] as byte[]
+                Eval.me(new String(bytes, "UTF-8"))
+            }
+        """
+    }
+    
+    private String getTestCode(String testName, List testMethods) {
+        return """
+            class $testName extends junit.framework.TestCase {
+                """+testMethods.join("\r\n")+"""
+            }
+        """
+    }
+
+    private Class createClass(String testCode) {
+        return new GroovyClassLoader().parseClass(testCode)
+    }    
+}
\ No newline at end of file
diff --git a/src/test/groovy/util/JavadocAssertionTestBuilderTest.groovy b/src/test/groovy/util/JavadocAssertionTestBuilderTest.groovy
new file mode 100644
index 0000000..57a87c8
--- /dev/null
+++ b/src/test/groovy/util/JavadocAssertionTestBuilderTest.groovy
@@ -0,0 +1,117 @@
+package groovy.util
+
+import junit.framework.TestCase
+import org.codehaus.groovy.control.MultipleCompilationErrorsException
+
+/**
+ * @author Merlyn Albery-Speyer
+ */
+class JavadocAssertionTestBuilderTest extends GroovyTestCase {
+    def builder
+    
+    void setUp() {
+        builder = new JavadocAssertionTestBuilder()
+    }
+    
+    void testBuildsTest() {
+        Class test = builder.buildTest("SomeClass.java", '/** <pre class="groovyTestCase"> assert true </pre> */ public class SomeClass { }')
+        assert test.newInstance() instanceof TestCase
+        assert test.simpleName == "SomeClassJavadocAssertionTest"
+        test.newInstance().testAssertionFromLineNumber1()
+    }
+    
+    void testAssertionsAreCalled() {
+        Class test = builder.buildTest("SomeClass.java", '/** <pre class="groovyTestCase"> assert false </pre> */ public class SomeClass { }')
+        shouldFail(AssertionError) {
+            test.newInstance().testAssertionFromLineNumber1()
+        }
+    }
+    
+    void testLineNumbering() {
+        Class test = builder.buildTest("SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert true </pre>
+             * Nothing on line 3
+             * Two on this line <pre class="groovyTestCase"> assert true </pre> <pre class="groovyTestCase"> assert true </pre>
+             */
+            public class SomeClass { }
+        ''')
+        assert test.methods.findAll { it.name =~ /test.*/ }.size() == 3
+        test.newInstance().testAssertionFromLineNumber2()
+        test.newInstance().testAssertionFromLineNumber4a()
+        test.newInstance().testAssertionFromLineNumber4b()
+    }
+    
+    void testNoTestBuiltWhenThereAreNoAssertions() {
+        Class test = builder.buildTest("SomeClass.java", "/** .. */ public class SomeClass { }")
+        assert test == null
+    }
+    
+    void testAssertionsMaySpanMultipleLines() {
+        Class test = builder.buildTest("SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert(
+             * true)
+             * assert true </pre>
+             */
+            public class SomeClass { }
+        ''')
+        test.newInstance().testAssertionFromLineNumber2()
+    }
+    
+    void testTagMustBeInsideJavadoc() {
+        Class test = builder.buildTest("SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert true </pre>
+             */
+            public class SomeClass {
+                 public static void main(String[] args) {
+                    // <pre class="groovyTestCase"> assert false </pre>        
+                 }
+            }
+        ''')
+        assert test.methods.findAll { it.name =~ /test.*/ }.size() == 1
+        test.newInstance().testAssertionFromLineNumber2()
+    }
+    
+    void testClassNamesMayBeReusedAcrossPackages() {
+        Class package1Test = builder.buildTest("./test/com/someplace/package1/SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert true </pre>
+             */
+            public class SomeClass { }
+        ''')
+        Class package2Test = builder.buildTest("./test/com/someplace/package2/SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert true </pre>
+             */
+            public class SomeClass { }
+        ''')
+        assert package1Test.simpleName == "SomeClassJavadocAssertionTest"
+        assert package2Test.simpleName == "SomeClassJavadocAssertionTest"
+        assert package1Test != package2Test    
+    }
+
+    void testClassNeedNotBeAPreTag() {
+        Class test = builder.buildTest("./test/com/someplace/package1/SomeClass.java", '''
+            /** <code class="groovyTestCase"> assert true </code>
+             */
+            public class SomeClass { }
+        ''')
+        test.newInstance().testAssertionFromLineNumber2()
+    }
+    
+    void testAssertionSyntaxErrorsReportedAtTestTime() {
+        Class test = builder.buildTest("SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert #@$@ </pre> */
+            public class SomeClass { }
+        ''')
+        shouldFail(MultipleCompilationErrorsException) {
+            test.newInstance().testAssertionFromLineNumber2()
+        }
+    }
+    
+    void testDecodesCommonHtml() {
+        Class test = builder.buildTest("SomeClass.java", '''
+            /** <pre class="groovyTestCase"> assert 3 &lt; 5
+             * assert """&nbsp;&gt;&lt;&quot;&amp;&apos;&at;&ndash;""" == """ ><"&'@-"""</pre> */
+            public class SomeClass { }
+        ''')
+        test.newInstance().testAssertionFromLineNumber2();
+    }
+}
\ No newline at end of file
diff --git a/src/test/groovy/util/JavadocAssertionTestSuite.groovy b/src/test/groovy/util/JavadocAssertionTestSuite.groovy
new file mode 100644
index 0000000..5dc6b1c
--- /dev/null
+++ b/src/test/groovy/util/JavadocAssertionTestSuite.groovy
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2003-2007 the original author or authors.
+ *
+ * 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 groovy.util
+
+import junit.framework.TestSuite
+import junit.framework.Test
+
+/**
+ * <code>JavadocAssertionTestSuite</code> will dynamically create test cases from Groovy assertions placed within
+ * Javadoc comments. Assertions should be placed within an html tag with a <code>class="groovyTestCase"</code>
+ * attribute assignment. Example:
+ * <pre>&lt;pre class="groovyTestCase"&gt; assert "example".size() == 6 &lt;/pre&gt;</pre>
+ *
+ * Source files will be read from the directory specified by the <code>javadocAssertion.src.dir</code>
+ * system property, including all files matching <code>javadocAssertion.src.pattern</code> and
+ * excluding files matching the <code>javadocAssertion.src.excludesPattern</code>. 
+ *
+ * By default all <code>.java</code> and <code>.groovy</code> source files from <code>./src</code> will
+ * be scanned for assertions.
+ *
+ * @author Merlyn Albery-Speyer
+ */
+class JavadocAssertionTestSuite extends TestSuite {
+    /** The System Property to set as base directory for collection of Classes.
+     * The pattern will be used as an Ant fileset include basedir.
+     * Key is "javadocAssertion.src.dir".
+     * Defaults to the <code>./src</code> directory
+     */
+    public static final String SYSPROP_SRC_DIR = "javadocAssertion.src.dir";
+
+    /** The System Property to set as the filename pattern for collection of Classes.
+     * The pattern will be used as Regular Expression pattern applied with the find
+     * operator against each candidate file.path.
+     * Key is "javadocAssertion.src.pattern".
+     * Defaults to including all <code>.java</code> and <code>.groovy</code> files.
+     */
+    public static final String SYSPROP_SRC_PATTERN = "javadocAssertion.src.pattern";
+    
+    /** The System Property to set as a filename excludes pattern for collection of Classes.
+     * When non-empty, the pattern will be used as Regular Expression pattern applied with the
+     * find operator against each candidate file.path.
+     * Key is "javadocAssertion.src.excludesPattern".
+     * Default value is "".
+     */
+    public static final String SYSPROP_SRC_EXCLUDES_PATTERN = "javadocAssertion.src.excludesPattern";
+    
+    private static JavadocAssertionTestBuilder testBuilder = new JavadocAssertionTestBuilder()
+    private static IFileNameFinder finder = new FileNameFinder()
+    
+    static Test suite() {
+        String basedir = System.getProperty(SYSPROP_SRC_DIR, "./src/")
+        return suite(basedir)
+    }
+    
+    static Test suite(String basedir) {
+        String includePattern = System.getProperty(SYSPROP_SRC_PATTERN, "**/*.java,**/*.groovy")
+        return suite(basedir, includePattern)
+    }
+    
+    static Test suite(String basedir, String includePattern) {
+        String excludePattern = System.getProperty(SYSPROP_SRC_EXCLUDES_PATTERN, "")
+        return suite(basedir, includePattern, excludePattern)
+    }
+    
+    static Test suite(String basedir, String includePattern, String excludePattern) {
+        assert new File(basedir).exists()
+        
+        TestSuite suite = new JavadocAssertionTestSuite()
+
+        Collection filenames = finder.getFileNames([dir:basedir, includes:includePattern, excludes:excludePattern])
+        filenames.each { filename ->
+            String code = new File(filename).text
+            Class test = testBuilder.buildTest(filename, code)
+            if (test != null) {
+                suite.addTestSuite(test)
+            }
+        }
+
+        return suite
+    }
+}
\ No newline at end of file

