GROOVY-11051: convert closure's return value to the method's return type
diff --git a/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java b/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java
index ee118e6..194ee8b 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java
@@ -23,32 +23,37 @@
 import java.io.Serializable;
 import java.lang.reflect.Method;
 
+import static org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType;
+
 /**
  * This class is a general adapter to adapt a closure to any Java interface.
  */
 public class ConvertedClosure extends ConversionHandler implements Serializable {
-    private final String methodName;
+
     private static final long serialVersionUID = 1162833713450835227L;
 
+    private final String methodName;
+
     /**
-     * to create a ConvertedClosure object.
-     * @param closure the closure object.
+     * @throws IllegalArgumentException if closure is null
      */
-    public ConvertedClosure(Closure closure, String method) {
-        super(closure);
-        this.methodName = method;
+    public ConvertedClosure(final Closure closure) {
+        this(closure, null);
     }
 
-    public ConvertedClosure(Closure closure) {
-        this(closure,null);
+    /**
+     * @throws IllegalArgumentException if closure is null
+     */
+    public ConvertedClosure(final Closure closure, final String methodName) {
+        super(closure); this.methodName = methodName;
     }
 
     @Override
-    public Object invokeCustom(Object proxy, Method method, Object[] args)
-    throws Throwable {
-        if (methodName!=null && !methodName.equals(method.getName())) return null;
-        return ((Closure) getDelegate()).call(args);
+    public Object invokeCustom(final Object proxy, final Method method, final Object[] args) throws Throwable {
+        if (methodName != null && !methodName.equals(method.getName())) return null;
+        Object result = ((Closure)getDelegate()).call(args);
+        if (method.getReturnType()==void.class) return null;
+        result = castToType(result, method.getReturnType());
+        return result;
     }
-
 }
-
diff --git a/src/test-resources/groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy b/src/test-resources/groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy
index cc3b668..d243917 100644
--- a/src/test-resources/groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy
+++ b/src/test-resources/groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy
@@ -17,7 +17,7 @@
  *  under the License.
  */
 incompatibleAssignment { lhsType, rhsType, expr ->
-    if (lhsType == int_TYPE && rhsType==STRING_TYPE) {
+    if (lhsType == int_TYPE && rhsType == STRING_TYPE) {
         handled = true
     }
-}
\ No newline at end of file
+}
diff --git a/src/test-resources/groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy b/src/test-resources/groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy
index aa19504..0877efd 100644
--- a/src/test-resources/groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy
+++ b/src/test-resources/groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy
@@ -16,8 +16,8 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-incompatibleReturnType { returnStmt, inferredReturnType ->
-    if (inferredReturnType==STRING_TYPE) {
+incompatibleReturnType { returnStmt, returnType ->
+    if (returnType == BigDecimal_TYPE || returnType == STRING_TYPE) {
         handled = true
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
index a72e65b..f33eaef 100644
--- a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
@@ -37,16 +37,8 @@
         '''
     }
 
-    // GROOVY-9079
-    void testClosureWithoutArguments3() {
-        assertScript '''
-            java.util.concurrent.Callable<String> c = { -> return 'foo' }
-            assert c() == 'foo'
-        '''
-    }
-
     // GROOVY-10071
-    void testClosureWithoutArguments4() {
+    void testClosureWithoutArguments3() {
         assertScript '''
             def c = { ... zeroOrMore -> return 'foo' + zeroOrMore }
             assert c('bar', 'baz') == 'foo[bar, baz]'
@@ -56,7 +48,7 @@
     }
 
     // GROOVY-10072, GROOVY-11023
-    void testClosureWithoutArguments5() {
+    void testClosureWithoutArguments4() {
         assertScript '''
             def c = { p = 'foo' -> return p }
             assert c('bar') == 'bar'
@@ -70,7 +62,7 @@
     }
 
     // GROOVY-10636
-    void testClosureWithoutArguments6() {
+    void testClosureWithoutArguments5() {
         assertScript '''
             def f(Closure<Number>... closures) {
                 closures*.call().sum()
@@ -207,84 +199,53 @@
         'Cannot return value of type X for closure expecting A<java.lang.Number>'
     }
 
-    // GROOVY-10128, GROOVY-10306
+    // GROOVY-10792
     void testClosureReturnTypeInference8() {
-        assertScript '''
-            java.util.function.Function<String, Number> x = { s ->
-                long n = 1
-                return n
+        shouldFailWithMessages '''
+            void proc(Closure<Boolean> c) {
+                boolean result = c().booleanValue()
+                assert !result
             }
-            assert x.apply('') == 1L
-        '''
-        assertScript '''
-            class C {
-                byte p = 1
-                void m() {
-                    byte v = 2
-                    java.util.function.Supplier<Number> one = { -> p }
-                    java.util.function.Supplier<Number> two = { -> v }
-                    assert one.get() == (byte)1
-                    assert two.get() == (byte)2
-                }
+            def list = []
+            proc {
+                list
             }
-            new C().m()
-        '''
-    }
-
-    // GROOVY-8427
-    void testClosureReturnTypeInference9() {
-        assertScript '''
-            import java.util.function.Consumer
-
-            class C {
-                static <T> void m(T a, Consumer<T> c) {
-                    c.accept(a)
-                }
-                static void main(args) {
-                    def c = { ->
-                        int x = 0
-                        m('') {
-                            print 'void return'
-                        }
-                    }
-                    c.call()
-                }
-            }
-        '''
+        ''',
+        'Cannot return value of type java.util.ArrayList<java.lang.Object> for closure expecting java.lang.Boolean'
     }
 
     // GROOVY-8202
-    void testClosureReturnTypeInference10() {
+    void testClosureReturnTypeInference9() {
         assertScript '''
             void proc() {
             }
             String test0(flag) {
-              if (flag) {
-                'foo'
-              } else {
-                proc()
-              }
+                if (flag) {
+                    'foo'
+                } else {
+                    proc()
+                }
             }
             String test1(flag) {
-              Closure<String> c = { ->
-                if (flag) {
-                  'bar'
-                } else {
-                  proc()
-                  null
+                Closure<String> c = { ->
+                    if (flag) {
+                        'bar'
+                    } else {
+                        proc()
+                        null
+                    }
                 }
-              }
-              c.call()
+                c.call()
             }
             String test2(flag) {
-              Closure<String> c = { -> // Cannot assign Closure<Object> to Closure<String>
-                if (flag) {
-                  'baz'
-                } else {
-                  proc()
+                Closure<String> c = { -> // Cannot assign Closure<Object> to Closure<String>
+                    if (flag) {
+                        'baz'
+                    } else {
+                        proc()
+                    }
                 }
-              }
-              c.call()
+                c.call()
             }
 
             assert test0(true) == 'foo'
@@ -530,7 +491,7 @@
         '''
     }
 
-    // a case in Grails
+    // from Grails
     void testShouldNotThrowClosureSharedVariableError2() {
         assertScript '''
             class AntPathMatcher {
@@ -589,12 +550,8 @@
     // GROOVY-5705
     void testNPEWhenCallingClosureFromAField() {
         assertScript '''
-            import groovy.transform.*
-
             class Test {
                 Closure c = { it }
-
-                @TypeChecked
                 void test() {
                     c("123")
                 }
@@ -705,189 +662,6 @@
         }
     }
 
-    void testSAMType() {
-        assertScript '''
-            interface I { def m() }
-
-            @ASTTest(phase=INSTRUCTION_SELECTION, value={
-                assert node.getNodeMetaData(INFERRED_TYPE).name == 'I'
-            })
-            I i = { 1 }
-            assert i.m() == 1
-            def x = (I) { 2 }
-            assert x.m() == 2
-        '''
-
-        assertScript '''
-            interface I { int m() }
-            abstract class A implements I { }
-
-            I i = { 1 }
-            assert i.m() == 1
-            A a = { 2 }
-            assert a.m() == 2
-        '''
-
-        shouldFailWithMessages '''
-            interface I {
-                String toString()
-            }
-            I i = { p -> "" }
-        ''',
-        'Cannot assign'
-
-        shouldFailWithMessages '''
-            interface I {
-                String toString()
-            }
-            abstract class A implements I { }
-
-            A a = { "" } // implicit parameter
-        ''',
-        'Cannot assign'
-
-        assertScript '''
-            interface I { // non-functional, but every instance extends Object
-                boolean equals(Object)
-                int m()
-            }
-            I i = { 1 }
-            assert i.m() == 1
-        '''
-
-        shouldFailWithMessages '''
-            interface I {
-                boolean equals(Object)
-                int m()
-            }
-            abstract class A implements I { // no abstract methods
-                int m() { 1 }
-            }
-            A a = { 2 }
-        ''',
-        'Cannot assign'
-    }
-
-    // GROOVY-7927
-    void testSAMGenericsInAssignment() {
-        assertScript '''
-            interface SAM<T,R> { R accept(T t); }
-            SAM<Integer,Integer> s = { Integer n -> -n }
-            assert s.accept(1) == -1
-        '''
-    }
-
-    void testSAMProperty() {
-        assertScript '''
-            interface SAM { def foo(); }
-            class X {
-                SAM s
-            }
-            def x = new X(s:{1})
-            assert x.s.foo() == 1
-        '''
-    }
-
-    // GROOVY-7003
-    void testSAMProperty2() {
-        assertScript '''
-            import java.beans.*
-
-            class C {
-                static PropertyChangeListener listener = { PropertyChangeEvent event ->
-                    result = "${event.oldValue} -> ${event.newValue}"
-                }
-                public static result
-            }
-
-            def event = new PropertyChangeEvent(new Object(), 'foo', 'bar', 'baz')
-            C.getListener().propertyChange(event)
-            assert C.result == 'bar -> baz'
-        '''
-    }
-
-    void testSAMAttribute() {
-        assertScript '''
-            interface SAM { def foo(); }
-            class X {
-                public SAM s
-            }
-            def x = new X()
-            x.s = {1}
-            assert x.s.foo() == 1
-            x = new X()
-            x.@s = {2}
-            assert x.s.foo() == 2
-        '''
-    }
-
-    // GROOVY-10254
-    void testSAMReturnType() {
-        assertScript '''
-            interface SAM<T> { T get() }
-            SAM<Integer> foo() {
-                return { -> 42 }
-            }
-
-            def result = foo().get()
-            assert result == 42
-        '''
-    }
-
-    void testMultipleSAMSignature() {
-        assertScript '''
-            interface SAM { def foo() }
-            def method(SAM a, SAM b) {
-                a.foo()
-                b.foo()
-            }
-            method({println 'a'}, {println 'b'})
-        '''
-    }
-
-    void testMultipleSAMSignature2() {
-        assertScript '''
-            interface SAM { def foo() }
-            def method(Object o, SAM a, SAM b) {
-                a.foo()
-                b.foo()
-            }
-            method(new Object(), {println 'a'}, {println 'b'})
-        '''
-    }
-
-    void testMultipleSAMMethodWithClosure() {
-        assertScript '''
-            interface SAM { def foo() }
-            def method(SAM a, SAM b) {
-                a.foo()
-                b.foo()
-            }
-            def method(Closure a, SAM b) {
-                b.foo()
-            }
-            def called = false
-            method({called = true;println 'a'}, {println 'b'})
-            assert !called
-        '''
-    }
-
-    void testMultipleSAMMethodWithClosureInverted() {
-        assertScript '''
-            interface SAM { def foo() }
-            def method(SAM a, SAM b) {
-                a.foo()
-                b.foo()
-            }
-            def method(SAM a, Closure b) {
-                a.foo()
-            }
-            def called = false
-            method({println 'a'}, {called=true;println 'b'})
-            assert !called
-        '''
-    }
-
     // GROOVY-6238
     void testDirectMethodCallOnClosureExpression() {
         assertScript '''
@@ -962,20 +736,6 @@
         '''
     }
 
-    void testParameterlessClosureToSAMTypeArgumentCoercion() {
-        assertScript '''
-            interface SamType {
-                int sam()
-            }
-
-            int foo(SamType samt) {
-                samt.sam()
-            }
-
-            assert foo { -> 1 }  == 1
-        '''
-    }
-
     // GROOVY-9558
     void testPutAtClosureDelegateProperty() {
         assertScript '''
@@ -1047,26 +807,4 @@
         'Cannot assign value of type java.lang.Class<java.lang.Integer> to variable of type int',
         "named param 'bar' has type 'java.lang.Class<java.lang.Number>' but expected 'java.lang.Number'"
     }
-
-    // GROOVY-10905
-    void testImplicitArgClosureMatchesSamMethodWithOneArg() {
-        assertScript '''
-        def method1(java.util.function.IntUnaryOperator unary) { '1a' }
-        def method1(java.util.function.IntBinaryOperator binary) { '1b' }
-        assert method1{ x -> } == '1a'
-        assert method1{ x, y -> } == '1b'
-        assert method1{ } == '1a'
-        '''
-    }
-
-    // GROOVY-10905
-    void testImplicitArgClosureMatchesSamMethodWithZeroArgs() {
-        assertScript '''
-        def method2(java.util.function.IntSupplier supplier) { '2a' }
-        def method2(java.util.function.IntBinaryOperator binary) { '2b' }
-        assert method2{ -> } == '2a'
-        assert method2{ x, y -> } == '2b'
-        assert method2{ } == '2a'
-        '''
-    }
 }
diff --git a/src/test/groovy/transform/stc/CoercionSTCTest.groovy b/src/test/groovy/transform/stc/CoercionSTCTest.groovy
index 87ecdd8..b07cc01 100644
--- a/src/test/groovy/transform/stc/CoercionSTCTest.groovy
+++ b/src/test/groovy/transform/stc/CoercionSTCTest.groovy
@@ -18,11 +18,20 @@
  */
 package groovy.transform.stc
 
+import org.codehaus.groovy.control.customizers.ImportCustomizer
+
 /**
  * Unit tests for static type checking : coercions.
  */
 class CoercionSTCTest extends StaticTypeCheckingTestCase {
 
+    @Override
+    void configure() {
+        config.addCompilationCustomizers(
+            new ImportCustomizer().addStarImports('java.util.function')
+        )
+    }
+
     void testCoerceToArray() {
         assertScript '''
             try {
@@ -128,45 +137,216 @@
         '''
     }
 
+    void testCoerceToFunctionalInterface1() {
+        String sam = '@FunctionalInterface interface SAM { def foo() }'
+
+        assertScript sam + '''
+            def test(SAM a, SAM b) {
+                '' + a.foo() + b.foo()
+            }
+            String result = test({'a'}, {'b'})
+            assert result == 'ab'
+        '''
+
+        assertScript sam + '''
+            def test(Object o, SAM a, SAM b) {
+                '' + a.foo() + b.foo()
+            }
+            String result = test(new Object(), {'a'}, {'b'})
+            assert result == 'ab'
+        '''
+
+        assertScript sam + '''
+            def test(SAM a, SAM b) {
+                '' + a.foo() + b.foo()
+            }
+            def test(Closure a, SAM b) {
+                b.foo()
+            }
+            String result = test({'a'}, {'b'})
+            assert result == 'b'
+        '''
+
+        assertScript sam + '''
+            def test(SAM a, SAM b) {
+                '' + a.foo() + b.foo()
+            }
+            def test(SAM a, Closure b) {
+                a.foo()
+            }
+            String result = test({'a'}, {'b'})
+            assert result == 'a'
+        '''
+    }
+
+    // GROOVY-10254
+    void testCoerceToFunctionalInterface2() {
+        assertScript '''
+            @FunctionalInterface
+            interface SAM<T> { T get() }
+
+            SAM<Integer> foo() {
+                return { -> 42 }
+            }
+
+            def result = foo().get()
+            assert result == 42
+        '''
+    }
+
     // GROOVY-10277
-    void testCoerceToFunctionalInterface() {
-        assertScript '''import java.util.function.*
+    void testCoerceToFunctionalInterface3() {
+        assertScript '''
             Consumer<Number> c = { n -> }
             Supplier<Number> s = { -> 42 }
             Predicate<Number> p = { n -> 42 }
         '''
 
-        assertScript '''import java.util.function.*
+        assertScript '''
             def c = (Consumer<Number>) { n -> }
             def s = (Supplier<Number>) { -> 42 }
             def p = (Predicate<Number>) { n -> 42 }
         '''
 
-        assertScript '''import java.util.function.*
+        assertScript '''
             def c = { n -> } as Consumer<Number>
             def s = { -> 42 } as Supplier<Number>
             def p = { n -> 42 } as Predicate<Number>
         '''
 
-        shouldFailWithMessages '''import java.util.function.*
+        shouldFailWithMessages '''
             def s = (Supplier<Number>) { -> false }
         ''',
         'Cannot return value of type boolean for closure expecting java.lang.Number'
 
-        shouldFailWithMessages '''import java.util.function.*
+        shouldFailWithMessages '''
             def s = { -> false } as Supplier<Number>
         ''',
         'Cannot return value of type boolean for closure expecting java.lang.Number'
 
-        shouldFailWithMessages '''import java.util.function.*
+        shouldFailWithMessages '''
             def s = (() -> ['']) as Supplier<Number>
         ''',
         'Cannot return value of type java.util.ArrayList<java.lang.String> for lambda expecting java.lang.Number'
     }
 
+    void testCoerceToFunctionalInterface4() {
+        assertScript '''
+            interface I { def m() }
+
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE).name == 'I'
+            })
+            I i = { 1 }
+            assert i.m() == 1
+            def x = (I) { 2 }
+            assert x.m() == 2
+        '''
+
+        assertScript '''
+            interface I { int m() }
+            abstract class A implements I { }
+
+            I i = { 1 }
+            assert i.m() == 1
+            A a = { 2 }
+            assert a.m() == 2
+        '''
+
+        shouldFailWithMessages '''
+            interface I {
+                String toString()
+            }
+            I i = { p -> "" }
+        ''',
+        'Cannot assign'
+
+        shouldFailWithMessages '''
+            interface I {
+                String toString()
+            }
+            abstract class A implements I { }
+
+            A a = { "" } // implicit parameter
+        ''',
+        'Cannot assign'
+
+        assertScript '''
+            interface I { // non-functional, but every instance extends Object
+                boolean equals(Object)
+                int m()
+            }
+            I i = { 1 }
+            assert i.m() == 1
+        '''
+
+        shouldFailWithMessages '''
+            interface I {
+                boolean equals(Object)
+                int m()
+            }
+            abstract class A implements I { // no abstract methods
+                int m() { 1 }
+            }
+            A a = { 2 }
+        ''',
+        'Cannot assign'
+    }
+
+    // GROOVY-7927
+    void testCoerceToFunctionalInterface5() {
+        assertScript '''
+            interface SAM<T,R> { R accept(T t); }
+            SAM<Integer,Integer> s = { Integer n -> -n }
+            assert s.accept(1) == -1
+        '''
+    }
+
+    void testCoerceToFunctionalInterface6() {
+        assertScript '''
+            interface SAM { def foo(); }
+            class X {
+                public SAM s
+            }
+            def x = new X()
+            x.s = {1}
+            assert x.s.foo() == 1
+            x = new X()
+            x.@s = {2}
+            assert x.s.foo() == 2
+        '''
+    }
+
+    void testCoerceToFunctionalInterface7() {
+        assertScript '''
+            interface SAM { def foo(); }
+            class X {
+                SAM s
+            }
+            def x = new X(s:{1})
+            assert x.s.foo() == 1
+        '''
+    }
+
+    // GROOVY-7003
+    void testCoerceToFunctionalInterface8() {
+        assertScript '''import java.beans.*
+            class C {
+                static PropertyChangeListener listener = { PropertyChangeEvent event ->
+                    result = "${event.oldValue} -> ${event.newValue}"
+                }
+                public static result
+            }
+
+            def event = new PropertyChangeEvent(new Object(), 'foo', 'bar', 'baz')
+            C.getListener().propertyChange(event)
+            assert C.result == 'bar -> baz'
+        '''
+    }
+
     // GROOVY-8045
-    void testCoerceToFunctionalInterface2() {
-        assertScript '''import java.util.function.*
+    void testCoerceToFunctionalInterface9() {
+        assertScript '''
             def f(Supplier<Integer>... suppliers) {
                 suppliers*.get().sum()
             }
@@ -174,4 +354,116 @@
             assert result == 3
         '''
     }
+
+    // GROOVY-8168
+    void testCoerceToFunctionalInterface10() {
+        String sam = '''
+            @FunctionalInterface
+            interface Operation {
+                double calculate(int i)
+            }
+        '''
+
+        assertScript sam + '''
+            Operation operation = { return 1.0d }
+            def result = operation.calculate(2)
+            assert result == 1.0d
+        '''
+
+        shouldFailWithMessages sam + '''
+            Operation operation = { return 1.0; }
+        ''',
+        'Cannot return value of type java.math.BigDecimal for closure expecting double'
+    }
+
+    // GROOVY-8427
+    void testCoerceToFunctionalInterface11() {
+        assertScript '''
+            def <T> void m(T a, Consumer<T> c) {
+                c.accept(a)
+            }
+
+            def c = { ->
+                int x = 0
+                m('') {
+                    print 'void return'
+                }
+            }
+            c.call()
+        '''
+    }
+
+    // GROOVY-9079
+    void testCoerceToFunctionalInterface12() {
+        assertScript '''import java.util.concurrent.Callable
+            Callable<String> c = { -> return 'foo' }
+            assert c() == 'foo'
+        '''
+    }
+
+    // GROOVY-10128, GROOVY-10306
+    void testCoerceToFunctionalInterface13() {
+        assertScript '''
+            Function<String, Number> x = { s ->
+                long n = 1
+                return n
+            }
+            assert x.apply('') == 1L
+        '''
+
+        assertScript '''
+            class C {
+                byte p = 1
+                void m() {
+                    byte v = 2
+                    Supplier<Number> one = { -> p }
+                    Supplier<Number> two = { -> v }
+                    assert one.get() == (byte)1
+                    assert two.get() == (byte)2
+                }
+            }
+            new C().m()
+        '''
+    }
+
+    // GROOVY-10792
+    void testCoerceToFunctionalInterface14() {
+        assertScript '''
+            @Grab('org.awaitility:awaitility-groovy:4.2.0')
+            import static org.awaitility.Awaitility.await
+
+            List<String> strings = ['x']
+            await().until { -> strings }
+        '''
+    }
+
+    // GROOVY-10905
+    void testCoerceToFunctionalInterface15() {
+        assertScript '''
+            def method(IntUnaryOperator unary) { '1a' }
+            def method(IntBinaryOperator binary) { '1b' }
+
+            assert method{ x -> } == '1a'
+            assert method{ x, y -> } == '1b'
+            assert method{ } == '1a'
+        '''
+
+        assertScript '''
+            def method(IntSupplier supplier) { '2a' }
+            def method(IntBinaryOperator binary) { '2b' }
+
+            assert method{ -> } == '2a'
+            assert method{ x, y -> } == '2b'
+            assert method{ } == '2a'
+        '''
+    }
+
+    // GROOVY-11051
+    void testCoerceToFunctionalInterface16() {
+        assertScript '''import java.util.concurrent.atomic.AtomicReference
+            def opt = new AtomicReference<Object>(null)
+                .stream().filter { it.get() }.findAny()
+            assert opt.isEmpty()
+        '''
+    }
 }
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index 40bf98d..0d3eead 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -245,6 +245,17 @@
         '''
     }
 
+    @Test // class::instanceMethod -- GROOVY-11051
+    void testPredicateCI2() {
+        [['null','Empty'],['new Object()','Present']].each { value, which ->
+            assertScript """import java.util.concurrent.atomic.AtomicReference
+                def opt = new AtomicReference<Object>($value).stream()
+                             .filter(AtomicReference::get).findFirst()
+                assert opt.is${which}()
+            """
+        }
+    }
+
     @Test // class::instanceMethod -- GROOVY-10791
     void testBiConsumerCI() {
         assertScript shell, '''
diff --git a/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy b/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy
index 8c7b1ab..78088f6 100644
--- a/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy
+++ b/src/test/groovy/transform/stc/TypeCheckingExtensionsTest.groovy
@@ -323,21 +323,6 @@
         'Method [three] with matching argument found: [2, class java.util.Date]'
     }
 
-    void testIncompatibleAssignment() {
-        extension = null
-        shouldFailWithMessages '''
-            int x = 'foo'
-        ''',
-        'Cannot assign value of type java.lang.String to variable of type int'
-
-        extension = 'groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy'
-        assertScript '''
-            try {
-                int x = 'foo'
-            } catch (e) {}
-        '''
-    }
-
     void testBinaryOperatorNotFound() {
         extension = null
         shouldFailWithMessages '''
@@ -484,19 +469,53 @@
         }
     }
 
-    void testIncompatibleReturnType() {
-        extension = null
-        shouldFailWithMessages '''
-            Date foo() { '1' }
-            true
-        ''',
-        'Cannot return value of type'
+    void testIncompatibleAssignment() {
+        String source = '''
+            int x = 'x'
+            assert x == 120
+        '''
 
-        extension = 'groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy'
-        assertScript '''
+        extension = null
+        shouldFailWithMessages source,
+            'Cannot assign value of type java.lang.String to variable of type int'
+
+        extension = 'groovy/transform/stc/IncompatibleAssignmentTestExtension.groovy'
+        assertScript source
+    }
+
+    void testIncompatibleReturnType() {
+        String source = '''
             Date foo() { '1' }
             true
         '''
+
+        extension = null
+        shouldFailWithMessages source,
+            'Cannot return value of type java.lang.String for method returning java.util.Date'
+
+        extension = 'groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy'
+        assertScript source
+    }
+
+    // GROOVY-8168
+    void testIncompatibleReturnType2() {
+        String source = '''
+            @FunctionalInterface
+            interface Operation {
+                double calculate(int i)
+            }
+
+            Operation operation = { i -> return 1.0 }
+            def result = operation.calculate(2)
+            assert result == 1.0d
+        '''
+
+        extension = null
+        shouldFailWithMessages source,
+            'Cannot return value of type java.math.BigDecimal for closure expecting double'
+
+        extension = 'groovy/transform/stc/IncompatibleReturnTypeTestExtension.groovy'
+        assertScript source
     }
 
     void testPrecompiledExtension() {