You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2023/06/10 17:32:25 UTC

[groovy] 01/02: refactor, regroup and rename tests

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 9dc1410454b7d9b55c6454430125a62a223c915e
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Jun 10 09:37:34 2023 -0500

    refactor, regroup and rename tests
---
 .../stc/ClosureParamTypeInferenceSTCTest.groovy    | 2296 ++++++++++----------
 ...osureParamTypeInferenceStaticCompileTest.groovy |    4 +-
 2 files changed, 1150 insertions(+), 1150 deletions(-)

diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index dc82c599dc..f346887642 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -18,266 +18,167 @@
  */
 package groovy.transform.stc
 
+import org.codehaus.groovy.control.customizers.ImportCustomizer
+
 /**
  * Unit tests for static type checking : closure parameter type inference.
  */
 class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
 
-    void testInferenceForDGM_collectUsingExplicitIt() {
-        assertScript '''
-            ['a','b'].collect { it -> it.toUpperCase() }
-        '''
-        shouldFailWithMessages '''
-            ['a','b'].collect { Date it -> it.toUpperCase() }
-        ''',
-        'Expected type java.lang.String for closure parameter: it'
-    }
-
-    void testInferenceForDGM_collectUsingImplicitIt() {
-        assertScript '''
-            ['a','b'].collect { it.toUpperCase() }
-        '''
-        assertScript '''
-            def items = []
-            ['a','b','c'].collect(items) { it.toUpperCase() }
-        '''
-        assertScript '''
-            String[] array = ['foo', 'bar', 'baz']
-            assert array.collect { it.startsWith('ba') } == [false, true, true]
-        '''
-        assertScript '''
-            List<Boolean> answer = [true]
-            String[] array = ['foo', 'bar', 'baz']
-            array.collect(answer){it.startsWith('ba')}
-            assert answer == [true, false, true, true]
-        '''
-        assertScript '''
-            Iterator<String> iter = ['foo', 'bar', 'baz'].iterator()
-            assert iter.collect { it.startsWith('ba') } == [false, true, true]
-        '''
-        assertScript '''
-            assert [1234, 3.14].collect { it.intValue() } == [1234,3]
-        '''
-    }
-
-    void testInferenceForDGM_eachUsingExplicitIt() {
-        assertScript '''
-            ['a','b'].each { it -> it.toUpperCase() }
-        '''
-    }
-
-    void testInferenceForDGM_eachUsingImplicitIt() {
-        assertScript '''
-            ['a','b'].each { it.toUpperCase() }
-        '''
-    }
-
-    void testInferenceForDGM_countUsingFirstSignature() {
-        assertScript '''
-            def src = [a: 1, b:2, c:3]
-            assert src.count { k,v -> v>1 } == 2
-        '''
-    }
-
-    void testInferenceForDGM_countUsingSecondSignature() {
-        assertScript '''
-            def src = [a: 1, b:2, c:3]
-            assert src.count { e -> e.value>1 } == 2
-        '''
+    @Override
+    void configure() {
+        config.addCompilationCustomizers(
+            new ImportCustomizer().addStarImports('groovy.transform', 'groovy.transform.stc', 'java.util.function')
+        )
     }
 
-    void testInferenceForDGM_countUsingSecondSignatureAndImplicitIt() {
+    // GROOVY-6022
+    void testSimpleType1() {
         assertScript '''
-            def src = [a: 1, b:2, c:3]
-            assert src.count { it.value>1 } == 2
-        '''
-    }
+            class Item {
+                int x
+            }
 
-    void testInferenceForDGM_collectManyUsingFirstSignature() {
-        assertScript '''
-            def map = [bread:3, milk:5, butter:2]
-            def result = map.collectMany{ k, v -> k.startsWith('b') ? k.toList() : [] }
-            assert result == ['b', 'r', 'e', 'a', 'd', 'b', 'u', 't', 't', 'e', 'r']
-        '''
-    }
+            void m(Item item, @ClosureParams(value=SimpleType, options="Item") Closure... closures) {
+                closures*.call(item)
+            }
 
-    void testInferenceForDGM_collectManyUsingSecondSignature() {
-        assertScript '''
-            def map = [bread:3, milk:5, butter:2]
-            def result = map.collectMany{ e -> e.key.startsWith('b') ? e.key.toList() : [] }
-            assert result == ['b', 'r', 'e', 'a', 'd', 'b', 'u', 't', 't', 'e', 'r']
+            m(new Item(), { item -> item.x }, { it.x })
         '''
     }
 
-    void testInferenceForDGM_collectManyUsingSecondSignatureAndImplicitIt() {
-        assertScript '''
-            def map = [bread:3, milk:5, butter:2]
-            def result = map.collectMany{ it.key.startsWith('b') ? it.key.toList() : [] }
-            assert result == ['b', 'r', 'e', 'a', 'd', 'b', 'u', 't', 't', 'e', 'r']
-        '''
+    // GROOVY-6602
+    void testSimpleType2() {
+        shouldFailWithMessages '''
+            void foo(@ClosureParams(value=SimpleType, options="java.lang.Number") Closure c) {
+                c.call(4.5)
+            }
+            foo { Integer i -> println i }
+        ''',
+        'Expected type java.lang.Number for closure parameter: i'
     }
 
-    void testInferenceForDGM_collectMap() {
-        assertScript '''
-            assert [a: 'foo',b:'bar'].collect { k,v -> k+v } == ['afoo','bbar']
-            assert [a: 'foo',b:'bar'].collect { e -> e.key+e.value } == ['afoo','bbar']
-            assert [a: 'foo',b:'bar'].collect { it.key+it.value } == ['afoo','bbar']
-        '''
+    // GROOVY-6603
+    void testSimpleType3() {
+        shouldFailWithMessages '''
+            void foo(@ClosureParams(value=SimpleType, options="java.lang.Number") Closure c) {
+                c.call("x")
+            }
+        ''',
+        'Cannot call closure that accepts [java.lang.Number] with [java.lang.String]'
     }
 
-    void testInferenceForDGM_collectMapWithCollection() {
+    void testFirstParam1() {
         assertScript '''
-            assert [a: 'foo',b:'bar'].collect([]) { k,v -> k+v } == ['afoo','bbar']
-            assert [a: 'foo',b:'bar'].collect([]) { e -> e.key+e.value } == ['afoo','bbar']
-            assert [a: 'foo',b:'bar'].collect([]) { it.key+it.value } == ['afoo','bbar']
+            def <T> T foo(T t, @ClosureParams(FirstParam) Closure c) { c.call(t) }
+            assert foo('a') { it.toUpperCase() } == 'A'
         '''
     }
 
-    void testInferenceForDGM_collectEntries() {
+    // GROOVY-6729
+    void testFirstParam2() {
         assertScript '''
-            assert ['a','b','c'].collectEntries { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
+            static <T> List<T> foo(List<T> list, @ClosureParams(FirstParam.FirstGenericType) Closure c) {
+                list.each {
+                    c.call(it)
+                }
+                return list
+            }
+            foo(["a","b","c"]) { s ->
+                s.toUpperCase() // Cannot find matching method java.lang.Object#toUpperCase()
+            }
         '''
     }
 
-    void testInferenceForDGM_collectEntriesWithCollector() {
+    void testFromStringWithBasicType() {
         assertScript '''
-            assert ['a','b','c'].collectEntries([:]) { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
+            void foo(@ClosureParams(value=FromString, options="java.lang.String") Closure c) { c.call('foo') }
+            foo { String str -> println str.toUpperCase()}
         '''
-    }
 
-    void testInferenceForDGM_collectEntriesIterator() {
-        assertScript '''
-            assert ['a','b','c'].iterator().collectEntries { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
-        '''
+        shouldFailWithMessages '''
+            void foo(@ClosureParams(value=FromString, options="java.lang.String") Closure c) { c.call('foo') }
+            foo { Date str -> println str}
+        ''',
+        'Expected type java.lang.String for closure parameter: str'
     }
 
-    void testInferenceForDGM_collectEntriesIteratorWithCollector() {
+    void testFromStringWithGenericType() {
         assertScript '''
-            assert ['a','b','c'].iterator().collectEntries([:]) { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
+            void foo(@ClosureParams(value=FromString, options="java.util.List<java.lang.String>") Closure c) { c.call(['foo']) }
+            foo { List<String> str -> str.each { println it.toUpperCase() } }
         '''
-    }
 
-    void testInferenceForDGM_collectEntriesOnMap() {
-        assertScript '''
-            assert [a:'a',b:'b',c:'c'].collectEntries { k,v -> [k+k, v.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
-            assert [a:'a',b:'b',c:'c'].collectEntries { e -> [e.key+e.key, e.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
-            assert [a:'a',b:'b',c:'c'].collectEntries { [it.key+it.key, it.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
-        '''
+        shouldFailWithMessages '''
+            void foo(@ClosureParams(value=FromString, options="java.util.List<java.lang.String>") Closure c) { c.call(['foo']) }
+            foo { List<Date> d -> d.each { println it } }
+        ''',
+        'Expected type java.util.List<java.lang.String> for closure parameter: d'
     }
 
-    void testInferenceForDGM_collectEntriesOnMapWithCollector() {
+    // GROOVY-9518
+    void testFromStringWithGenericType2() {
         assertScript '''
-            assert [a:'a',b:'b',c:'c'].collectEntries([:]) { k,v -> [k+k, v.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
-            assert [a:'a',b:'b',c:'c'].collectEntries([:]) { e -> [e.key+e.key, e.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
-            assert [a:'a',b:'b',c:'c'].collectEntries([:]) { [it.key+it.key, it.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
-        '''
-    }
+            class C {
+                C(String s, @ClosureParams(value=FromString, options="java.util.List<java.lang.Integer>") Closure<Integer> c) {
+                }
+            }
 
-    void testInferenceForDGM_collectEntriesOnArray() {
-        assertScript '''
-            String[] array = ['a','b','c']
-            assert array.collectEntries { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
+            new C('blah', { list -> list.get(0) })
         '''
-    }
 
-    void testInferenceForDGM_collectEntriesOnArrayWithCollector() {
         assertScript '''
-            String[] array = ['a','b','c']
-            assert array.collectEntries([:]) { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
-        '''
-    }
+            class C {
+                C(String s, Comparable<List<Integer>> c) {
+                }
+            }
 
-    void testInferenceForDGM_collectManyOnIterable() {
-        assertScript '''
-            assert (0..5).collectMany { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
+            new C('blah', { list -> list.get(0) })
         '''
-    }
 
-    void testInferenceForDGM_collectManyOnIterator() {
         assertScript '''
-            assert (0..5).iterator().collectMany { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
-        '''
-    }
+            class C {
+                C(String s, Comparable<List<Integer>> c) {
+                }
+            }
 
-    void testInferenceForDGM_collectManyOnIterableWithCollector() {
-        assertScript '''
-            assert (0..5).collectMany([]) { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
+            new C('blah', { it.get(0) })
         '''
     }
 
-    void testInferenceForDGM_collectManyOnMap() {
+    void testFromStringWithTypeParameter1() {
         assertScript '''
-            assert [a:0,b:1,c:2].collectMany { k,v -> [v, 2*v ]} == [0,0,1,2,2,4]
-            assert [a:0,b:1,c:2].collectMany { e -> [e.value, 2*e.value ]} == [0,0,1,2,2,4]
-            assert [a:0,b:1,c:2].collectMany { [it.value, 2*it.value ]} == [0,0,1,2,2,4]
+            def <T> void foo(T t, @ClosureParams(value=FromString, options="T") Closure c) { c.call(t) }
+            foo('bar') {
+                it.toUpperCase()
+            }
         '''
     }
 
-    void testInferenceForDGM_collectManyOnMapWithCollector() {
+    void testFromStringWithTypeParameter2() {
         assertScript '''
-            assert [a:0,b:1,c:2].collectMany([]) { k,v -> [v, 2*v ]} == [0,0,1,2,2,4]
-            assert [a:0,b:1,c:2].collectMany([]) { e -> [e.value, 2*e.value ]} == [0,0,1,2,2,4]
-            assert [a:0,b:1,c:2].collectMany([]) { [it.value, 2*it.value ]} == [0,0,1,2,2,4]
+            def <T> void foo(T t, @ClosureParams(value=FromString, options="T") Closure c) { c.call(t) }
+            foo(new Date()) {
+                it.time
+            }
         '''
     }
 
-    void testInferenceForDGM_collectManyOnArray() {
+    void testFromStringWithTypeParameter3() {
         assertScript '''
-            Integer[] arr = (0..5) as Integer[]
-            assert arr.collectMany { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
-        '''
-    }
-
-    void testInferenceOnNonExtensionMethod() {
-        assertScript '''import groovy.transform.stc.FirstParam
-            def <T> T foo(T arg, @ClosureParams(FirstParam) Closure c) { c.call(arg) }
-            assert foo('a') { it.toUpperCase() } == 'A'
-        '''
-    }
-
-    void testFromStringWithSimpleType() {
-        assertScript '''import groovy.transform.stc.FromString
-            void foo(@ClosureParams(value=FromString,options="java.lang.String") Closure cl) { cl.call('foo') }
-            foo { String str -> println str.toUpperCase()}
-        '''
-
-        shouldFailWithMessages '''import groovy.transform.stc.FromString
-            void foo(@ClosureParams(value=FromString,options="java.lang.String") Closure cl) { cl.call('foo') }
-            foo { Date str -> println str}
-        ''',
-        'Expected type java.lang.String for closure parameter: str'
-    }
-
-    void testFromStringWithGenericType() {
-        assertScript '''import groovy.transform.stc.FromString
-            void foo(@ClosureParams(value=FromString,options="java.util.List<java.lang.String>") Closure cl) { cl.call(['foo']) }
-            foo { List<String> str -> str.each { println it.toUpperCase() } }
-        '''
-
-        shouldFailWithMessages '''import groovy.transform.stc.FromString
-            void foo(@ClosureParams(value=FromString,options="java.util.List<java.lang.String>") Closure cl) { cl.call(['foo']) }
-            foo { List<Date> d -> d.each { println it } }
-        ''',
-        'Expected type java.util.List<java.lang.String> for closure parameter: d'
-    }
-
-    void testFromStringWithTypeParameter1() {
-        assertScript '''import groovy.transform.stc.FromString
-            def <T> void foo(T t, @ClosureParams(value=FromString,options="T") Closure cl) { cl.call(t) }
-            foo('hey') { println it.toUpperCase() }
-        '''
-    }
-
-    void testFromStringWithTypeParameter2() {
-        assertScript '''import groovy.transform.stc.FromString
-            def <T> void foo(T t, @ClosureParams(value=FromString,options="java.util.List<T>") Closure cl) { cl.call([t,t]) }
-            foo('hey') { List<String> str -> str.each { println it.toUpperCase() } }
+            def <T> void foo(T t, @ClosureParams(value=FromString, options="java.util.List<T>") Closure c) { c.call([t,t]) }
+            foo('bar') { List<String> list ->
+                list*.toUpperCase()
+            }
+            foo('baz') { list ->
+                list*.toUpperCase()
+            }
         '''
     }
 
     // GROOVY-7789
-    void testFromStringWithTypeParameter3() {
-        assertScript '''import groovy.transform.stc.FromString
+    void testFromStringWithTypeParameter4() {
+        assertScript '''
             class Monad<T> {  private final Closure c
                 Monad(@ClosureParams(value=FromString, options='T') Closure c) {
                     this.c = c
@@ -295,7 +196,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClass() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo<T> {
                 void foo(@ClosureParams(value=FromString,options="java.util.List<T>") Closure cl) { cl.call(['hey','ya']) }
             }
@@ -305,7 +206,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClassWithTwoGenerics() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo<T,U> {
                 void foo(@ClosureParams(value=FromString,options="java.util.List<U>") Closure cl) { cl.call(['hey','ya']) }
             }
@@ -315,7 +216,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignature() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo<T,U> {
                 public void foo(@ClosureParams(value=FromString,options="java.util.List<U>") Closure cl) { cl.call(['hey','ya']) }
             }
@@ -325,7 +226,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQN() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo<T,U> {
                 public void foo(@ClosureParams(value=FromString,options="List<U>") Closure cl) { cl.call(['hey','ya']) }
             }
@@ -335,7 +236,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClass() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo {
                 void bar() {
                     println 'Haha!'
@@ -350,7 +251,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClassAndTwoArgs() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo {
                 void bar() {
                     println 'Haha!'
@@ -365,7 +266,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
     }
 
     void testFromStringWithTypeParameterFromClassWithTwoGenericsAndPolymorphicSignature() {
-        assertScript '''import groovy.transform.stc.FromString
+        assertScript '''
             class Foo {
                 void bar() {
                     println 'Haha!'
@@ -386,1359 +287,1458 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringInSameSourceUnit() {
-        assertScript '''import groovy.transform.stc.FromString
-            public <T> void doSomething(T val, @ClosureParams(value=FromString, options="T") Closure cl) {
-                cl(val)
-            }
-            doSomething('foo') {
-                println it.toUpperCase()
-            }
-            doSomething(new Date()) {
-                println it.time
+    // GROOVY-6939
+    void testParamCountCheck1() {
+        shouldFailWithMessages '''
+            def m(o) {
+                o.each { x, y -> }
             }
-        '''
-    }
-
-    void testInferenceForDGM_countIterableOrIterator() {
-        assertScript '''
-            assert ['Groovy','Java'].count { it.length() > 4 } == 1
-        '''
-        assertScript '''
-            assert ['Groovy','Java'].iterator().count { it.length() > 4 } == 1
-        '''
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 2'
     }
 
-    void testInferenceForDGM_countMap() {
-        assertScript '''
-            assert [G:'Groovy',J:'Java'].count { k,v -> v.length() > 4 } == 1
-            assert [G:'Groovy',J:'Java'].count { e -> e.value.length() > 4 } == 1
-            assert [G:'Groovy',J:'Java'].count { it.value.length() > 4 } == 1
-        '''
+    // GROOVY-6939
+    void testParamCountCheck2() {
+        shouldFailWithMessages '''
+            def m(o) {
+                o.eachWithIndex { x, y, z -> }
+            }
+        ''',
+        'Incorrect number of parameters. Expected 2 but found 3'
     }
 
-    void testInferenceForDGM_countArray() {
-        assertScript '''
-            String[] array = ['Groovy','Java']
-            assert array.count { it.length() > 4 } == 1
-        '''
+    // GROOVY-6939
+    void testParamCountCheck3() {
+        shouldFailWithMessages '''
+            def m(o) {
+                o.eachWithIndex { print it }
+            }
+        ''',
+        'Incorrect number of parameters. Expected 2 but found 1'
     }
 
-    void testInferenceForDGM_countByCollection() {
-        assertScript '''
-            assert ['Groovy','yvoorG'].countBy { it.length() } == [6:2]
+    // GROOVY-6939
+    void testParamCountCheck4() {
+        shouldFailWithMessages '''
+            def m(... array) {
+                array.each { x, y -> }
+            }
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 2'
+    }
+
+    // GROOVY-6939
+    void testParamCountCheck5() {
+        shouldFailWithMessages '''
+            def m() {
+                [:].each { -> }
+            }
+        ''',
+        'Incorrect number of parameters. Expected 1 or 2 but found 0'
+    }
+
+    // GROOVY-8499
+    void testParamCountCheck6() {
+        shouldFailWithMessages '''
+            ['ab'.chars,'12'.chars].combinations().stream().map((x, y) -> "$x$y")
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 2'
+    }
+
+    // GROOVY-8816
+    void testParamCountCheck7() {
+        shouldFailWithMessages '''
+            def m() {
+                [].each { -> }
+            }
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 0'
+    }
+
+    // GROOVY-9854
+    void testParamCountCheck8() {
+        shouldFailWithMessages '''
+            switch (42) { case { -> }: break; }
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 0'
+    }
+
+    // GROOVY-9854
+    void testParamCountCheck9() {
+        shouldFailWithMessages '''
+            switch (42) { case { i, j -> }: break; }
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 2'
+    }
+
+    // GROOVY-11089
+    void testParamCountCheck10() {
+        shouldFailWithMessages '''
+            def array = new String[]{'a','b'}
+            array.with { a,b -> }
+        ''',
+        'Incorrect number of parameters. Expected 1 but found 2'
+    }
+
+    // GROOVY-7141
+    void testInferenceWithSAMTypeCoercion1() {
+        String sam = '''
+            @FunctionalInterface
+            interface I {
+                String foo(String s)
+            }
         '''
-        assertScript '''
-            assert ['Groovy','yvoorG'].iterator().countBy { it.length() } == [6:2]
+        assertScript sam + '''
+            def impl = [foo: { it.toUpperCase() }] as I
+            String result = impl.foo('bar')
+            assert result == 'BAR'
         '''
-    }
-    void testInferenceForDGM_countByArray() {
-        assertScript '''
-            String[] array = ['Groovy','yvoorG']
-            assert array.countBy { it.length() } == [6:2]
+        assertScript sam + '''
+            def impl = [foo: { s -> s.toUpperCase() }] as I
+            String result = impl.foo('bar')
+            assert result == 'BAR'
+        '''
+        assertScript sam + '''
+            def impl = [foo: { String s -> s.toUpperCase() }] as I
+            String result = impl.foo('bar')
+            assert result == 'BAR'
         '''
-    }
-    void testInferenceForDGM_countByMap() {
         assertScript '''
-            assert [langs:['Groovy','Java']].countBy { k,v -> k.length() } == [5:1]
-            assert [langs:['Groovy','Java']].countBy { e -> e.key.length() } == [5:1]
-            assert [langs:['Groovy','Java']].countBy { it.key.length() } == [5:1]
+            def impl = [apply: { it.toUpperCase() }] as java.util.function.Function<String,String>
+            String result = impl.apply('bar')
+            assert result == 'BAR'
         '''
     }
 
-    void testInferenceForDGM_downto() {
+    void testInferenceWithSAMTypeCoercion2() {
         assertScript '''
-            BigDecimal sum = 0
-            10.0.downto(0) {
-                sum += 2*it
+            interface Action<T> {
+                void execute(T thing)
             }
-            assert sum == 110
-        '''
-        assertScript '''
-            BigInteger sum = 0
-            10G.downto(0) {
-                sum += 2*it
+
+            class Wrapper<T> {
+                private final T thing
+                Wrapper(T thing) {
+                    this.thing = thing
+                }
+                void contravariantTake(Action<? super T> action) {
+                    action.execute(thing)
+                }
+                void invariantTake(Action<T> action) {
+                    action.execute(thing)
+                }
             }
-            assert sum == 110
-        '''
-        assertScript '''
-            double sum = 0
-            10d.downto(0) {
-                sum += 2*it
+
+            static <T> Wrapper<T> wrap(java.util.concurrent.Callable<T> callable) {
+                new Wrapper(callable.call())
             }
-            assert sum == 110
-        '''
-        assertScript '''
-            Double sum = 0
-            new Double(10).downto(0) {
-                sum += 2*it
+            static Integer dub(Integer integer) {
+                integer * 2
             }
-            assert sum == 110
-        '''
-        assertScript '''
-            float sum = 0
-            10f.downto(0) {
-                sum += 2*it
+
+            wrap {
+                1
+            } contravariantTake {
+                dub(it) // fails static compile, 'it' is not known to be Integer
             }
-            assert sum == 110
-        '''
-        assertScript '''
-            Float sum = 0
-            new Float(10).downto(0) {
-                sum += 2*it
+
+            wrap {
+                1
+            } invariantTake {
+                dub(it) // passes static compile, 'it' is known to be Integer
             }
-            assert sum == 110
         '''
+    }
+
+    void testGroovy6735() {
         assertScript '''
-            long sum = 0
-            10L.downto(0) {
-                sum += 2*it
+            def extractInfo(String s) {
+              def squareNums = s.findAll(/\\d+/) { String num -> num.toInteger() }.collect{ Integer num -> num ** 2 }
+              def wordSizePlusNum = s.findAll(/\\s*(\\w+)\\s*(\\d+)/) { _, String word, String num -> word.size() + num.toInteger() }
+              def numPlusWordSize = s.findAll(/\\s*(\\w+)\\s*(\\d+)/) { _, word, num -> num.toInteger() + word.size() }
+              [squareNums, wordSizePlusNum, numPlusWordSize]
             }
-            assert sum == 110
+            assert extractInfo(" ab 12 cdef 34 jhg ") == [[144, 1156], [14, 38], [14, 38]]
         '''
         assertScript '''
-            Long sum = 0
-            new Long(10).downto(0) {
-                sum += 2*it
-            }
-            assert sum == 110
+          assert "foobarbaz".findAll('b(a)([rz])') { full, a, b -> assert "BA"=="B" + a.toUpperCase() }.size() == 2
+          assert "foobarbaz".findAll('ba') { String found -> assert "BA" == found.toUpperCase() }.size() == 2
         '''
+    }
+
+    void testGroovy9058() {
         assertScript '''
-            def sum = 0
-            new Byte((byte)10).downto(0) {
-                sum += 2*it
+            List<Object[]> table() {
+                [ ['fee', 'fi'] as Object[], ['fo', 'fum'] as Object[] ]
             }
-            assert sum == 110
+
+            List<String> result = []
+            table().each { row -> result << row[0].toString().toUpperCase() }
+            assert result == ['FEE', 'FO']
         '''
     }
 
-    void testInferenceForDGM_upto() {
+    void testGroovy9570() {
         assertScript '''
-            BigDecimal sum = 0
-            0.0.upto(10) {
-                sum += 2*it
+            class C<I extends Item> {
+                Queue<I> queue
+
+                def c = { ->
+                    queue.each { I item ->
+                        println item
+                    }
+                }
+
+                def m() {
+                    queue.each { I item ->
+                        println item
+                    }
+                }
             }
-            assert sum == 110
+
+            interface Item {}
+
+            new C()
         '''
+    }
+
+    void testGroovy9735() {
         assertScript '''
-            BigInteger sum = 0
-            0G.upto(10) {
-                sum += 2*it
+            class C<I extends Item> {
+                Queue<I> queue
+
+                def c = { ->
+                    x(queue) { I item ->
+                        println item
+                    }
+                }
+
+                def m() {
+                    x(queue) { I item ->
+                        println item
+                    }
+                }
+
+                def <T> T x(Collection<T> y, @ClosureParams(FirstParam.FirstGenericType) Closure z) {
+                }
             }
-            assert sum == 110
+
+            interface Item {}
+
+            new C()
         '''
+    }
+
+    void testGroovy9597a() {
         assertScript '''
-            double sum = 0
-            0d.upto(10) {
-                sum += 2*it
+            class A {
+                def <T> void proc(Collection<T> values, @ClosureParams(FirstParam.FirstGenericType) Closure<String> block) {
+                }
             }
-            assert sum == 110
-        '''
-        assertScript '''
-            Double sum = 0
-            new Double(0).upto(10) {
-                sum += 2*it
+
+            class B {
+                List<Integer> list
+                void test(A a) {
+                    a.proc(this.list) { it.toBigDecimal().toString() } // works
+                    a.with {
+                      proc(this.list) { it.toBigDecimal().toString() } // error
+                    }
+                }
             }
-            assert sum == 110
+
+            new B().test(new A())
         '''
+    }
+
+    void testGroovy9597b() {
         assertScript '''
-            float sum = 0
-            0f.upto(10) {
-                sum += 2*it
+            class A {
+                static A of(@DelegatesTo(A) Closure x) {
+                    new A().tap {
+                        x.delegate = it
+                        x.call()
+                    }
+                }
+                def <T> void proc(Collection<T> values, @ClosureParams(FirstParam.FirstGenericType) Closure<String> block) {
+                }
             }
-            assert sum == 110
+
+            class B {
+              List<Integer> list
+              A a = A.of {
+                  proc(
+                      this.list,
+                      { it.toBigDecimal().toString() } // Cannot find matching method java.lang.Object#toBigDecimal()
+                  )
+              }
+            }
+
+            new B()
         '''
+    }
+
+    void testGroovy9854() {
         assertScript '''
-            Float sum = 0
-            new Float(0).upto(10) {
-                sum += 2*it
+            def result = switch (42) {
+                case { i -> i > 0 } -> 'positive'
+                case { it < 0 } -> 'negative'
+                default -> 'zero'
             }
-            assert sum == 110
+            assert result == 'positive'
         '''
+
+        shouldFailWithMessages '''
+            switch (42) { case { String s -> }: break; }
+        ''',
+        'Expected type java.lang.Integer for closure parameter: s'
+    }
+
+    void testGroovy9968() {
         assertScript '''
-            long sum = 0
-            0L.upto(10) {
-                sum += 2*it
+            @Canonical class Pogo { String prop }
+            @Canonical class Type<T extends Pogo> implements Iterable<T> {
+                Iterator<T> iterator() {
+                    list.iterator()
+                }
+                List<T> list
             }
-            assert sum == 110
+
+            def iterable = new Type([new Pogo('x'), new Pogo('y'), new Pogo('z')])
+            assert iterable.collect { Pogo p -> p.prop } == ['x', 'y', 'z']
+            assert iterable.collect { it.prop } == ['x', 'y', 'z']
         '''
+    }
+
+    void testGroovy10180() {
         assertScript '''
-            Long sum = 0
-            new Long(0).upto(10) {
-                sum += 2*it
+            void test(args) {
+                if (args instanceof Map) {
+                    args.each { e ->
+                        def k = e.key, v = e.value
+                    }
+                }
             }
-            assert sum == 110
         '''
         assertScript '''
-            def sum = 0
-            new Byte((byte)0).upto(10) {
-                sum += 2*it
+            void test(args) {
+                if (args instanceof Map) {
+                    args.each { k, v ->
+                    }
+                }
             }
-            assert sum == 110
         '''
     }
 
-    void testInferenceForDGM_dropWhileOnIterable() {
+    void testGroovy10660() {
         assertScript '''
-            assert (0..10).dropWhile { it<5 } == (5..10)
-            assert (0..10).dropWhile { int i -> i<5 } == (5..10)
+            <T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
+                // batch processor:
+                return { text, list ->
+                    for (item in list) proc.accept(text, item)
+                }
+            }
+
+            m { text, item -> }
         '''
-    }
 
-    void testInferenceForDGM_dropWhileOnList() {
         assertScript '''
-            assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { it<5 } == [5,6,7,8,9,10]
-            assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { int i -> i<5 } == [5,6,7,8,9,10]
+            <T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
+                // batch processor:
+                return (text, list) -> {
+                    for (item in list) proc.accept(text, item)
+                }
+            }
+
+            m((text, item) -> { })
         '''
-    }
 
-    void testInferenceForDGM_dropWhileOnIterator() {
         assertScript '''
-            assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
-            assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
+            <T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
+                /*implicit return*/ (text, list) -> {
+                    for (item in list) proc.accept(text, item)
+                }
+            }
+
+            m((text, item) -> { })
         '''
     }
 
-    void testInferenceForDGM_dropWhileOnArray() {
+    void testGroovy10673() {
         assertScript '''
-            Integer[] array = [0,1,2,3,4,5,6,7,8,9,10]
-            assert array.iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
-            assert array.iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
+            void proc(Consumer<Number> action) {
+                action.accept(1.2345)
+            }
+
+            int i = 0
+            proc { n ->
+                def c = {
+                    i = n.intValue()
+                }
+                c()
+            }
+            assert i == 1
         '''
     }
 
-    void testInferenceForDGM_eachByte() {
-        assertScript '''
-            byte[] array = new byte[0]
-            array.eachByte { byte b -> b.intValue() }
-            array.eachByte { it.intValue() }
-        '''
-        assertScript '''
-            Byte[] array = new Byte[0]
-            array.eachByte { Byte b -> b.intValue() }
-            array.eachByte { it.intValue() }
-        '''
+    void testGroovy10756() {
+        assertScript """import ${Pogo10756.name.replace('$','.')}
+            Pogo10756.files.collect { it.name }
+            //                        ^^ File
+        """
+
+        assertScript """import ${Pogo10756.name.replace('$','.')}
+            def file = Pogo10756.files[0]
+            file?.name
+        """
     }
 
-    void testInferenceForDGM_eachMatch() {
-        assertScript '''
-            'foo bar baz'.eachMatch(~/(?m)^(\s*).*\n$/) { all, ws ->
-                all.trim(); ws.length()
-            }
-        '''
+    static class Pogo10756 {
+        static <T extends File> Collection<T> getFiles() { [] }
     }
 
-    void testInferenceForDGM_eachWithIndexOnMap() {
+    //--------------------------------------------------------------------------
+
+    void testDGM_anyOnMap() {
         assertScript '''
-            [a:'A',bb:'B',ccc:'C'].eachWithIndex { e,i -> assert e.key.toUpperCase() == e.value*(1+i) }
-            [a:'A',bb:'B',ccc:'C'].eachWithIndex { k,v,i -> assert k.toUpperCase() == v*(1+i) }
+            assert [a:10, b:1].any { k,v -> k.length() == v }
+            assert [a:10, b:1].any { e -> e.key.length() == e.value }
+            assert [a:10, b:1].any {it.key.length() == it.value }
         '''
     }
-    void testInferenceForDGM_eachWithIndexOnObject() {
+    void testDGM_anyOnIterable() {
         assertScript '''
-            def foo(object) {
-                object.eachWithIndex { Map<String,String> map, i -> map.ccc.toLowerCase() + (1+i) }
-                //                     ^^^^^^^^^^^^^^^^^^ each/eachWithIndex are flexible
-            }
-            foo([ [a:'A',bb:'B',ccc:'C'] ])
+            assert ['abc','de','f'].any { it.length() == 2 }
         '''
     }
-    void testInferenceForDGM_eachWithIndexOnIterable() {
+    void testDGM_anyOnIterator() {
         assertScript '''
-            ['1','2','3'].eachWithIndex { e,i -> assert e.toUpperCase() == String.valueOf(1+i) }
+            assert ['abc','de','f'].iterator().any { it.length() == 2 }
         '''
     }
-    void testInferenceForDGM_eachWithIndexOnIterator() {
+    void testDGM_anyOnArray() {
         assertScript '''
-            ['1','2','3'].iterator().eachWithIndex { e,i -> assert e.toUpperCase() == String.valueOf(1+i) }
+            String[] strings = ['abc','de','f']
+            assert strings.any { it.length() == 2 }
         '''
     }
-    void testInferenceForDGM_eachWithIndexOnRecursiveIterable() { // GROOVY-10651
-        ['', '<?>'].each { args ->
-            assertScript """
-                void proc(groovy.transform.stc.TreeNode$args node) {
-                    node.eachWithIndex { child, index ->
-                        proc(child) // recurse
-                    }
-                }
-            """
-        }
-    }
 
-    void testInferenceForDGM_everyOnIterable() {
+    void testDGM_collectExplicitIt() {
         assertScript '''
-            assert ['foo','bar','baz'].every { String it -> it.length() == 3 }
-            assert ['foo','bar','baz'].every { it -> it.length() == 3 }
-            assert ['foo','bar','baz'].every { it.length() == 3 }
+            ['a','b'].collect { it -> it.toUpperCase() }
         '''
+        shouldFailWithMessages '''
+            ['a','b'].collect { Date it -> it.toUpperCase() }
+        ''',
+        'Expected type java.lang.String for closure parameter: it'
     }
-    void testInferenceForDGM_everyOnIterator() {
+    void testDGM_collectImplicitIt() {
         assertScript '''
-            assert ['foo','bar','baz'].iterator().every { String it -> it.length() == 3 }
-            assert ['foo','bar','baz'].iterator().every { it -> it.length() == 3 }
-            assert ['foo','bar','baz'].iterator().every { it.length() == 3 }
+            ['a','b'].collect { it.toUpperCase() }
         '''
-    }
-    void testInferenceForDGM_everyOnArray() {
         assertScript '''
-            String[] items = ['foo','bar','baz']
-            assert items.every { it.length() == 3 }
-            assert items.every { String s -> s.length() == 3 }
+            def items = []
+            ['a','b','c'].collect(items) { it.toUpperCase() }
         '''
-    }
-    void testInferenceForDGM_everyOnMap() {
         assertScript '''
-            assert [a:'A',b:'B',cc:'CC'].every { String k, String v -> k == v.toLowerCase() }
-            assert [a:'A',b:'B',cc:'CC'].every { k, v -> k == v.toLowerCase() }
-            assert [a:'A',b:'B',cc:'CC'].every { e -> e.key == e.value.toLowerCase() }
-            assert [a:'A',b:'B',cc:'CC'].every { it.key == it.value.toLowerCase() }
+            String[] array = ['foo', 'bar', 'baz']
+            assert array.collect { it.startsWith('ba') } == [false, true, true]
+        '''
+        assertScript '''
+            List<Boolean> answer = [true]
+            String[] array = ['foo', 'bar', 'baz']
+            array.collect(answer){it.startsWith('ba')}
+            assert answer == [true, false, true, true]
+        '''
+        assertScript '''
+            Iterator<String> iter = ['foo', 'bar', 'baz'].iterator()
+            assert iter.collect { it.startsWith('ba') } == [false, true, true]
         '''
-    }
-
-    void testInferenceForDGM_findIndexOf() {
         assertScript '''
-            String[] items1 = ['foo','bar','baz']
-            assert items1.findIndexOf { it.startsWith('ba') == 1 }
-            assert items1.findIndexOf { String s -> s.startsWith('ba') == 1 }
-            def items2 = ['foo','bar','baz']
-            assert items2.findIndexOf { it.startsWith('ba') == 1 }
-            assert items2.iterator().findIndexOf { it.startsWith('ba') == 1 }
+            assert [1234, 3.14].collect { it.intValue() } == [1234,3]
         '''
     }
-
-    void testInferenceForDGM_findLastIndexOf() {
+    void testDGM_collectOnMap() {
         assertScript '''
-            String[] items1 = ['foo','bar','baz']
-            assert items1.findLastIndexOf { it.startsWith('ba') == 2 }
-            assert items1.findLastIndexOf { String s -> s.startsWith('ba') == 2 }
-            def items2 = ['foo','bar','baz']
-            assert items2.findLastIndexOf { it.startsWith('ba') == 2 }
-            assert items2.iterator().findLastIndexOf { it.startsWith('ba') == 2 }
+            assert [a: 'foo',b:'bar'].collect { k,v -> k+v } == ['afoo','bbar']
+            assert [a: 'foo',b:'bar'].collect { e -> e.key+e.value } == ['afoo','bbar']
+            assert [a: 'foo',b:'bar'].collect { it.key+it.value } == ['afoo','bbar']
         '''
-    }
 
-    void testInferenceForDGM_findIndexValues() {
         assertScript '''
-            String[] items1 = ['foo','bar','baz']
-            assert items1.findIndexValues { it.startsWith('ba') } == [1, 2]
-            assert items1.findIndexValues { String s -> s.startsWith('ba') } == [1, 2]
-            def items2 = ['foo','bar','baz']
-            assert items2.findIndexValues { it.startsWith('ba') } == [1, 2]
-            assert items2.iterator().findIndexValues { it.startsWith('ba') } == [1, 2]
+            assert [a: 'foo',b:'bar'].collect([]) { k,v -> k+v } == ['afoo','bbar']
+            assert [a: 'foo',b:'bar'].collect([]) { e -> e.key+e.value } == ['afoo','bbar']
+            assert [a: 'foo',b:'bar'].collect([]) { it.key+it.value } == ['afoo','bbar']
         '''
     }
 
-    void testInferenceForDGM_findOnCollection() {
+    void testDGM_collectEntries() {
         assertScript '''
-            assert ['a','bbb','ccc'].find { String it -> it.length() == 3 } == 'bbb'
-            assert ['a','bbb','ccc'].find { it -> it.length() == 3 } == 'bbb'
-            assert ['a','bbb','ccc'].find { it.length() == 3 } == 'bbb'
+            assert ['a','b','c'].collectEntries { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
         '''
     }
-    void testInferenceForDGM_findOnArray() {
+    void testDGM_collectEntriesWithCollector() {
         assertScript '''
-            String[] arraylistOfStrings = ['a','bbb','ccc']
-            assert arraylistOfStrings.find { String it -> it.length() == 3 } == 'bbb'
-            assert arraylistOfStrings.find { it -> it.length() == 3 } == 'bbb'
-            assert arraylistOfStrings.find { it.length() == 3 } == 'bbb'
+            assert ['a','b','c'].collectEntries([:]) { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
         '''
     }
-    void testInferenceForDGM_findOnMap() {
+    void testDGM_collectEntriesIterator() {
         assertScript '''
-            assert [a:2,b:4,c:6].find { String k, int v -> k.toUpperCase()=='C' && 2*v==12 } instanceof Map.Entry
-            assert [a:2,b:4,c:6].find { k, v -> k.toUpperCase()=='C' && 2*v==12 } instanceof Map.Entry
-            assert [a:2,b:4,c:6].find { e -> e.key.toUpperCase()=='C' && 2*e.value==12 } instanceof Map.Entry
-            assert [a:2,b:4,c:6].find { it.key.toUpperCase()=='C' && 2*it.value==12 } instanceof Map.Entry
+            assert ['a','b','c'].iterator().collectEntries { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
         '''
     }
-    void testInferenceForDGM_findOnStr() { // GROOVY-11076, GROOVY-11089
-        assertScript '''
-            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { List<String> all_zip_city -> all_zip_city*.toUpperCase() }
-        '''
+    void testDGM_collectEntriesIteratorWithCollector() {
         assertScript '''
-            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { String[] all_zip_city -> all_zip_city*.toUpperCase() }
+            assert ['a','b','c'].iterator().collectEntries([:]) { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
         '''
+    }
+    void testDGM_collectEntriesOnMap() {
         assertScript '''
-            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { Object[] all_zip_city -> all_zip_city*.toString() }
+            assert [a:'a',b:'b',c:'c'].collectEntries { k,v -> [k+k, v.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
+            assert [a:'a',b:'b',c:'c'].collectEntries { e -> [e.key+e.key, e.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
+            assert [a:'a',b:'b',c:'c'].collectEntries { [it.key+it.key, it.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
         '''
+    }
+    void testDGM_collectEntriesOnMapWithCollector() {
         assertScript '''
-            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { all, zip, city -> all.size() + zip.size() + city.size() }
+            assert [a:'a',b:'b',c:'c'].collectEntries([:]) { k,v -> [k+k, v.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
+            assert [a:'a',b:'b',c:'c'].collectEntries([:]) { e -> [e.key+e.key, e.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
+            assert [a:'a',b:'b',c:'c'].collectEntries([:]) { [it.key+it.key, it.value.toUpperCase() ]} == [aa:'A',bb:'B',cc:'C']
         '''
+    }
+    void testDGM_collectEntriesOnArray() {
         assertScript '''
-            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { String all, String zip, String city -> city + " " + zip }
+            String[] array = ['a','b','c']
+            assert array.collectEntries { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
         '''
+    }
+    void testDGM_collectEntriesOnArrayWithCollector() {
         assertScript '''
-            "75001 Paris".find(~/\\d{5}/) { String zip -> zip }
+            String[] array = ['a','b','c']
+            assert array.collectEntries([:]) { [it, it.toUpperCase() ]} == [a:'A',b:'B',c:'C']
         '''
-
-        shouldFailWithMessages '''
-            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { String all, Date zip, String city -> }
-        ''',
-        'Expected type java.lang.String for closure parameter: zip'
-
-        shouldFailWithMessages '''
-            "75001 Paris".find(~/\\d{5}/) { Number zip -> zip }
-        ''',
-        'Expected (java.util.List<java.lang.String>) or (java.lang.String) or (java.lang.String[]) but found (java.lang.Number)'
     }
 
-    void testInferenceForDGM_findAllOnCollection() {
+    void testDGM_collectManyUsingFirstSignature() {
         assertScript '''
-            assert ['a','bbb','ccc'].findAll { String it -> it.length() == 3 } == ['bbb','ccc']
-            assert ['a','bbb','ccc'].findAll { it -> it.length() == 3 } == ['bbb','ccc']
-            assert ['a','bbb','ccc'].findAll { it.length() == 3 } == ['bbb','ccc']
+            def map = [bread:3, milk:5, butter:2]
+            def result = map.collectMany{ k, v -> k.startsWith('b') ? k.toList() : [] }
+            assert result == ['b', 'r', 'e', 'a', 'd', 'b', 'u', 't', 't', 'e', 'r']
         '''
     }
-    void testInferenceForDGM_findAllOnArray() {
+
+    void testDGM_collectManyUsingSecondSignature() {
         assertScript '''
-            String[] arraylistOfStrings = ['a','bbb','ccc']
-            assert arraylistOfStrings.findAll { String it -> it.length() == 3 } == ['bbb','ccc']
-            assert arraylistOfStrings.findAll { it -> it.length() == 3 } == ['bbb','ccc']
-            assert arraylistOfStrings.findAll { it.length() == 3 } == ['bbb','ccc']
+            def map = [bread:3, milk:5, butter:2]
+            def result = map.collectMany{ e -> e.key.startsWith('b') ? e.key.toList() : [] }
+            assert result == ['b', 'r', 'e', 'a', 'd', 'b', 'u', 't', 't', 'e', 'r']
         '''
     }
-    void testInferenceForDGM_findAllOnMap() {
+
+    void testDGM_collectManyUsingSecondSignatureAndImplicitIt() {
         assertScript '''
-            assert [a:2,b:4,c:6].findAll { String k, int v -> k.toUpperCase()=='C' && 2*v==12 } == [c:6]
-            assert [a:2,b:4,c:6].findAll { k, v -> k.toUpperCase()=='C' && 2*v==12 } == [c:6]
-            assert [a:2,b:4,c:6].findAll { e -> e.key.toUpperCase()=='C' && 2*e.value==12 } == [c:6]
-            assert [a:2,b:4,c:6].findAll { it.key.toUpperCase()=='C' && 2*it.value==12 } == [c:6]
+            def map = [bread:3, milk:5, butter:2]
+            def result = map.collectMany{ it.key.startsWith('b') ? it.key.toList() : [] }
+            assert result == ['b', 'r', 'e', 'a', 'd', 'b', 'u', 't', 't', 'e', 'r']
         '''
     }
 
-    void testInferenceForDGM_findResultOnCollection() {
+    void testDGM_collectManyOnIterable() {
         assertScript '''
-            assert ['barbar','barbaz','foo'].findResult { it.length() == 3?it.toUpperCase():null } == 'FOO'
-            assert ['barbar','barbaz','foo'].findResult { String it -> it.length() == 3?it.toUpperCase():null } == 'FOO'
-            assert ['barbar','barbaz','foo'].findResult { it -> it.length() == 3?it.toUpperCase():null } == 'FOO'
-            assert ['barbar','barbaz','foo'].findResult(-1) { it.length() == 4?it.toUpperCase():null } == -1
-            assert ['barbar','barbaz','foo'].findResult(-1) { String it -> it.length() == 4?it.toUpperCase():null } == -1
-            assert ['barbar','barbaz','foo'].findResult(-1) { it -> it.length() == 4?it.toUpperCase():null } == -1
+            assert (0..5).collectMany { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
         '''
     }
-    void testInferenceForDGM_findResultOnIterable() {
+
+    void testDGM_collectManyOnIterator() {
         assertScript '''
-            assert (0..10).findResult { it== 3?2*it:null } == 6
-            assert (0..10).findResult { int it -> it==3?2*it:null } == 6
-            assert (0..10).findResult { it -> it==3?2*it:null } == 6
+            assert (0..5).iterator().collectMany { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
         '''
     }
-    void testInferenceForDGM_findResultOnMap() {
-        assertScript '''
-            assert [a:1, b:2, c:3].findResult { String k, int v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == 6
-            assert [a:1, b:2, c:3].findResult { k, v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == 6
-            assert [a:1, b:2, c:3].findResult { e -> "${e.key.toUpperCase()}$e.value"=='C3'?2*e.value:null } == 6
-            assert [a:1, b:2, c:3].findResult { "${it.key.toUpperCase()}$it.value"=='C3'?2*it.value:null } == 6
 
-            assert [a:1, b:2, c:3].findResult('a') { String k, int v -> "${k.toUpperCase()}$v"=='C4'?2*v:null } == 'a'
-            assert [a:1, b:2, c:3].findResult('a') { k, v -> "${k.toUpperCase()}$v"=='C4'?2*v:null } == 'a'
-            assert [a:1, b:2, c:3].findResult('a') { e -> "${e.key.toUpperCase()}$e.value"=='C4'?2*e.value:null } == 'a'
-            assert [a:1, b:2, c:3].findResult('a') { "${it.key.toUpperCase()}$it.value"=='C4'?2*it.value:null } == 'a'
+    void testDGM_collectManyOnIterableWithCollector() {
+        assertScript '''
+            assert (0..5).collectMany([]) { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
         '''
     }
-    void testInferenceForDGM_findResult() {
+
+    void testDGM_collectManyOnMap() {
         assertScript '''
-            String[] items1 = ['foo','bar','baz']
-            assert items1.findResult { it.startsWith('ba') ? it : null } == 'bar'
-            def items2 = ['foo','bar','baz']
-            assert items2.findResult { it.startsWith('ba') ? it : null } == 'bar'
-            assert items2.iterator().findResult { it.startsWith('ba') ? it : null } == 'bar'
+            assert [a:0,b:1,c:2].collectMany { k,v -> [v, 2*v ]} == [0,0,1,2,2,4]
+            assert [a:0,b:1,c:2].collectMany { e -> [e.value, 2*e.value ]} == [0,0,1,2,2,4]
+            assert [a:0,b:1,c:2].collectMany { [it.value, 2*it.value ]} == [0,0,1,2,2,4]
         '''
     }
 
-    void testInferenceForDGM_findResultsOnIterable() {
+    void testDGM_collectManyOnMapWithCollector() {
         assertScript '''
-            assert (0..10).findResults { it<3?2*it:null } == [0,2,4]
-            assert (0..10).findResults { int it -> it<3?2*it:null } == [0,2,4]
-            assert (0..10).findResults { it -> it<3?2*it:null } == [0,2,4]
+            assert [a:0,b:1,c:2].collectMany([]) { k,v -> [v, 2*v ]} == [0,0,1,2,2,4]
+            assert [a:0,b:1,c:2].collectMany([]) { e -> [e.value, 2*e.value ]} == [0,0,1,2,2,4]
+            assert [a:0,b:1,c:2].collectMany([]) { [it.value, 2*it.value ]} == [0,0,1,2,2,4]
         '''
     }
-    void testInferenceForDGM_findResultsOnMap() {
+
+    void testDGM_collectManyOnArray() {
         assertScript '''
-            assert [a:1, b:2, c:3].findResults { String k, int v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == [6]
-            assert [a:1, b:2, c:3].findResults { k, v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == [6]
-            assert [a:1, b:2, c:3].findResults { e -> "${e.key.toUpperCase()}$e.value"=='C3'?2*e.value:null } == [6]
-            assert [a:1, b:2, c:3].findResults { "${it.key.toUpperCase()}$it.value"=='C3'?2*it.value:null } == [6]
+            Integer[] arr = (0..5) as Integer[]
+            assert arr.collectMany { [it, 2*it ]} == [0,0,1,2,2,4,3,6,4,8,5,10]
         '''
     }
-    void testInferenceForDGM_findResults() {
+
+    void testDGM_countUsingFirstSignature() {
         assertScript '''
-            String[] items1 = ['foo','bar','baz']
-            assert items1.findResults { it.startsWith('ba') ? it : null } == ['bar', 'baz']
-            def items2 = ['foo','bar','baz']
-            assert items2.findResults { it.startsWith('ba') ? it : null } == ['bar', 'baz']
-            assert items2.iterator().findResults { it.startsWith('ba') ? it : null } == ['bar', 'baz']
+            def src = [a: 1, b:2, c:3]
+            assert src.count { k,v -> v>1 } == 2
         '''
     }
 
-    void testInferenceForDGM_groupByIterable() {
+    void testDGM_countUsingSecondSignature() {
         assertScript '''
-            assert ['a','bb','cc','d','eee'].groupBy { it.length() } == [1:['a','d'],2:['bb','cc'],3:['eee']]
+            def src = [a: 1, b:2, c:3]
+            assert src.count { e -> e.value>1 } == 2
         '''
     }
-    void testInferenceForDGM_groupByArray() {
+
+    void testDGM_countUsingSecondSignatureAndImplicitIt() {
         assertScript '''
-            String[] array = ['a','bb','cc','d','eee']
-            assert array.groupBy { it.length() } == [1:['a','d'],2:['bb','cc'],3:['eee']]
+            def src = [a: 1, b:2, c:3]
+            assert src.count { it.value>1 } == 2
         '''
     }
-    void testInferenceForDGM_groupByMap() {
+
+    void testDGM_countIterableOrIterator() {
         assertScript '''
-            assert [a:'1',b:'2',c:'C'].groupBy { e -> e.key.toUpperCase()==e.value?1:0 } == [0:[a:'1',b:'2'], 1:[c:'C']]
-            assert [a:'1',b:'2',c:'C'].groupBy { k, v -> k.toUpperCase()==v?1:0 } == [0:[a:'1',b:'2'], 1:[c:'C']]
-            assert [a:'1',b:'2',c:'C'].groupBy { it.key.toUpperCase()==it.value?1:0 } == [0:[a:'1',b:'2'], 1:[c:'C']]
+            assert ['Groovy','Java'].count { it.length() > 4 } == 1
         '''
-    }
-    void testInferenceForDGM_groupEntriesBy() {
         assertScript '''
-            def result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { k,v -> v % 2 }
-            result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { it.value % 2 }
-            result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { e -> e.value % 2 }
-            assert result[0]*.key == ["b", "d", "f"]
-            assert result[1]*.value == [1, 3, 5]
-     '''
+            assert ['Groovy','Java'].iterator().count { it.length() > 4 } == 1
+        '''
     }
 
-    void testInferenceForDGM_injectOnCollectionWithInitialValue() {
+    void testDGM_countMap() {
         assertScript '''
-            assert ['a','bb','ccc'].inject(0) { acc, str -> acc += str.length(); acc } == 6
+            assert [G:'Groovy',J:'Java'].count { k,v -> v.length() > 4 } == 1
+            assert [G:'Groovy',J:'Java'].count { e -> e.value.length() > 4 } == 1
+            assert [G:'Groovy',J:'Java'].count { it.value.length() > 4 } == 1
         '''
     }
 
-    void testInferenceForDGM_injectOnArrayWithInitialValue() {
+    void testDGM_countArray() {
         assertScript '''
-            String[] array = ['a','bb','ccc']
-            assert array.inject(0) { acc, str -> acc += str.length(); acc } == 6
+            String[] array = ['Groovy','Java']
+            assert array.count { it.length() > 4 } == 1
         '''
     }
 
-    void testInferenceForDGM_injectOnIteratorWithInitialValue() {
+    void testDGM_countByCollection() {
         assertScript '''
-            assert ['a','bb','ccc'].iterator().inject(0) { acc, str -> acc += str.length(); acc } == 6
+            assert ['Groovy','yvoorG'].countBy { it.length() } == [6:2]
         '''
-    }
-
-    void testInferenceForDGM_injectOnCollection() {
         assertScript '''
-            assert ['a','bb','ccc'].inject { acc, str -> acc += str.toUpperCase(); acc } == 'aBBCCC'
+            assert ['Groovy','yvoorG'].iterator().countBy { it.length() } == [6:2]
         '''
     }
-
-    void testInferenceForDGM_injectOnArray() {
+    void testDGM_countByArray() {
         assertScript '''
-            String[] array = ['a','bb','ccc']
-            assert array.inject { acc, str -> acc += str.toUpperCase(); acc } == 'aBBCCC'
+            String[] array = ['Groovy','yvoorG']
+            assert array.countBy { it.length() } == [6:2]
         '''
     }
-
-    void testInferenceForDGM_injectOnCollectionWithInitialValueDirect() {
-        assertScript '''import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
-            assert DGM.inject(['a','bb','ccc'],0) { acc, str -> acc += str.length(); acc } == 6
+    void testDGM_countByMap() {
+        assertScript '''
+            assert [langs:['Groovy','Java']].countBy { k,v -> k.length() } == [5:1]
+            assert [langs:['Groovy','Java']].countBy { e -> e.key.length() } == [5:1]
+            assert [langs:['Groovy','Java']].countBy { it.key.length() } == [5:1]
         '''
     }
 
-    void testInferenceForDGM_injectOnCollectionDirect() {
-        assertScript '''import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
-            assert DGM.inject(['a','bb','ccc']) { acc, str -> acc += str.toUpperCase(); acc } == 'aBBCCC'
+    void testDGM_downto() {
+        assertScript '''
+            BigDecimal sum = 0
+            10.0.downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
-    }
-
-    void testDGM_injectOnMap() {
         assertScript '''
-            assert [a:1,b:2].inject(0) { acc, entry -> acc += entry.value; acc} == 3
-            assert [a:1,b:2].inject(0) { acc, k, v -> acc += v; acc} == 3
+            BigInteger sum = 0
+            10G.downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
+        '''
+        assertScript '''
+            double sum = 0
+            10d.downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
+        '''
+        assertScript '''
+            Double sum = 0
+            new Double(10).downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
+        '''
+        assertScript '''
+            float sum = 0
+            10f.downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
+        '''
+        assertScript '''
+            Float sum = 0
+            new Float(10).downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
+        '''
+        assertScript '''
+            long sum = 0
+            10L.downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
+        '''
+        assertScript '''
+            Long sum = 0
+            new Long(10).downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
-    }
-
-    void testDGM_max() {
         assertScript '''
-            assert ['a','abc', 'defg','hi'].max { it.length() } == 'defg'
-            assert ['a','abc', 'defg','hi'].iterator().max { it.length() } == 'defg'
-            assert (['a','abc', 'defg','hi'] as String[]).max { it.length() } == 'defg'
+            def sum = 0
+            new Byte((byte)10).downto(0) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
     }
 
-    void testDGM_maxOnMap() {
+    void testDGM_upto() {
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { a,b -> a.value.length() <=> b.value.length() }
-            assert result.key == 'c'
-            assert result.value == 'defg'
+            BigDecimal sum = 0
+            0.0.upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { Map.Entry<String,String> a, Map.Entry<String,String> b -> a.value.length() <=> b.value.length() }
-            assert result.key == 'c'
-            assert result.value == 'defg'
+            BigInteger sum = 0
+            0G.upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { e -> e.value.length() }
-            assert result.key == 'c'
-            assert result.value == 'defg'
+            double sum = 0
+            0d.upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { it.value.length() }
-            assert result.key == 'c'
-            assert result.value == 'defg'
+            Double sum = 0
+            new Double(0).upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
-    }
-
-    void testDGM_min() {
         assertScript '''
-            assert ['a','abc', 'defg','hi'].min { it.length() } == 'a'
-            assert ['a','abc', 'defg','hi'].iterator().min { it.length() } == 'a'
-            assert (['a','abc', 'defg','hi'] as String[]).min { it.length() } == 'a'
+            float sum = 0
+            0f.upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
-    }
-
-    void testDGM_maxOnMin() {
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { a,b -> a.value.length() <=> b.value.length() }
-            assert result.key == 'a'
-            assert result.value == 'a'
+            Float sum = 0
+            new Float(0).upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { Map.Entry<String,String> a, Map.Entry<String,String> b -> a.value.length() <=> b.value.length() }
-            assert result.key == 'a'
-            assert result.value == 'a'
+            long sum = 0
+            0L.upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { e -> e.value.length() }
-            assert result.key == 'a'
-            assert result.value == 'a'
+            Long sum = 0
+            new Long(0).upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
         assertScript '''
-            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { it.value.length() }
-            assert result.key == 'a'
-            assert result.value == 'a'
+            def sum = 0
+            new Byte((byte)0).upto(10) {
+                sum += 2*it
+            }
+            assert sum == 110
         '''
     }
 
-    void testDGM_removeAllOnCollection() {
+    void testDGM_dropWhileOnIterable() {
         assertScript '''
-            def list = ['abc','a','groovy','java']
-            list.removeAll { it.length() <4 }
-            assert list == ['groovy','java']
+            assert (0..10).dropWhile { it<5 } == (5..10)
+            assert (0..10).dropWhile { int i -> i<5 } == (5..10)
         '''
     }
-    void testDGM_retainAllOnCollection() {
+
+    void testDGM_dropWhileOnList() {
         assertScript '''
-            def list = ['abc','a','groovy','java']
-            list.retainAll { it.length()>3 }
-            assert list == ['groovy','java']
+            assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { it<5 } == [5,6,7,8,9,10]
+            assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { int i -> i<5 } == [5,6,7,8,9,10]
         '''
     }
 
-    void testReverseEachOnList() {
+    void testDGM_dropWhileOnIterator() {
         assertScript '''
-            ['a','b'].reverseEach { println it.toUpperCase() }
+            assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
+            assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
         '''
     }
-    void testReverseEachOnArray() {
+
+    void testDGM_dropWhileOnArray() {
         assertScript '''
-            (['a','b'] as String[]).reverseEach { println it.toUpperCase() }
+            Integer[] array = [0,1,2,3,4,5,6,7,8,9,10]
+            assert array.iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
+            assert array.iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
         '''
     }
-    void testReverseEachOnMap() {
+
+    void testDGM_each() {
         assertScript '''
-            [a:1,b:2].reverseEach { k,v -> println ((k.toUpperCase())*v) }
-            [a:1,b:2].reverseEach { e -> println ((e.key.toUpperCase())*e.value) }
-            [a:1,b:2].reverseEach { println ((it.key.toUpperCase())*it.value) }
+            ['a','b'].each { it -> it.toUpperCase() }
         '''
-    }
-
-    void testDGM_sortOnCollection() {
         assertScript '''
-            assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { a,b -> a.length() <=> b.length() }
-            assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { str -> str.length() }
-            assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { it.length() }
+            ['a','b'].each { it.toUpperCase() }
         '''
     }
-    void testDGM_sortOnArray() {
+
+    void testDGM_eachByte() {
         assertScript '''
-            String[] array = ["hello","hi","hey"]
-            assert ["hi","hey","hello"] == array.sort { a,b -> a.length() <=> b.length() }
-            assert ["hi","hey","hello"] == array.sort { str -> str.length() }
-            assert ["hi","hey","hello"] == array.sort { it.length() }
+            byte[] array = new byte[0]
+            array.eachByte { byte b -> b.intValue() }
+            array.eachByte { it.intValue() }
         '''
-    }
-    void testDGM_sortOnIterator() {
         assertScript '''
-            assert ["hi","hey","hello"] == ["hello","hi","hey"].iterator().sort { a,b -> a.length() <=> b.length() }.collect()
-            assert ["hi","hey","hello"] == ["hello","hi","hey"].iterator().sort { str -> str.length() }.collect()
-            assert ["hi","hey","hello"] == ["hello","hi","hey"].iterator().sort { it.length() }.collect()
+            Byte[] array = new Byte[0]
+            array.eachByte { Byte b -> b.intValue() }
+            array.eachByte { it.intValue() }
         '''
     }
-    void testDGM_sortOnIterable() {
+
+    void testDGM_eachMatch() {
         assertScript '''
-            def foo(Iterable<String> iterable) {
-                assert ["hi","hey","hello"] == iterable.sort { a,b -> a.length() <=> b.length() }
-                assert ["hi","hey","hello"] == iterable.sort { str -> str.length() }
-                assert ["hi","hey","hello"] == iterable.sort { it.length() }
+            'foo bar baz'.eachMatch(~/(?m)^(\s*).*\n$/) { all, ws ->
+                all.trim(); ws.length()
             }
-            foo(["hello","hi","hey"])
         '''
     }
 
-    void testDGM_sortOnMap() {
+    void testDGM_eachWithIndexOnMap() {
         assertScript '''
-            def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }
-            assert map == [b:3, d:4, a:5, c:6]
+            [a:'A',bb:'B',ccc:'C'].eachWithIndex { e,i -> assert e.key.toUpperCase() == e.value*(1+i) }
+            [a:'A',bb:'B',ccc:'C'].eachWithIndex { k,v,i -> assert k.toUpperCase() == v*(1+i) }
+        '''
+    }
+    void testDGM_eachWithIndexOnObject() {
+        assertScript '''
+            def foo(object) {
+                object.eachWithIndex { Map<String,String> map, i -> map.ccc.toLowerCase() + (1+i) }
+                //                     ^^^^^^^^^^^^^^^^^^ each/eachWithIndex are flexible
+            }
+            foo([ [a:'A',bb:'B',ccc:'C'] ])
         '''
+    }
+    void testDGM_eachWithIndexOnIterable() {
         assertScript '''
-            def map = [a:5, b:3, c:6, d:4].sort { a -> a.value }
-            assert map == [b:3, d:4, a:5, c:6]
+            ['1','2','3'].eachWithIndex { e,i -> assert e.toUpperCase() == String.valueOf(1+i) }
         '''
+    }
+    void testDGM_eachWithIndexOnIterator() {
         assertScript '''
-            def map = [a:5, b:3, c:6, d:4].sort { it.value }
-            assert map == [b:3, d:4, a:5, c:6]
+            ['1','2','3'].iterator().eachWithIndex { e,i -> assert e.toUpperCase() == String.valueOf(1+i) }
         '''
     }
+    void testDGM_eachWithIndexOnRecursiveIterable() { // GROOVY-10651
+        ['', '<?>'].each { args ->
+            assertScript """
+                void proc(groovy.transform.stc.TreeNode$args node) {
+                    node.eachWithIndex { child, index ->
+                        proc(child) // recurse
+                    }
+                }
+            """
+        }
+    }
 
-    void testDGM_splitOnCollection() {
+    void testDGM_everyOnIterable() {
         assertScript '''
-            assert [1,2,3,4].split { it % 2 == 0 } == [[2,4],[1,3]]
+            assert ['foo','bar','baz'].every { String it -> it.length() == 3 }
+            assert ['foo','bar','baz'].every { it -> it.length() == 3 }
+            assert ['foo','bar','baz'].every { it.length() == 3 }
         '''
+    }
+    void testDGM_everyOnIterator() {
         assertScript '''
-            Collection items = ['foo','bar','baz']
-            assert items.split { it.startsWith('ba') } == [['bar', 'baz'], ['foo']]
+            assert ['foo','bar','baz'].iterator().every { String it -> it.length() == 3 }
+            assert ['foo','bar','baz'].iterator().every { it -> it.length() == 3 }
+            assert ['foo','bar','baz'].iterator().every { it.length() == 3 }
         '''
     }
-    void testDGM_splitOnArray() {
+    void testDGM_everyOnArray() {
         assertScript '''
             String[] items = ['foo','bar','baz']
-            assert items.split { it.startsWith('ba') } == [['bar', 'baz'], ['foo']]
+            assert items.every { it.length() == 3 }
+            assert items.every { String s -> s.length() == 3 }
         '''
     }
-
-    void testDGM_sum() {
+    void testDGM_everyOnMap() {
         assertScript '''
-            String[] items1 = ['foo','bar','baz']
-            assert items1.sum { it.toUpperCase() } == 'FOOBARBAZ'
-            def items2 = ['fi','fo','fum']
-            assert items2.sum('FEE') { it.toUpperCase() } == 'FEEFIFOFUM'
+            assert [a:'A',b:'B',cc:'CC'].every { String k, String v -> k == v.toLowerCase() }
+            assert [a:'A',b:'B',cc:'CC'].every { k, v -> k == v.toLowerCase() }
+            assert [a:'A',b:'B',cc:'CC'].every { e -> e.key == e.value.toLowerCase() }
+            assert [a:'A',b:'B',cc:'CC'].every { it.key == it.value.toLowerCase() }
         '''
     }
 
-    void testDGM_takeWhileOnIterable() {
+    void testDGM_findIndexOf() {
         assertScript '''
-            class AbcIterable implements Iterable<String>  {
-                Iterator<String>  iterator() { "abc".iterator() }
-            }
-            def abc = new AbcIterable()
-            assert abc.takeWhile{ it < 'b' } == ['a']
-            assert abc.takeWhile{ it <= 'b' } == ['a', 'b']
+            String[] items1 = ['foo','bar','baz']
+            assert items1.findIndexOf { it.startsWith('ba') == 1 }
+            assert items1.findIndexOf { String s -> s.startsWith('ba') == 1 }
+            def items2 = ['foo','bar','baz']
+            assert items2.findIndexOf { it.startsWith('ba') == 1 }
+            assert items2.iterator().findIndexOf { it.startsWith('ba') == 1 }
         '''
     }
-    void testDGM_takeWhileOnIterator() {
+
+    void testDGM_findLastIndexOf() {
         assertScript '''
-            class AbcIterable implements Iterable<String>  {
-                Iterator<String>  iterator() { "abc".iterator() }
-            }
-            def abc = new AbcIterable()
-            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
-            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+            String[] items1 = ['foo','bar','baz']
+            assert items1.findLastIndexOf { it.startsWith('ba') == 2 }
+            assert items1.findLastIndexOf { String s -> s.startsWith('ba') == 2 }
+            def items2 = ['foo','bar','baz']
+            assert items2.findLastIndexOf { it.startsWith('ba') == 2 }
+            assert items2.iterator().findLastIndexOf { it.startsWith('ba') == 2 }
         '''
     }
-    void testDGM_takeWhileOnList() {
+
+    void testDGM_findIndexValues() {
         assertScript '''
-            def abc = ['a','b','c']
-            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
-            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+            String[] items1 = ['foo','bar','baz']
+            assert items1.findIndexValues { it.startsWith('ba') } == [1, 2]
+            assert items1.findIndexValues { String s -> s.startsWith('ba') } == [1, 2]
+            def items2 = ['foo','bar','baz']
+            assert items2.findIndexValues { it.startsWith('ba') } == [1, 2]
+            assert items2.iterator().findIndexValues { it.startsWith('ba') } == [1, 2]
         '''
     }
-    void testDGM_takeWhileOnArray() {
+
+    void testDGM_findOnCollection() {
         assertScript '''
-            String[] abc = ['a','b','c']
-            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
-            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+            assert ['a','bbb','ccc'].find { String it -> it.length() == 3 } == 'bbb'
+            assert ['a','bbb','ccc'].find { it -> it.length() == 3 } == 'bbb'
+            assert ['a','bbb','ccc'].find { it.length() == 3 } == 'bbb'
         '''
     }
-    void testDGM_takeWhileOnMap() {
+    void testDGM_findOnArray() {
         assertScript '''
-            def shopping = [milk:1, bread:2, chocolate:3]
-            assert shopping.takeWhile{ it.key.size() < 6 } == [milk:1, bread:2]
-            assert shopping.takeWhile{ it.value % 2 } == [milk:1]
-            assert shopping.takeWhile{ k, v -> k.size() + v <= 7 } == [milk:1, bread:2]
+            String[] arraylistOfStrings = ['a','bbb','ccc']
+            assert arraylistOfStrings.find { String it -> it.length() == 3 } == 'bbb'
+            assert arraylistOfStrings.find { it -> it.length() == 3 } == 'bbb'
+            assert arraylistOfStrings.find { it.length() == 3 } == 'bbb'
         '''
     }
-
-    void testDGM_times() {
+    void testDGM_findOnMap() {
         assertScript '''
-            String foo(int x) { "x"*x }
-            10.times {
-                println foo(it)
-            }
+            assert [a:2,b:4,c:6].find { String k, int v -> k.toUpperCase()=='C' && 2*v==12 } instanceof Map.Entry
+            assert [a:2,b:4,c:6].find { k, v -> k.toUpperCase()=='C' && 2*v==12 } instanceof Map.Entry
+            assert [a:2,b:4,c:6].find { e -> e.key.toUpperCase()=='C' && 2*e.value==12 } instanceof Map.Entry
+            assert [a:2,b:4,c:6].find { it.key.toUpperCase()=='C' && 2*it.value==12 } instanceof Map.Entry
         '''
     }
-
-    void testDGM_unique() {
+    void testDGM_findOnStr() { // GROOVY-11076, GROOVY-11089
         assertScript '''
-            def orig = [1, 3, 4, 5]
-            def uniq = orig.unique(false) { it % 2 }
-            assert orig == [1, 3, 4, 5]
-            assert uniq == [1, 4]
+            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { List<String> all_zip_city -> all_zip_city*.toUpperCase() }
         '''
         assertScript '''
-            def orig = [2, 3, 3, 4]
-            def uniq = orig.unique(false) { a, b -> a <=> b }
-            assert orig == [2, 3, 3, 4]
-            assert uniq == [2, 3, 4]
+            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { String[] all_zip_city -> all_zip_city*.toUpperCase() }
         '''
-    }
-    void testDGM_uniqueOnCollection() {
         assertScript '''
-            def orig = [1, 3, 4, 5]
-            def uniq = orig.unique { it % 2 }
-            assert uniq == [1, 4]
+            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { Object[] all_zip_city -> all_zip_city*.toString() }
         '''
         assertScript '''
-            def orig = [2, 3, 3, 4]
-            def uniq = orig.unique { a, b -> a <=> b }
-            assert uniq == [2, 3, 4]
+            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { all, zip, city -> all.size() + zip.size() + city.size() }
         '''
-    }
-    void testDGM_uniqueOnIterator() {
         assertScript '''
-            def orig = [1, 3, 4, 5].iterator()
-            def uniq = orig.unique { it % 2 }.collect()
-            assert uniq == [1, 4]
+            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { String all, String zip, String city -> city + " " + zip }
         '''
         assertScript '''
-            def orig = [2, 3, 3, 4].iterator()
-            def uniq = orig.unique { a, b -> a <=> b }.collect()
-            assert uniq == [2, 3, 4]
+            "75001 Paris".find(~/\\d{5}/) { String zip -> zip }
         '''
+
+        shouldFailWithMessages '''
+            "75001 Paris".find(/(\\d{5})\\s(\\w+)/) { String all, Date zip, String city -> }
+        ''',
+        'Expected type java.lang.String for closure parameter: zip'
+
+        shouldFailWithMessages '''
+            "75001 Paris".find(~/\\d{5}/) { Number zip -> zip }
+        ''',
+        'Expected (java.util.List<java.lang.String>) or (java.lang.String) or (java.lang.String[]) but found (java.lang.Number)'
     }
 
-    void testDGM_withDefaultOnMap() {
+    void testDGM_findAllOnCollection() {
         assertScript '''
-            def map = [a:'A'].withDefault { it.toUpperCase() }
-            assert map.b=='B'
+            assert ['a','bbb','ccc'].findAll { String it -> it.length() == 3 } == ['bbb','ccc']
+            assert ['a','bbb','ccc'].findAll { it -> it.length() == 3 } == ['bbb','ccc']
+            assert ['a','bbb','ccc'].findAll { it.length() == 3 } == ['bbb','ccc']
         '''
     }
-
-    void testDGM_anyOnMap() {
+    void testDGM_findAllOnArray() {
         assertScript '''
-            assert [a:10, b:1].any { k,v -> k.length() == v }
-            assert [a:10, b:1].any { e -> e.key.length() == e.value }
-            assert [a:10, b:1].any {it.key.length() == it.value }
+            String[] arraylistOfStrings = ['a','bbb','ccc']
+            assert arraylistOfStrings.findAll { String it -> it.length() == 3 } == ['bbb','ccc']
+            assert arraylistOfStrings.findAll { it -> it.length() == 3 } == ['bbb','ccc']
+            assert arraylistOfStrings.findAll { it.length() == 3 } == ['bbb','ccc']
         '''
     }
-    void testDGM_anyOnIterable() {
+    void testDGM_findAllOnMap() {
         assertScript '''
-            assert ['abc','de','f'].any { it.length() == 2 }
+            assert [a:2,b:4,c:6].findAll { String k, int v -> k.toUpperCase()=='C' && 2*v==12 } == [c:6]
+            assert [a:2,b:4,c:6].findAll { k, v -> k.toUpperCase()=='C' && 2*v==12 } == [c:6]
+            assert [a:2,b:4,c:6].findAll { e -> e.key.toUpperCase()=='C' && 2*e.value==12 } == [c:6]
+            assert [a:2,b:4,c:6].findAll { it.key.toUpperCase()=='C' && 2*it.value==12 } == [c:6]
         '''
     }
-    void testDGM_anyOnIterator() {
+
+    void testDGM_findResultOnCollection() {
         assertScript '''
-            assert ['abc','de','f'].iterator().any { it.length() == 2 }
+            assert ['barbar','barbaz','foo'].findResult { it.length() == 3?it.toUpperCase():null } == 'FOO'
+            assert ['barbar','barbaz','foo'].findResult { String it -> it.length() == 3?it.toUpperCase():null } == 'FOO'
+            assert ['barbar','barbaz','foo'].findResult { it -> it.length() == 3?it.toUpperCase():null } == 'FOO'
+            assert ['barbar','barbaz','foo'].findResult(-1) { it.length() == 4?it.toUpperCase():null } == -1
+            assert ['barbar','barbaz','foo'].findResult(-1) { String it -> it.length() == 4?it.toUpperCase():null } == -1
+            assert ['barbar','barbaz','foo'].findResult(-1) { it -> it.length() == 4?it.toUpperCase():null } == -1
         '''
     }
-    void testDGM_anyOnArray() {
+    void testDGM_findResultOnIterable() {
         assertScript '''
-            String[] strings = ['abc','de','f']
-            assert strings.any { it.length() == 2 }
+            assert (0..10).findResult { it== 3?2*it:null } == 6
+            assert (0..10).findResult { int it -> it==3?2*it:null } == 6
+            assert (0..10).findResult { it -> it==3?2*it:null } == 6
         '''
     }
+    void testDGM_findResultOnMap() {
+        assertScript '''
+            assert [a:1, b:2, c:3].findResult { String k, int v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == 6
+            assert [a:1, b:2, c:3].findResult { k, v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == 6
+            assert [a:1, b:2, c:3].findResult { e -> "${e.key.toUpperCase()}$e.value"=='C3'?2*e.value:null } == 6
+            assert [a:1, b:2, c:3].findResult { "${it.key.toUpperCase()}$it.value"=='C3'?2*it.value:null } == 6
 
-    // GROOVY-6939
-    void testParamCountCheck1() {
-        shouldFailWithMessages '''
-            def m(o) {
-                o.each { x, y -> }
-            }
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 2'
-    }
-
-    // GROOVY-6939
-    void testParamCountCheck2() {
-        shouldFailWithMessages '''
-            def m(o) {
-                o.eachWithIndex { x, y, z -> }
-            }
-        ''',
-        'Incorrect number of parameters. Expected 2 but found 3'
+            assert [a:1, b:2, c:3].findResult('a') { String k, int v -> "${k.toUpperCase()}$v"=='C4'?2*v:null } == 'a'
+            assert [a:1, b:2, c:3].findResult('a') { k, v -> "${k.toUpperCase()}$v"=='C4'?2*v:null } == 'a'
+            assert [a:1, b:2, c:3].findResult('a') { e -> "${e.key.toUpperCase()}$e.value"=='C4'?2*e.value:null } == 'a'
+            assert [a:1, b:2, c:3].findResult('a') { "${it.key.toUpperCase()}$it.value"=='C4'?2*it.value:null } == 'a'
+        '''
     }
-
-    // GROOVY-6939
-    void testParamCountCheck3() {
-        shouldFailWithMessages '''
-            def m(o) {
-                o.eachWithIndex { print it }
-            }
-        ''',
-        'Incorrect number of parameters. Expected 2 but found 1'
+    void testDGM_findResult() {
+        assertScript '''
+            String[] items1 = ['foo','bar','baz']
+            assert items1.findResult { it.startsWith('ba') ? it : null } == 'bar'
+            def items2 = ['foo','bar','baz']
+            assert items2.findResult { it.startsWith('ba') ? it : null } == 'bar'
+            assert items2.iterator().findResult { it.startsWith('ba') ? it : null } == 'bar'
+        '''
     }
 
-    // GROOVY-6939
-    void testParamCountCheck4() {
-        shouldFailWithMessages '''
-            def m(... array) {
-                array.each { x, y -> }
-            }
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 2'
+    void testDGM_findResultsOnIterable() {
+        assertScript '''
+            assert (0..10).findResults { it<3?2*it:null } == [0,2,4]
+            assert (0..10).findResults { int it -> it<3?2*it:null } == [0,2,4]
+            assert (0..10).findResults { it -> it<3?2*it:null } == [0,2,4]
+        '''
     }
-
-    // GROOVY-6939
-    void testParamCountCheck5() {
-        shouldFailWithMessages '''
-            def m() {
-                [:].each { -> }
-            }
-        ''',
-        'Incorrect number of parameters. Expected 1 or 2 but found 0'
+    void testDGM_findResultsOnMap() {
+        assertScript '''
+            assert [a:1, b:2, c:3].findResults { String k, int v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == [6]
+            assert [a:1, b:2, c:3].findResults { k, v -> "${k.toUpperCase()}$v"=='C3'?2*v:null } == [6]
+            assert [a:1, b:2, c:3].findResults { e -> "${e.key.toUpperCase()}$e.value"=='C3'?2*e.value:null } == [6]
+            assert [a:1, b:2, c:3].findResults { "${it.key.toUpperCase()}$it.value"=='C3'?2*it.value:null } == [6]
+        '''
     }
-
-    // GROOVY-8499
-    void testParamCountCheck6() {
-        shouldFailWithMessages '''
-            ['ab'.chars,'12'.chars].combinations().stream().map((x, y) -> "$x$y")
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 2'
+    void testDGM_findResults() {
+        assertScript '''
+            String[] items1 = ['foo','bar','baz']
+            assert items1.findResults { it.startsWith('ba') ? it : null } == ['bar', 'baz']
+            def items2 = ['foo','bar','baz']
+            assert items2.findResults { it.startsWith('ba') ? it : null } == ['bar', 'baz']
+            assert items2.iterator().findResults { it.startsWith('ba') ? it : null } == ['bar', 'baz']
+        '''
     }
 
-    // GROOVY-8816
-    void testParamCountCheck7() {
-        shouldFailWithMessages '''
-            def m() {
-                [].each { -> }
-            }
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 0'
+    void testDGM_groupByIterable() {
+        assertScript '''
+            assert ['a','bb','cc','d','eee'].groupBy { it.length() } == [1:['a','d'],2:['bb','cc'],3:['eee']]
+        '''
     }
-
-    // GROOVY-9854
-    void testParamCountCheck8() {
-        shouldFailWithMessages '''
-            switch (42) { case { -> }: break; }
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 0'
+    void testDGM_groupByArray() {
+        assertScript '''
+            String[] array = ['a','bb','cc','d','eee']
+            assert array.groupBy { it.length() } == [1:['a','d'],2:['bb','cc'],3:['eee']]
+        '''
     }
-
-    // GROOVY-9854
-    void testParamCountCheck9() {
-        shouldFailWithMessages '''
-            switch (42) { case { i, j -> }: break; }
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 2'
+    void testDGM_groupByMap() {
+        assertScript '''
+            assert [a:'1',b:'2',c:'C'].groupBy { e -> e.key.toUpperCase()==e.value?1:0 } == [0:[a:'1',b:'2'], 1:[c:'C']]
+            assert [a:'1',b:'2',c:'C'].groupBy { k, v -> k.toUpperCase()==v?1:0 } == [0:[a:'1',b:'2'], 1:[c:'C']]
+            assert [a:'1',b:'2',c:'C'].groupBy { it.key.toUpperCase()==it.value?1:0 } == [0:[a:'1',b:'2'], 1:[c:'C']]
+        '''
     }
-
-    // GROOVY-11089
-    void testParamCountCheck10() {
-        shouldFailWithMessages '''
-            def array = new String[]{'a','b'}
-            array.with { a,b -> }
-        ''',
-        'Incorrect number of parameters. Expected 1 but found 2'
+    void testDGM_groupEntriesBy() {
+        assertScript '''
+            def result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { k,v -> v % 2 }
+            result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { it.value % 2 }
+            result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { e -> e.value % 2 }
+            assert result[0]*.key == ["b", "d", "f"]
+            assert result[1]*.value == [1, 3, 5]
+     '''
     }
-
-    // GROOVY-7141
-    void testInferenceWithSAMTypeCoercion1() {
-        String sam = '''
-            @FunctionalInterface
-            interface I {
-                String foo(String s)
-            }
-        '''
-        assertScript sam + '''
-            def impl = [foo: { it.toUpperCase() }] as I
-            String result = impl.foo('bar')
-            assert result == 'BAR'
-        '''
-        assertScript sam + '''
-            def impl = [foo: { s -> s.toUpperCase() }] as I
-            String result = impl.foo('bar')
-            assert result == 'BAR'
-        '''
-        assertScript sam + '''
-            def impl = [foo: { String s -> s.toUpperCase() }] as I
-            String result = impl.foo('bar')
-            assert result == 'BAR'
-        '''
+
+    void testDGM_injectOnCollectionWithInitialValue() {
         assertScript '''
-            def impl = [apply: { it.toUpperCase() }] as java.util.function.Function<String,String>
-            String result = impl.apply('bar')
-            assert result == 'BAR'
+            assert ['a','bb','ccc'].inject(0) { acc, str -> acc += str.length(); acc } == 6
         '''
     }
 
-    void testInferenceWithSAMTypeCoercion2() {
+    void testDGM_injectOnArrayWithInitialValue() {
         assertScript '''
-            interface Action<T> {
-                void execute(T thing)
-            }
-
-            class Wrapper<T> {
-                private final T thing
-                Wrapper(T thing) {
-                    this.thing = thing
-                }
-                void contravariantTake(Action<? super T> action) {
-                    action.execute(thing)
-                }
-                void invariantTake(Action<T> action) {
-                    action.execute(thing)
-                }
-            }
-
-            static <T> Wrapper<T> wrap(java.util.concurrent.Callable<T> callable) {
-                new Wrapper(callable.call())
-            }
-            static Integer dub(Integer integer) {
-                integer * 2
-            }
-
-            wrap {
-                1
-            } contravariantTake {
-                dub(it) // fails static compile, 'it' is not known to be Integer
-            }
-
-            wrap {
-                1
-            } invariantTake {
-                dub(it) // passes static compile, 'it' is known to be Integer
-            }
+            String[] array = ['a','bb','ccc']
+            assert array.inject(0) { acc, str -> acc += str.length(); acc } == 6
         '''
     }
 
-    //--------------------------------------------------------------------------
+    void testDGM_injectOnIteratorWithInitialValue() {
+        assertScript '''
+            assert ['a','bb','ccc'].iterator().inject(0) { acc, str -> acc += str.length(); acc } == 6
+        '''
+    }
 
-    void testGroovy6022() {
-        assertScript '''import groovy.transform.stc.SimpleType
-            class Item {
-                int x
-            }
+    void testDGM_injectOnCollection() {
+        assertScript '''
+            assert ['a','bb','ccc'].inject { acc, str -> acc += str.toUpperCase(); acc } == 'aBBCCC'
+        '''
+    }
 
-            void m(Item item, @ClosureParams(value=SimpleType, options="Item") Closure... closures) {
-                closures*.call(item)
-            }
+    void testDGM_injectOnArray() {
+        assertScript '''
+            String[] array = ['a','bb','ccc']
+            assert array.inject { acc, str -> acc += str.toUpperCase(); acc } == 'aBBCCC'
+        '''
+    }
 
-            m(new Item(), { item -> item.x }, { it.x })
+    void testDGM_injectOnCollectionWithInitialValueDirect() {
+        assertScript '''import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
+            assert DGM.inject(['a','bb','ccc'],0) { acc, str -> acc += str.length(); acc } == 6
         '''
     }
 
-    void testGroovy6602() {
-        shouldFailWithMessages '''import groovy.transform.stc.SimpleType
-            void foo(@ClosureParams(value=SimpleType, options="java.lang.Number") Closure c) {
-                c.call(4.5)
-            }
-            foo { Integer i -> println i }
-        ''',
-        'Expected type java.lang.Number for closure parameter: i'
+    void testDGM_injectOnCollectionDirect() {
+        assertScript '''import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
+            assert DGM.inject(['a','bb','ccc']) { acc, str -> acc += str.toUpperCase(); acc } == 'aBBCCC'
+        '''
     }
 
-    void testGroovy6603() {
-        shouldFailWithMessages '''import groovy.transform.stc.SimpleType
-            void foo(@ClosureParams(value=SimpleType, options="java.lang.Number") Closure c) {
-                c.call("x")
-            }
-        ''',
-        'Cannot call closure that accepts [java.lang.Number] with [java.lang.String]'
+    void testDGM_injectOnMap() {
+        assertScript '''
+            assert [a:1,b:2].inject(0) { acc, entry -> acc += entry.value; acc} == 3
+            assert [a:1,b:2].inject(0) { acc, k, v -> acc += v; acc} == 3
+        '''
     }
 
-    void testGroovy6729() {
-        assertScript '''import groovy.transform.stc.FirstParam
-            static <T> List<T> foo(List<T> list, @ClosureParams(FirstParam.FirstGenericType) Closure c) {
-                list.each {
-                    c.call(it)
-                }
-                return list
-            }
-            foo(["a","b","c"]) { s ->
-                s.toUpperCase() // Cannot find matching method java.lang.Object#toUpperCase()
-            }
+    void testDGM_max() {
+        assertScript '''
+            assert ['a','abc', 'defg','hi'].max { it.length() } == 'defg'
+            assert ['a','abc', 'defg','hi'].iterator().max { it.length() } == 'defg'
+            assert (['a','abc', 'defg','hi'] as String[]).max { it.length() } == 'defg'
         '''
     }
 
-    void testGroovy6735() {
+    void testDGM_maxOnMap() {
         assertScript '''
-            def extractInfo(String s) {
-              def squareNums = s.findAll(/\\d+/) { String num -> num.toInteger() }.collect{ Integer num -> num ** 2 }
-              def wordSizePlusNum = s.findAll(/\\s*(\\w+)\\s*(\\d+)/) { _, String word, String num -> word.size() + num.toInteger() }
-              def numPlusWordSize = s.findAll(/\\s*(\\w+)\\s*(\\d+)/) { _, word, num -> num.toInteger() + word.size() }
-              [squareNums, wordSizePlusNum, numPlusWordSize]
-            }
-            assert extractInfo(" ab 12 cdef 34 jhg ") == [[144, 1156], [14, 38], [14, 38]]
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { a,b -> a.value.length() <=> b.value.length() }
+            assert result.key == 'c'
+            assert result.value == 'defg'
         '''
         assertScript '''
-          assert "foobarbaz".findAll('b(a)([rz])') { full, a, b -> assert "BA"=="B" + a.toUpperCase() }.size() == 2
-          assert "foobarbaz".findAll('ba') { String found -> assert "BA" == found.toUpperCase() }.size() == 2
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { Map.Entry<String,String> a, Map.Entry<String,String> b -> a.value.length() <=> b.value.length() }
+            assert result.key == 'c'
+            assert result.value == 'defg'
+        '''
+        assertScript '''
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { e -> e.value.length() }
+            assert result.key == 'c'
+            assert result.value == 'defg'
+        '''
+        assertScript '''
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].max { it.value.length() }
+            assert result.key == 'c'
+            assert result.value == 'defg'
         '''
     }
 
-    void testGroovy9058() {
+    void testDGM_min() {
         assertScript '''
-            List<Object[]> table() {
-                [ ['fee', 'fi'] as Object[], ['fo', 'fum'] as Object[] ]
-            }
-
-            List<String> result = []
-            table().each { row -> result << row[0].toString().toUpperCase() }
-            assert result == ['FEE', 'FO']
+            assert ['a','abc', 'defg','hi'].min { it.length() } == 'a'
+            assert ['a','abc', 'defg','hi'].iterator().min { it.length() } == 'a'
+            assert (['a','abc', 'defg','hi'] as String[]).min { it.length() } == 'a'
         '''
     }
 
-    void testGroovy9518() {
+    void testDGM_maxOnMin() {
         assertScript '''
-            class C {
-                C(String s, Comparable<List<Integer>> c) {
-                }
-            }
-
-            new C('blah', { list -> list.get(0) })
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { a,b -> a.value.length() <=> b.value.length() }
+            assert result.key == 'a'
+            assert result.value == 'a'
+        '''
+        assertScript '''
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { Map.Entry<String,String> a, Map.Entry<String,String> b -> a.value.length() <=> b.value.length() }
+            assert result.key == 'a'
+            assert result.value == 'a'
+        '''
+        assertScript '''
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { e -> e.value.length() }
+            assert result.key == 'a'
+            assert result.value == 'a'
+        '''
+        assertScript '''
+            def result = [a:'a',b:'abc', c:'defg',d:'hi'].min { it.value.length() }
+            assert result.key == 'a'
+            assert result.value == 'a'
         '''
     }
 
-    void testGroovy9518a() {
+    void testDGM_removeAllOnCollection() {
         assertScript '''
-            class C {
-                C(String s, Comparable<List<Integer>> c) {
-                }
-            }
-
-            new C('blah', { it.get(0) })
+            def list = ['abc','a','groovy','java']
+            list.removeAll { it.length() <4 }
+            assert list == ['groovy','java']
         '''
     }
-
-    void testGroovy9518b() {
-        assertScript '''import groovy.transform.stc.FromString
-            class C {
-                C(String s, @ClosureParams(value=FromString,options="java.util.List<java.lang.Integer>") Closure<Integer> c) {
-                }
-            }
-
-            new C('blah', { list -> list.get(0) })
+    void testDGM_retainAllOnCollection() {
+        assertScript '''
+            def list = ['abc','a','groovy','java']
+            list.retainAll { it.length()>3 }
+            assert list == ['groovy','java']
         '''
     }
 
-    void testGroovy9570() {
+    void testReverseEachOnList() {
         assertScript '''
-            class C<I extends Item> {
-                Queue<I> queue
-
-                def c = { ->
-                    queue.each { I item ->
-                        println item
-                    }
-                }
+            ['a','b'].reverseEach { println it.toUpperCase() }
+        '''
+    }
+    void testReverseEachOnArray() {
+        assertScript '''
+            (['a','b'] as String[]).reverseEach { println it.toUpperCase() }
+        '''
+    }
+    void testReverseEachOnMap() {
+        assertScript '''
+            [a:1,b:2].reverseEach { k,v -> println ((k.toUpperCase())*v) }
+            [a:1,b:2].reverseEach { e -> println ((e.key.toUpperCase())*e.value) }
+            [a:1,b:2].reverseEach { println ((it.key.toUpperCase())*it.value) }
+        '''
+    }
 
-                def m() {
-                    queue.each { I item ->
-                        println item
-                    }
-                }
+    void testDGM_sortOnCollection() {
+        assertScript '''
+            assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { a,b -> a.length() <=> b.length() }
+            assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { str -> str.length() }
+            assert ["hi","hey","hello"] == ["hello","hi","hey"].sort { it.length() }
+        '''
+    }
+    void testDGM_sortOnArray() {
+        assertScript '''
+            String[] array = ["hello","hi","hey"]
+            assert ["hi","hey","hello"] == array.sort { a,b -> a.length() <=> b.length() }
+            assert ["hi","hey","hello"] == array.sort { str -> str.length() }
+            assert ["hi","hey","hello"] == array.sort { it.length() }
+        '''
+    }
+    void testDGM_sortOnIterator() {
+        assertScript '''
+            assert ["hi","hey","hello"] == ["hello","hi","hey"].iterator().sort { a,b -> a.length() <=> b.length() }.collect()
+            assert ["hi","hey","hello"] == ["hello","hi","hey"].iterator().sort { str -> str.length() }.collect()
+            assert ["hi","hey","hello"] == ["hello","hi","hey"].iterator().sort { it.length() }.collect()
+        '''
+    }
+    void testDGM_sortOnIterable() {
+        assertScript '''
+            def foo(Iterable<String> iterable) {
+                assert ["hi","hey","hello"] == iterable.sort { a,b -> a.length() <=> b.length() }
+                assert ["hi","hey","hello"] == iterable.sort { str -> str.length() }
+                assert ["hi","hey","hello"] == iterable.sort { it.length() }
             }
+            foo(["hello","hi","hey"])
+        '''
+    }
 
-            interface Item {}
-
-            new C()
+    void testDGM_sortOnMap() {
+        assertScript '''
+            def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }
+            assert map == [b:3, d:4, a:5, c:6]
+        '''
+        assertScript '''
+            def map = [a:5, b:3, c:6, d:4].sort { a -> a.value }
+            assert map == [b:3, d:4, a:5, c:6]
+        '''
+        assertScript '''
+            def map = [a:5, b:3, c:6, d:4].sort { it.value }
+            assert map == [b:3, d:4, a:5, c:6]
         '''
     }
 
-    void testGroovy9735() {
+    void testDGM_splitOnCollection() {
         assertScript '''
-            import groovy.transform.stc.FirstParam
-
-            class C<I extends Item> {
-                Queue<I> queue
-
-                def c = { ->
-                    x(queue) { I item ->
-                        println item
-                    }
-                }
-
-                def m() {
-                    x(queue) { I item ->
-                        println item
-                    }
-                }
-
-                def <T> T x(Collection<T> y, @ClosureParams(FirstParam.FirstGenericType) Closure z) {
-                }
-            }
-
-            interface Item {}
-
-            new C()
+            assert [1,2,3,4].split { it % 2 == 0 } == [[2,4],[1,3]]
+        '''
+        assertScript '''
+            Collection items = ['foo','bar','baz']
+            assert items.split { it.startsWith('ba') } == [['bar', 'baz'], ['foo']]
         '''
     }
-
-    void testGroovy9597a() {
+    void testDGM_splitOnArray() {
         assertScript '''
-            import groovy.transform.stc.FirstParam
-
-            class A {
-                def <T> void proc(Collection<T> values, @ClosureParams(FirstParam.FirstGenericType) Closure<String> block) {
-                }
-            }
-
-            class B {
-                List<Integer> list
-                void test(A a) {
-                    a.proc(this.list) { it.toBigDecimal().toString() } // works
-                    a.with {
-                      proc(this.list) { it.toBigDecimal().toString() } // error
-                    }
-                }
-            }
-
-            new B().test(new A())
+            String[] items = ['foo','bar','baz']
+            assert items.split { it.startsWith('ba') } == [['bar', 'baz'], ['foo']]
         '''
     }
 
-    void testGroovy9597b() {
+    void testDGM_sum() {
         assertScript '''
-            import groovy.transform.stc.FirstParam
-
-            class A {
-                static A of(@DelegatesTo(A) Closure x) {
-                    new A().tap {
-                        x.delegate = it
-                        x.call()
-                    }
-                }
-                def <T> void proc(Collection<T> values, @ClosureParams(FirstParam.FirstGenericType) Closure<String> block) {
-                }
-            }
-
-            class B {
-              List<Integer> list
-              A a = A.of {
-                  proc(
-                      this.list,
-                      { it.toBigDecimal().toString() } // Cannot find matching method java.lang.Object#toBigDecimal()
-                  )
-              }
-            }
-
-            new B()
+            String[] items1 = ['foo','bar','baz']
+            assert items1.sum { it.toUpperCase() } == 'FOOBARBAZ'
+            def items2 = ['fi','fo','fum']
+            assert items2.sum('FEE') { it.toUpperCase() } == 'FEEFIFOFUM'
         '''
     }
 
-    void testGroovy9854() {
+    void testDGM_takeWhileOnIterable() {
         assertScript '''
-            def result = switch (42) {
-                case { i -> i > 0 } -> 'positive'
-                case { it < 0 } -> 'negative'
-                default -> 'zero'
+            class AbcIterable implements Iterable<String>  {
+                Iterator<String>  iterator() { "abc".iterator() }
             }
-            assert result == 'positive'
+            def abc = new AbcIterable()
+            assert abc.takeWhile{ it < 'b' } == ['a']
+            assert abc.takeWhile{ it <= 'b' } == ['a', 'b']
         '''
-
-        shouldFailWithMessages '''
-            switch (42) { case { String s -> }: break; }
-        ''',
-        'Expected type java.lang.Integer for closure parameter: s'
     }
-
-    void testGroovy9968() {
+    void testDGM_takeWhileOnIterator() {
         assertScript '''
-            import groovy.transform.*
-            @Canonical class Pogo { String prop }
-            @Canonical class Type<T extends Pogo> implements Iterable<T> {
-                Iterator<T> iterator() {
-                    list.iterator()
-                }
-                List<T> list
+            class AbcIterable implements Iterable<String>  {
+                Iterator<String>  iterator() { "abc".iterator() }
             }
-
-            def iterable = new Type([new Pogo('x'), new Pogo('y'), new Pogo('z')])
-            assert iterable.collect { Pogo p -> p.prop } == ['x', 'y', 'z']
-            assert iterable.collect { it.prop } == ['x', 'y', 'z']
+            def abc = new AbcIterable()
+            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
         '''
     }
-
-    void testGroovy10180() {
+    void testDGM_takeWhileOnList() {
         assertScript '''
-            void test(args) {
-                if (args instanceof Map) {
-                    args.each { e ->
-                        def k = e.key, v = e.value
-                    }
-                }
-            }
+            def abc = ['a','b','c']
+            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
         '''
+    }
+    void testDGM_takeWhileOnArray() {
         assertScript '''
-            void test(args) {
-                if (args instanceof Map) {
-                    args.each { k, v ->
-                    }
-                }
-            }
+            String[] abc = ['a','b','c']
+            assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+            assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
         '''
     }
-
-    void testGroovy10660() {
-        assertScript '''import java.util.function.BiConsumer
-
-            <T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
-                // batch processor:
-                return { text, list ->
-                    for (item in list) proc.accept(text, item)
-                }
-            }
-
-            m { text, item -> }
+    void testDGM_takeWhileOnMap() {
+        assertScript '''
+            def shopping = [milk:1, bread:2, chocolate:3]
+            assert shopping.takeWhile{ it.key.size() < 6 } == [milk:1, bread:2]
+            assert shopping.takeWhile{ it.value % 2 } == [milk:1]
+            assert shopping.takeWhile{ k, v -> k.size() + v <= 7 } == [milk:1, bread:2]
         '''
+    }
 
-        assertScript '''import java.util.function.BiConsumer
-
-            <T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
-                // batch processor:
-                return (text, list) -> {
-                    for (item in list) proc.accept(text, item)
-                }
+    void testDGM_times() {
+        assertScript '''
+            String foo(int x) { "x"*x }
+            10.times {
+                println foo(it)
             }
-
-            m((text, item) -> { })
         '''
+    }
 
-        assertScript '''import java.util.function.BiConsumer
-
-            <T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
-                /*implicit return*/ (text, list) -> {
-                    for (item in list) proc.accept(text, item)
-                }
-            }
-
-            m((text, item) -> { })
+    void testDGM_unique() {
+        assertScript '''
+            def orig = [1, 3, 4, 5]
+            def uniq = orig.unique(false) { it % 2 }
+            assert orig == [1, 3, 4, 5]
+            assert uniq == [1, 4]
+        '''
+        assertScript '''
+            def orig = [2, 3, 3, 4]
+            def uniq = orig.unique(false) { a, b -> a <=> b }
+            assert orig == [2, 3, 3, 4]
+            assert uniq == [2, 3, 4]
         '''
     }
-
-    void testGroovy10673() {
-        assertScript '''import java.util.function.Consumer
-
-            void proc(Consumer<Number> action) {
-                action.accept(1.2345)
-            }
-
-            int i = 0
-            proc { n ->
-                def c = {
-                    i = n.intValue()
-                }
-                c()
-            }
-            assert i == 1
+    void testDGM_uniqueOnCollection() {
+        assertScript '''
+            def orig = [1, 3, 4, 5]
+            def uniq = orig.unique { it % 2 }
+            assert uniq == [1, 4]
+        '''
+        assertScript '''
+            def orig = [2, 3, 3, 4]
+            def uniq = orig.unique { a, b -> a <=> b }
+            assert uniq == [2, 3, 4]
+        '''
+    }
+    void testDGM_uniqueOnIterator() {
+        assertScript '''
+            def orig = [1, 3, 4, 5].iterator()
+            def uniq = orig.unique { it % 2 }.collect()
+            assert uniq == [1, 4]
+        '''
+        assertScript '''
+            def orig = [2, 3, 3, 4].iterator()
+            def uniq = orig.unique { a, b -> a <=> b }.collect()
+            assert uniq == [2, 3, 4]
         '''
     }
 
-    void testGroovy10756() {
-        assertScript """import ${Pogo10756.name.replace('$','.')}
-            Pogo10756.files.collect { it.name }
-            //                        ^^ File
-        """
-
-        assertScript """import ${Pogo10756.name.replace('$','.')}
-            def file = Pogo10756.files[0]
-            file?.name
-        """
+    void testDGM_with() {
+        assertScript '''
+            "string".with { it.toUpperCase() }
+        '''
+        assertScript '''
+            "string".with { str -> str.toUpperCase() }
+        '''
+        shouldFailWithMessages '''
+            12345678.with { xxx -> xxx.toUpperCase() }
+        ''',
+        'Cannot find matching method java.lang.Integer#toUpperCase()'
     }
 
-    static class Pogo10756 {
-        static <T extends File> Collection<T> getFiles() { [] }
+    void testDGM_withDefaultOnMap() {
+        assertScript '''
+            def map = [a:'A'].withDefault { it.toUpperCase() }
+            assert map.b=='B'
+        '''
     }
 }
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/ClosureParamTypeInferenceStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/ClosureParamTypeInferenceStaticCompileTest.groovy
index e16a515d12..64141ef44d 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/ClosureParamTypeInferenceStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/ClosureParamTypeInferenceStaticCompileTest.groovy
@@ -23,5 +23,5 @@ import groovy.transform.stc.ClosureParamTypeInferenceSTCTest
 /**
  * Unit tests for static compilation: closure parameter type inference.
  */
-class ClosureParamTypeInferenceStaticCompileTest extends ClosureParamTypeInferenceSTCTest  implements StaticCompilationTestSupport { }
-
+class ClosureParamTypeInferenceStaticCompileTest extends ClosureParamTypeInferenceSTCTest  implements StaticCompilationTestSupport {
+}