GROOVY-11368: STC: store parameter inferred type, except self-type param
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 7d609f5..e7ef925 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -723,9 +723,8 @@
                 localVariable = (VariableExpression) accessedVariable;
             }
 
-            ClassNode inferredType = localVariable.getNodeMetaData(INFERRED_TYPE);
-            inferredType = getInferredTypeFromTempInfo(localVariable, inferredType);
-            if (inferredType != null && !isObjectType(inferredType) && !inferredType.equals(accessedVariable.getOriginType())) {
+            ClassNode inferredType = getInferredTypeFromTempInfo(localVariable, localVariable.getNodeMetaData(INFERRED_TYPE));
+            if (inferredType != null && !isObjectType(inferredType) && !inferredType.equals(isTraitSelf(vexp))) {
                 vexp.putNodeMetaData(INFERRED_TYPE, inferredType);
             }
         }
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index c3531e5..d478df1 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -19,6 +19,7 @@
 package groovy.transform.stc
 
 import groovy.transform.PackageScope
+import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
 
 /**
  * Unit tests for static type checking : fields and properties.
@@ -134,47 +135,44 @@
 
     void testInferenceFromFieldType() {
         assertScript '''
-            class A {
+            class C {
                 String name = 'Cedric'
             }
-            A a = new A()
-            def b = a.name
-            b.toUpperCase() // type of b should be inferred from field type
+            C c = new C()
+            def x = c.name
+            x.toUpperCase() // type of x should be inferred from field type
         '''
     }
 
     void testAssignFieldValueWithAttributeNotation() {
         assertScript '''
-            class A {
+            class C {
                 int x
             }
-
-            A a = new A()
-            a.@x = 1
+            C c = new C()
+            c.@x = 1
         '''
     }
 
     void testAssignFieldValueWithWrongTypeAndAttributeNotation() {
          shouldFailWithMessages '''
-             class A {
+             class C {
                  int x
              }
-
-             A a = new A()
-             a.@x = '1'
+             C c = new C()
+             c.@x = '1'
          ''',
          'Cannot assign value of type java.lang.String to variable of type int'
      }
 
     void testInferenceFromAttributeType() {
         assertScript '''
-            class A {
+            class C {
                 String name = 'Cedric'
             }
-
-            A a = new A()
-            def b = a.@name
-            b.toUpperCase() // type of b should be inferred from field type
+            C c = new C()
+            def x = c.@name
+            x.toUpperCase() // type of x should be inferred from field type
         '''
     }
 
@@ -188,61 +186,61 @@
 
     void testShouldComplainAboutMissingProperty2() {
         shouldFailWithMessages '''
-            class A {
+            class C {
             }
-            A a = new A()
-            a.x = 0
+            C c = new C()
+            c.x = 0
         ''',
-        'No such property: x for class: A'
+        'No such property: x for class: C'
     }
 
     // GROOVY-11319
     void testShouldComplainAboutMissingProperty3() {
         shouldFailWithMessages '''
-            class A {
+            class C {
                 private int getX() { 1 }
             }
-            class B extends A {
+            class D extends C {
                 void test() {
                     super.x
                 }
             }
-            new B().test()
+            new D().test()
         ''',
-        'No such property: x for class: A'
+        'No such property: x for class: C'
     }
 
     // GROOVY-11319
     void testShouldComplainAboutMissingProperty4() {
         shouldFailWithMessages '''
-            class A {
+            class C {
                 private void setX(int i) {
-                    assert false : 'no access'
+                    assert false : 'cannot access'
                 }
             }
-            class B extends A {
+            class D extends C {
                 void test() {
                     super.x = 1
                 }
             }
-            new B().test()
+            new D().test()
         ''',
-        'No such property: x for class: A'
+        'No such property: x for class: C'
     }
 
     void testShouldComplainAboutMissingProperty5() {
         shouldFailWithMessages '''
-            class A {
-                private int x
+            class C {
+                private x
             }
-            class B extends A {
+            class D extends C {
                 void test() {
                     this.x
                 }
             }
-            new B().test()
+            new D().test()
         ''',
-        'No such property: x for class: B'
+        'No such property: x for class: D'
     }
 
     void testShouldComplainAboutMissingAttribute() {
@@ -255,112 +253,109 @@
 
     void testShouldComplainAboutMissingAttribute2() {
         shouldFailWithMessages '''
-            class A {
+            class C {
             }
-            A a = new A()
-            a.@x = 0
+            C c = new C()
+            c.@x = 0
         ''',
-        'No such attribute: x for class: A'
+        'No such attribute: x for class: C'
     }
 
     void testShouldComplainAboutMissingAttribute3() {
         shouldFailWithMessages '''
-            class A {
+            class C {
                 def getX() { }
             }
-            A a = new A()
-            println a.@x
+            C c = new C()
+            println c.@x
         ''',
-        'No such attribute: x for class: A'
+        'No such attribute: x for class: C'
     }
 
     void testShouldComplainAboutMissingAttribute4() {
         shouldFailWithMessages '''
-            class A {
+            class C {
                 def setX(x) { }
             }
-            A a = new A()
-            a.@x = 0
+            C c = new C()
+            c.@x = 0
         ''',
-        'No such attribute: x for class: A'
+        'No such attribute: x for class: C'
     }
 
     void testShouldComplainAboutMissingAttribute5() {
         shouldFailWithMessages '''
-            class A {
+            class C {
                 private x
             }
-            class B extends A {
+            class D extends C {
                 void test() {
                     this.@x
                 }
             }
-            new B().test()
+            new D().test()
         ''',
-        'Cannot access field: x of class: A'
+        'Cannot access field: x of class: C'
     }
 
     void testPropertyWithInheritance() {
         assertScript '''
-            class A {
+            class C {
                 int x
             }
-            class B extends A {
+            class D extends C {
             }
-
-            B b = new B()
-            assert b.x == 0
-
-            b.x = 2
-            assert b.x == 2
+            D d = new D()
+            assert d.x == 0
+            d.x = 2
+            assert d.x == 2
         '''
     }
 
     void testPropertyTypeWithInheritance() {
         shouldFailWithMessages '''
-            class A {
+            class C {
                 int x
             }
-            class B extends A {
+            class D extends C {
             }
-            B b = new B()
-            b.x = '2'
+            D d = new D()
+            d.x = '2'
         ''',
         'Cannot assign value of type java.lang.String to variable of type int'
     }
 
     void testPropertyWithInheritanceFromAnotherSourceUnit() {
         assertScript '''
-            class B extends groovy.transform.stc.FieldsAndPropertiesSTCTest.BaseClass {
+            class C extends groovy.transform.stc.FieldsAndPropertiesSTCTest.BaseClass {
             }
-            B b = new B()
-            b.x = 2
+            C c = new C()
+            c.x = 2
         '''
     }
 
     void testPropertyWithInheritanceFromAnotherSourceUnit2() {
         shouldFailWithMessages '''
-            class B extends groovy.transform.stc.FieldsAndPropertiesSTCTest.BaseClass {
+            class C extends groovy.transform.stc.FieldsAndPropertiesSTCTest.BaseClass {
             }
-            B b = new B()
-            b.x = '2'
+            C c = new C()
+            c.x = '2'
         ''',
         'Cannot assign value of type java.lang.String to variable of type int'
     }
 
     void testPropertyWithSuperInheritanceFromAnotherSourceUnit() {
         assertScript '''
-            class B extends groovy.transform.stc.FieldsAndPropertiesSTCTest.BaseClass2 {
+            class C extends groovy.transform.stc.FieldsAndPropertiesSTCTest.BaseClass2 {
             }
-            B b = new B()
-            b.x = 2
+            C c = new C()
+            c.x = 2
         '''
     }
 
     // GROOVY-9955
     void testStaticPropertyWithInheritanceFromAnotherSourceUnit() {
-        assertScript '''
-            import groovy.transform.stc.FieldsAndPropertiesSTCTest.Public
+        assertScript """import ${Public.canonicalName}
             assert Public.answer == 42
             assert Public.CONST == 'XX'
             assert Public.VALUE == null
@@ -369,7 +364,7 @@
             Public.@VALUE = 'ZZ'
             assert Public.@VALUE == 'ZZ'
             Public.VALUE = null
-        '''
+        """
     }
 
     // GROOVY-10695
@@ -403,7 +398,6 @@
             class C {
                 String p
             }
-
             def x = new C().getP()
             x = x?.toUpperCase()
         '''
@@ -426,7 +420,6 @@
                         }
                     }
                 }
-
                 String which = new C().m()
                 assert which == 'PROPERTY'
             """
@@ -442,13 +435,48 @@
                 Integer m() { 123456 - p }
                 Integer m(int i) { i - p }
             }
-
             def c = new C()
             assert c.m() == 123456 // BUG! exception in phase 'class generation' ...
             assert c.m(123) == 123 // ClassCastException: class org.codehaus.groovy.ast.Parameter cannot be cast to ...
         '''
     }
 
+    // GROOVY-11005
+    void testGetterForProperty4() {
+        File parentDir = File.createTempDir()
+        config.with {
+            targetDirectory = File.createTempDir()
+            jointCompilationOptions = [memStub: true]
+        }
+        try {
+            def a = new File(parentDir, 'Pogo.groovy')
+            a.write '''
+                class Pogo {
+                    String value
+                    String getValue() { value }
+                }
+            '''
+            def b = new File(parentDir, 'Test.groovy')
+            b.write '''
+                class Test extends Pogo {
+                    void test() {
+                        value = 'string'
+                    }
+                }
+            '''
+
+            def loader = new GroovyClassLoader(this.class.classLoader)
+            def cu = new JavaAwareCompilationUnit(config, loader)
+            cu.addSources(a, b)
+            cu.compile()
+
+            loader.loadClass('Test').newInstance().test()
+        } finally {
+            parentDir.deleteDir()
+            config.targetDirectory.deleteDir()
+        }
+    }
+
     // GROOVY-5232
     void testSetterForProperty() {
         assertScript '''
@@ -461,7 +489,6 @@
                     return p
                 }
             }
-
             Person.create()
         '''
     }
@@ -469,35 +496,35 @@
     // GROOVY-5443
     void testFieldInitShouldPass() {
         assertScript '''
-            class Foo {
+            class C {
                 int bar = 1
             }
-            new Foo()
+            new C()
         '''
     }
 
     // GROOVY-5443
     void testFieldInitShouldNotPassBecauseOfIncompatibleTypes() {
         shouldFailWithMessages '''
-            class Foo {
+            class C {
                 int bar = new Date()
             }
-            new Foo()
+            new C()
         ''',
         'Cannot assign value of type java.util.Date to variable of type int'
     }
 
     // GROOVY-5443, GROOVY-10277
-    void testFieldInitShouldNotPassBecauseOfIncompatibleTypesWithClosure1() {
+    void testFieldInitShouldNotPassBecauseOfIncompatibleTypesWithClosure() {
         shouldFailWithMessages '''
-            class Foo {
+            class C {
                 Closure<List> bar = { Date date -> date.getTime() }
             }
         ''',
         'Cannot return value of type long for closure expecting java.util.List'
 
         shouldFailWithMessages '''
-            class Foo {
+            class C {
                 java.util.function.Supplier<String> bar = { -> 123 }
             }
         ''',
@@ -507,48 +534,29 @@
     // GROOVY-9882
     void testFieldInitShouldPassForCompatibleTypesWithClosure() {
         assertScript '''
-            class Foo {
+            class C {
                 java.util.function.Supplier<String> bar = { 'abc' }
             }
-            assert new Foo().bar.get() == 'abc'
+            assert new C().bar.get() == 'abc'
         '''
     }
 
     void testClosureParameterMismatch() {
         shouldFailWithMessages '''
-            class Foo {
+            class C {
                 java.util.function.Supplier<String> bar = { baz -> '' }
             }
         ''',
         'Wrong number of parameters for method target: get()'
 
         shouldFailWithMessages '''
-            class Foo {
+            class C {
                 java.util.function.Consumer<String> bar = { -> null }
             }
         ''',
         'Wrong number of parameters for method target: accept(java.lang.String)'
     }
 
-    void testListDotProperty() {
-        assertScript '''class Elem { int value }
-            List<Elem> list = new LinkedList<Elem>()
-            list.add(new Elem(value:123))
-            list.add(new Elem(value:456))
-            assert list.value == [ 123, 456 ]
-            list.add(new Elem(value:789))
-            assert list.value == [ 123, 456, 789 ]
-        '''
-        assertScript '''class Elem { String value }
-            List<Elem> list = new LinkedList<Elem>()
-            list.add(new Elem(value:'123'))
-            list.add(new Elem(value:'456'))
-            assert list.value == [ '123', '456' ]
-            list.add(new Elem(value:'789'))
-            assert list.value == [ '123', '456', '789' ]
-        '''
-    }
-
     // GROOVY-5585
     void testClassPropertyOnInterface() {
         assertScript '''
@@ -569,138 +577,50 @@
 
     void testSetterUsingPropertyNotation() {
         assertScript '''
-            class A {
-                boolean ok = false;
-                void setFoo(String foo) { ok = foo == 'foo' }
+            class C {
+                boolean ok = false
+                void setFoo(String foo) { ok = (foo == 'foo') }
             }
-            def a = new A()
-            a.foo = 'foo'
-            assert a.ok
+            def c = new C()
+            c.foo = 'foo'
+            assert c.ok
         '''
     }
 
     void testSetterUsingPropertyNotationOnInterface() {
         assertScript '''
             interface FooAware { void setFoo(String arg) }
-            class A implements FooAware {
+            class C implements FooAware {
                 void setFoo(String foo) { }
             }
-            void test(FooAware a) {
-                a.foo = 'foo'
+            void test(FooAware fa) {
+                fa.foo = 'foo'
             }
-            def a = new A()
-            test(a)
+            def c = new C()
+            test(c)
         '''
     }
 
-    // GROOVY-5001, GROOVY-5491, GROOVY-6144, GROOVY-8788
-    void testMapProperties1() {
-        assertScript '''
-            class A { }
-            class B { }
-            class HM extends HashMap<String,A> {
-                B b = new B()
-            }
-
-            def map = new HM()
-            map.put('a', new A())
-            assert map.get('a') != null
-            assert map.get('b') == null
-
-            A a = map.a
-            B b = map.b
-            a = map['a']
-            b = map['b']
-            assert a instanceof A
-            assert b instanceof B
+    void testListDotProperty1() {
+        assertScript '''class Elem { int value }
+            List<Elem> list = new LinkedList<Elem>()
+            list.add(new Elem(value:123))
+            list.add(new Elem(value:456))
+            assert list.value == [ 123, 456 ]
+            list.add(new Elem(value:789))
+            assert list.value == [ 123, 456, 789 ]
+        '''
+        assertScript '''class Elem { String value }
+            List<Elem> list = new LinkedList<Elem>()
+            list.add(new Elem(value:'123'))
+            list.add(new Elem(value:'456'))
+            assert list.value == [ '123', '456' ]
+            list.add(new Elem(value:'789'))
+            assert list.value == [ '123', '456', '789' ]
         '''
     }
 
-    // GROOVY-5517
-    void testMapProperties2() {
-        assertScript '''
-            @groovy.transform.stc.POJO
-            @groovy.transform.CompileStatic
-            class MyHashMap extends HashMap {
-                public static int version = 666
-            }
-            def map = new MyHashMap()
-            map.foo = 123
-            def value = map.foo
-            assert value == 123
-            map['foo'] = 4.5
-            value = map['foo']
-            assert value == 4.5
-            value = map.version
-            assert value == 666
-        '''
-    }
-
-    // GROOVY-5797
-    void testMapProperties3() {
-        assertScript '''
-            def m(Map foo) {
-                def map = [baz: 1]
-                map[ foo.bar ]
-            }
-            assert m(bar:'baz') == 1
-        '''
-    }
-
-    void testMapProperties4() {
-        assertScript '''
-            def map = [:]
-            map['a'] = 1
-            map.b = 2
-            assert map.get('a') == 1
-            assert map.get('b') == 2
-        '''
-    }
-
-    void testMapProperties5() {
-        assertScript '''
-            Map map = [a: 1, b:2]
-            String key = 'b'
-            assert map['a'] == 1
-            assert map[key] == 2
-        '''
-    }
-
-    void testMapProperties6() {
-        assertScript '''
-            class Foo {
-                public static Map CLASSES = [key:'value']
-            }
-            String name = 'key'
-            assert Foo.CLASSES[name] == 'value'
-        '''
-    }
-
-    // GROOVY-5700, GROOVY-8788
-    void testInferenceOfMapSubProperty() {
-        assertScript '''
-            def map = [key: 123]
-            @ASTTest(phase=INSTRUCTION_SELECTION, value={
-                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
-            })
-            def val = map['key']
-            assert val == 123
-        '''
-    }
-
-    // GROOVY-5700
-    void testInferenceOfMapDotProperty() {
-        assertScript '''
-            def map = [key: 123]
-            @ASTTest(phase=INSTRUCTION_SELECTION, value={
-                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
-            })
-            def val = map.key
-            assert val == 123
-        '''
-    }
-
-    void testInferenceOfListDotProperty() {
+    void testListDotProperty2() {
         assertScript '''
             class C { int x }
             def list = [new C(x:1), new C(x:2)]
@@ -713,29 +633,194 @@
         '''
     }
 
+    // GROOVY-5700
+    void testMapPropertyAccess1() {
+        assertScript '''
+            def map = [key: 123]
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
+            })
+            def val = map.key
+            assert val == 123
+        '''
+    }
+
+    // GROOVY-8788
+    void testMapPropertyAccess2() {
+        assertScript '''
+            def map = [key: 123]
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
+            })
+            def val = map['key']
+            assert val == 123
+        '''
+    }
+
+    // GROOVY-5988
+    void testMapPropertyAccess3() {
+        assertScript '''
+            String key = 'name'
+            Map<String, Integer> map = [:]
+            map[key] = 123
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                assert node.getNodeMetaData(INFERRED_TYPE) == Integer_TYPE
+            })
+            def val = map[key]
+            assert val == 123
+        '''
+    }
+
+    // GROOVY-5797
+    void testMapPropertyAccess4() {
+        assertScript '''
+            def test(Map foo) {
+                def map = [baz: 1]
+                map[ foo.bar ]
+            }
+            assert test(bar:'baz') == 1
+        '''
+    }
+
+    // GROOVY-8074
+    void testMapPropertyAccess6() {
+        assertScript '''
+            class C extends HashMap {
+                def foo = 1
+            }
+            def map = new C()
+            map.put('foo', 11)
+            assert map.foo == 1
+            assert map['foo'] == 1
+        '''
+        assertScript """
+            def map = new ${MapType.name}()
+            map.put('foo', 11)
+            assert map.foo == 1
+            assert map['foo'] == 1
+            map.put('bar', 22)
+            assert map.bar == 22
+            assert map['bar'] == 22
+            map.put('baz', 33)
+            assert map.baz == 33
+            assert map['baz'] == 33
+        """
+    }
+
+    // GROOVY-5001, GROOVY-5491, GROOVY-6144
+    void testMapPropertyAccess7() {
+        String types = '''
+            class A { }
+            class B { }
+            class C extends HashMap<String,A> {
+                B b = new B()
+            }
+        '''
+        assertScript types + '''
+            def map = new C()
+            map.put('a', new A())
+            assert map.get('a') != null
+            assert map.get('b') == null
+            A a = map.a
+            B b = map.b
+            a = map['a']
+            b = map['b']
+            assert a instanceof A
+            assert b instanceof B
+        '''
+        assertScript types + '''
+            def test(C map) {
+                A a = map.a
+                B b = map.b
+                a = map['a']
+                b = map['b']
+                assert a instanceof A
+                assert b instanceof B
+            }
+            test(new C().tap{ put('a', new A()) })
+        '''
+    }
+
+    // GROOVY-5517
+    void testMapPropertyAccess8() {
+        String type = '''
+            @groovy.transform.stc.POJO
+            @groovy.transform.CompileStatic
+            class C extends HashMap {
+                public static int version = 666
+            }
+        '''
+        assertScript type + '''
+            def map = new C()
+            map.foo = 123
+            def value = map.foo
+            assert value == 123
+            map['foo'] = 4.5
+            value = map['foo']
+            assert value == 4.5
+            value = map.version
+            assert value == 666
+        '''
+        assertScript type + '''
+            def test(C map) {
+                map.foo = 123
+                def value = map.foo
+                assert value == 123
+                map['foo'] = 4.5
+                value = map['foo']
+                assert value == 4.5
+                value = map.version
+                assert value == 666
+            }
+            test(new C())
+        '''
+    }
+
+    // GROOVY-11368
+    void testMapPropertyAccess9() {
+        String type = '''
+            class C implements Map<String,String> {
+                @Delegate Map<String,String> impl = [:]
+            }
+        '''
+        assertScript type + '''
+            def map = new C()
+            assert map.entry == null
+            assert map.empty == null
+            assert map.class == null
+            assert map.metaClass == null
+        '''
+        assertScript type + '''
+            def test(C map) { // no diff
+                assert map.entry == null
+                assert map.empty == null
+                assert map.class == null
+                assert map.metaClass == null
+            }
+            test(new C())
+        '''
+    }
+
     void testTypeCheckerDoesNotThinkPropertyIsReadOnly() {
         assertScript '''
             // a base class defining a read-only property
-            class Top {
+            class C {
                 private String foo = 'foo'
                 String getFoo() { foo }
-                String getFooFromTop() { foo }
+                String getFooFromC() { foo }
             }
 
             // a subclass defining its own field
-            class Bottom extends Top {
-                private String foo
-
-                Bottom(String msg) {
+            class D extends C {
+                D(String msg) {
                     this.foo = msg
                 }
-
-                public String getFoo() { this.foo }
+                private String foo
+                public  String getFoo() { this.foo }
             }
-
-            def b = new Bottom('bar')
-            assert b.foo == 'bar'
-            assert b.fooFromTop == 'foo'
+            def d = new D('bar')
+            assert d.foo == 'bar'
+            assert d.fooFromC == 'foo'
         '''
     }
 
@@ -749,11 +834,12 @@
     // GROOVY-5725
     void testAccessFieldDefinedInInterface() {
         assertScript '''
-            class Foo implements groovy.transform.stc.FieldsAndPropertiesSTCTest.InterfaceWithField {
-                static main(args) {
+            class C implements groovy.transform.stc.FieldsAndPropertiesSTCTest.InterfaceWithField {
+                void test() {
                     assert boo == "I don't fancy fields in interfaces"
                 }
             }
+            new C().test()
         '''
     }
 
@@ -767,7 +853,6 @@
                 }
                 def p = 1
             }
-
             def i = new Outer.Inner(new Outer())
             def x = i.m()
             assert x == 1
@@ -784,7 +869,6 @@
                 }
                 def p = 1
             }
-
             def i = new Outer.Inner(new Outer())
             def x = i.m()
             assert x == 1
@@ -803,7 +887,6 @@
                 }
                 def p = 1
             }
-
             def i = new Outer.Inner(new Outer())
             def x = i.m()
             assert x == 2
@@ -818,7 +901,6 @@
                 }
                 def p = 1
             }
-
             def i = new Outer.Inner(new Outer())
             def x = i.p
         ''',
@@ -833,7 +915,6 @@
                 }
                 def p = 1
             }
-
             def i = new Outer.Inner(new Outer())
             def x = i.getP()
         ''',
@@ -881,8 +962,7 @@
                     }
                 }
             }
-
-            def in = Outer.Inner.FOO
+            def foo = Outer.Inner.FOO
             assert Outer.props == [bar: 10, baz: 20, foo: 30]
         '''
     }
@@ -899,7 +979,6 @@
                     }
                 }
             }
-
             assert Outer.Inner.CONST.value == 2
         '''
     }
@@ -913,7 +992,6 @@
                 String p = 'field'
                 String getP() { 'property' }
             }
-
             String which = new Outer.Inner(new Outer()).m()
             assert which == 'property'
         '''
@@ -929,7 +1007,6 @@
                 String p = 'field'
                 String getP() { 'property' }
             }
-
             String which = new Outer.Inner(new Outer()).m()
             assert which == 'method'
         '''
@@ -954,7 +1031,6 @@
                         }
                     }
                 }
-
                 Object value = new Outer.Inner().test(0)
                 assert value == 2
             """
@@ -964,10 +1040,10 @@
     // GROOVY-11029
     void testSuperPropertyAccess1() {
         assertScript '''
-            class One {
+            class C {
                 Object thing
             }
-            class Two extends One {
+            class D extends C {
                 @Override
                 Object getThing() {
                     super.thing
@@ -977,30 +1053,28 @@
                     super.thing = object
                 }
             }
-
-            def two = new Two()
-            two.thing = 'value'
-            assert two.thing == 'value'
+            def d = new D()
+            d.thing = 'value'
+            assert d.thing == 'value'
         '''
     }
 
     void testSuperPropertyAccess2() {
         assertScript '''
-            abstract class One implements java.util.function.IntSupplier {
+            abstract class A implements java.util.function.IntSupplier {
                 final int prop = 1
             }
-            class Two {
+            class C {
                 final int prop = 2
-                One m() {
-                    new One() {
+                A m() {
+                    new A() {
                         int getAsInt() {
                             prop
                         }
                     }
                 }
             }
-
-            Number which = new Two().m().getAsInt()
+            Number which = new C().m().getAsInt()
             assert which == 1 // super before outer
         '''
     }
@@ -1008,24 +1082,23 @@
     // GROOVY-9562
     void testSuperPropertyAccess3() {
         assertScript '''
-            abstract class One {
+            abstract class A {
                 final int prop = 1
             }
-            abstract class Two {
+            abstract class B {
                 final int prop = 2
                 abstract int baz()
             }
-            class Foo extends One {
-                Two bar() {
-                    new Two() {
+            class C extends A {
+                B bar() {
+                    new B() {
                         int baz() {
                             prop
                         }
                     }
                 }
             }
-
-            Number which = new Foo().bar().baz()
+            Number which = new C().bar().baz()
             assert which == 2 // super before outer
         '''
     }
@@ -1035,12 +1108,11 @@
             class C {
                 private int x
                 void test() {
-                    def fun = { -> x = 666 }
-                    fun.call()
+                    def func = { -> x = 666 }
+                    func()
                     assert x == 666
                 }
             }
-
             new C().test()
         '''
     }
@@ -1056,7 +1128,6 @@
                     }
                 }
             }
-
             new C().test()
         '''
     }
@@ -1075,7 +1146,6 @@
                         }
                     }
                 }
-
                 assert C.E.FOO.number == 2
             """
         }
@@ -1117,7 +1187,6 @@
                     log.info "test"
                 }
             }
-
             new GreetingActor()
         '''
     }
@@ -1125,30 +1194,30 @@
     // GROOVY-6277
     void testPublicFieldVersusPrivateGetter() {
         assertScript '''
-            class Foo {
-                private getWho() { 'Foo' }
+            class C {
+                private String getWho() { 'C' }
             }
-            class Bar extends Foo {
-                public who = 'Bar'
+            class D extends C {
+                public String who = 'D'
             }
-            String result = new Bar().who
-            assert result == 'Bar'
+            String result = new D().who
+            assert result == 'D'
         '''
     }
 
     void testProtectedAccessorFromSamePackage() {
         assertScript '''
-            class Foo {
-                protected String getWho() { 'Foo' }
+            class C {
+                protected String getWho() { 'C' }
             }
-            class Bar {
-                def m(Foo foo) {
-                    def x = foo.who
+            class D {
+                def m(C c) {
+                    def x = c.who
                     x.toLowerCase()
                 }
             }
-            String result = new Bar().m(new Foo())
-            assert result == 'foo'
+            String result = new D().m(new C())
+            assert result == 'c'
         '''
     }
 
@@ -1158,18 +1227,14 @@
             class Outer {
                 static class Inner {
                     public final String value
-
                     Inner(String string) {
                         value = string
                     }
-
                     Inner() {
                         this(VALUE.toString())
                     }
                 }
-
                 private static Integer VALUE = 42
-
                 static main(args) {
                     assert new Inner().value == '42'
                 }
@@ -1208,57 +1273,57 @@
     // GROOVY-5872
     void testAssignNullToFieldWithGenericsShouldNotThrowError() {
         assertScript '''
-            class Foo {
+            class C {
                 List<String> list = null // should not throw an error
             }
-            new Foo()
+            new C()
         '''
     }
 
     void testSetterInWith() {
         assertScript '''
-            class Builder {
+            class C {
                 private int y
-                void setFoo(int x) { y = x}
+                void setFoo(int x) { y = x }
                 int value() { y }
             }
-            def b = new Builder()
-            b.with {
+            def c = new C()
+            c.with {
                 setFoo(5)
             }
-            assert b.value() == 5
+            assert c.value() == 5
         '''
     }
 
     void testSetterInWithUsingPropertyNotation() {
         assertScript '''
-            class Builder {
+            class C {
                 private int y
-                void setFoo(int x) { y = x}
+                void setFoo(int x) { y = x }
                 int value() { y }
             }
-            def b = new Builder()
-            b.with {
+            def c = new C()
+            c.with {
                 foo = 5
             }
-            assert b.value() == 5
+            assert c.value() == 5
         '''
     }
 
     void testSetterInWithUsingPropertyNotationAndClosureSharedVariable() {
         assertScript '''
-            class Builder {
+            class C {
                 private int y
-                void setFoo(int x) { y = x}
+                void setFoo(int x) { y = x }
                 int value() { y }
             }
-            def b = new Builder()
+            def c = new C()
             def csv = 0
-            b.with {
+            c.with {
                 foo = 5
                 csv = 10
             }
-            assert b.value() == 5
+            assert c.value() == 5
             assert csv == 10
         '''
     }
@@ -1322,7 +1387,7 @@
     }
 
     void testShouldFailWithIncompatibleGenericTypes() {
-        shouldFailWithMessages '''\
+        shouldFailWithMessages '''
             public class Foo {
                 private List<String> names;
 
@@ -1359,18 +1424,17 @@
 
     void testPropertyWithMultipleSetters() {
         assertScript '''
-            import org.codehaus.groovy.ast.expr.BinaryExpression
-            import org.codehaus.groovy.ast.expr.BooleanExpression
-            import org.codehaus.groovy.ast.stmt.AssertStatement
+            import org.codehaus.groovy.ast.expr.*
+            import org.codehaus.groovy.ast.stmt.*
 
-            class A {
+            class C {
                 private field
                 void setX(Integer a) {field=a}
                 void setX(String b) {field=b}
                 def getX(){field}
             }
 
-            @ASTTest(phase=INSTRUCTION_SELECTION,value={
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
                 lookup('test1').each { stmt ->
                     def exp = stmt.expression
                     assert exp instanceof BinaryExpression
@@ -1391,13 +1455,13 @@
                 }
             })
             void test() {
-                def a = new A()
+                def c = new C()
                 test1:
-                a.x = 1
-                assert a.x==1
+                c.x = 1
+                assert c.x==1
                 test2:
-                a.x = "3"
-                assert a.x == "3"
+                c.x = "3"
+                assert c.x == "3"
             }
             test()
         '''
@@ -1428,7 +1492,6 @@
             abstract class A implements I { String which
                 void setX(boolean b) { which = 'boolean' }
             }
-
             A a = new A() {
                 void setX(String s) { which = 'String' }
             }
@@ -1455,31 +1518,28 @@
 
     void testPropertyAssignmentAsExpression() {
         assertScript '''
-            class Foo {
+            class C {
                 int x = 2
             }
-            def f = new Foo()
-            def v = f.x = 3
-            assert v == 3
+            def c = new C()
+            def x = c.x = 3
+            assert x == 3
         '''
     }
 
     void testPropertyAssignmentInSubClassAndMultiSetter() {
         10.times {
             assertScript '''
-                class A {
+                class C {
                     int which
-
-                    A() {
+                    C() {
                         contentView = 42L
                         assert which == 2
                     }
-
                     void setContentView(Date value) { which = 1 }
                     void setContentView(Long value) { which = 2 }
                 }
-
-                class B extends A {
+                class D extends C {
                     void m() {
                         contentView = 42L
                         assert which == 2
@@ -1487,26 +1547,22 @@
                         assert which == 1
                     }
                 }
-
-                new B().m()
+                new D().m()
             '''
         }
     }
 
     void testPropertyAssignmentInSubClassAndMultiSetterThroughDelegation() {
         10.times {
-            assertScript '''\
-                class A {
+            assertScript '''
+                class C {
                     int which
-
                     void setContentView(Date value) { which = 1 }
                     void setContentView(Long value) { which = 2 }
                 }
-
-                class B extends A {
+                class D extends C {
                 }
-
-                new B().with {
+                new D().with {
                     contentView = 42L
                     assert which == 2
                     contentView = new Date()
@@ -1591,7 +1647,8 @@
 
             Foo foo = new Foo()
             foo.bar = new Bar()
-        ''', 'Cannot assign value of type Bar to variable of type int'
+        ''',
+        'Cannot assign value of type Bar to variable of type int'
 
         assertScript '''
             class Foo {
@@ -1650,10 +1707,20 @@
         '''
     }
 
+    //--------------------------------------------------------------------------
+
     static interface InterfaceWithField {
         String boo = "I don't fancy fields in interfaces"
     }
 
+    static class MapType extends HashMap<String,Number> {
+        def foo = 1
+        protected bar = 2
+        @PackageScope baz = 3
+        protected void setBar(bar) {}
+        @PackageScope void setBaz(baz) {}
+    }
+
     static class BaseClass {
         int x
     }
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index 253cb88..fbaec97 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -33,7 +33,6 @@
                     def bar = createBar()
                     bar.foo
                 }
-
                 Bar createBar() { new Bar() }
             }
             class Bar {
@@ -44,7 +43,7 @@
     }
 
     // GROOVY-5579
-    void testUseSetterAndNotSetProperty() {
+    void testUseSetterNotSetProperty() {
         assertScript '''
             Date d = new Date()
             d.time = 1
@@ -58,7 +57,7 @@
 
     void testUseDirectWriteFieldAccess() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 protected int x
@@ -67,22 +66,22 @@
                     x = a
                 }
             }
-            class B extends A {
+            class D extends C {
                 void directAccess() {
                     this.@x = 2
                 }
             }
-            B b = new B()
-            b.directAccess()
-            assert b.isSetterCalled() == false
-            assert b.x == 2
+            D d = new D()
+            d.directAccess()
+            assert d.isSetterCalled() == false
+            assert d.x == 2
         '''
-        assert astTrees['B'][1].contains('PUTFIELD A.x')
+        assert astTrees['D'][1].contains('PUTFIELD C.x')
     }
 
     void testUseDirectWriteStaticFieldAccess() {
         assertScript '''
-            class A {
+            class C {
                 static boolean setterCalled
 
                 static protected int x
@@ -91,21 +90,21 @@
                     x = a
                 }
             }
-            class B extends A {
+            class D extends C {
                 static void directAccess() {
                     this.@x = 2
                 }
             }
-            B.directAccess()
-            assert B.isSetterCalled() == false
-            assert B.x == 2
+            D.directAccess()
+            assert D.isSetterCalled() == false
+            assert D.x == 2
         '''
-        assert astTrees['B'][1].contains('PUTSTATIC A.x')
+        assert astTrees['D'][1].contains('PUTSTATIC C.x')
     }
 
     void testUseSetterFieldAccess() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 protected int x
@@ -114,135 +113,133 @@
                     x = a
                 }
             }
-            class B extends A {
+            class D extends C {
                 void setterAccess() {
                     this.x = 2
                 }
             }
-            B b = new B()
-            b.setterAccess()
-            assert b.isSetterCalled() == true
-            assert b.x == 2
+            D d = new D()
+            d.setterAccess()
+            assert d.isSetterCalled() == true
+            assert d.x == 2
         '''
-        assert astTrees['B'][1].contains('INVOKEVIRTUAL B.setX')
+        assert astTrees['D'][1].contains('INVOKEVIRTUAL D.setX')
     }
 
     void testUseDirectWriteFieldAccessFromOutsideClass() {
         assertScript '''
-            class A {
+            class C {
                 public int x
             }
-            class B  {
-                void directAccess(A a) {
-                    a.@x = 2
+            class D  {
+                void directAccess(C c) {
+                    c.@x = 2
                 }
             }
-            B b = new B()
-            A a = new A()
-            b.directAccess(a)
-            assert a.x == 2
+            D d = new D()
+            C c = new C()
+            d.directAccess(c)
+            assert c.x == 2
         '''
-        assert astTrees['B'][1].contains('PUTFIELD A.x')
+        assert astTrees['D'][1].contains('PUTFIELD C.x')
     }
 
     void testUseDirectWriteFieldAccessPrivateWithRuntimeClassBeingDifferent() {
         assertScript '''
-            class A {
+            class C {
                 private int x
-                public A(int x) {
+                public C(int x) {
                     this.@x = x
                 }
-                public boolean sameAs(A a) {
-                    return this.@x == a.@x
+                public boolean sameAs(C c) {
+                    return this.@x == c.@x
                 }
             }
-            class B extends A {
-                // B.x visible in B A.x in A, but reflection depending on the runtime type
-                // would see B.x in A#sameAs and not A.x
+            class D extends C {
+                // D.x visible in D C.x in C, but reflection depending on the runtime type would see C.x in C#sameAs and not C.x
                 private int x
-                public B(int x) {
+                public D(int x) {
                     super(x)
                     this.@x = x + 50
                 }
             }
-            B b = new B(1)
-            A a = new A(1)
-            assert b.sameAs(a)
+            D d = new D(1)
+            C c = new C(1)
+            assert d.sameAs(c)
         '''
         // same with property style access:
         assertScript '''
-            class A {
+            class C {
                 private int x
-                public A(int x) {
+                public C(int x) {
                     this.x = x
                 }
-                public boolean sameAs(A a) {
-                    return this.x == a.x
+                public boolean sameAs(C c) {
+                    return this.x == c.x
                 }
             }
-            class B extends A {
-                // B.x visible in B A.x in A, but reflection depending on the runtime type
-                // would see B.x in A#sameAs and not A.x
+            class D extends C {
+                // D.x visible in D C.x in C, but reflection depending on the runtime type would see D.x in C#sameAs and not C.x
                 private int x
-                public B(int x) {
+                public D(int x) {
                     super(x)
                     this.x = x + 50
                 }
             }
-            B b = new B(1)
-            A a = new A(1)
-            assert b.sameAs(a)
+            D d = new D(1)
+            C c = new C(1)
+            assert d.sameAs(c)
         '''
     }
 
     void testReadFieldFromSameClass() {
         ['', 'public', 'private', 'protected', '@groovy.transform.PackageScope'].each { mod ->
             assertScript """
-                class A {
+                class C {
                     $mod int x
                     int m() {
                         x
                     }
                 }
-                assert new A().m() == 0
+                assert new C().m() == 0
             """
-            def a = astTrees['A'][1]
-            assert (a =~ 'GETFIELD A.x').collect().size() == mod.empty ? 2 : 1
+            def a = astTrees['C'][1]
+            assert (a =~ 'GETFIELD C.x').collect().size() == mod.empty ? 2 : 1
         }
     }
 
     void testWriteFieldFromSameClass() {
         ['', 'public', 'private', 'protected', '@groovy.transform.PackageScope'].each { mod ->
             assertScript """
-                class A {
+                class C {
                     $mod int x
                     int m() {
                         x = 5
                         x
                     }
                 }
-                new A().m() == 5
+                new C().m() == 5
             """
-            def a = astTrees['A'][1]
-            assert (a =~ 'PUTFIELD A.x').collect().size() == mod.empty ? 2 : 1
+            def a = astTrees['C'][1]
+            assert (a =~ 'PUTFIELD C.x').collect().size() == mod.empty ? 2 : 1
         }
     }
 
     void testReadFieldFromSuperClass() {
         ['public', 'protected', '@groovy.transform.PackageScope'].each { mod ->
             assertScript """
-                class A {
+                class C {
                     $mod int x
                 }
-                class B extends A {
+                class D extends C {
                     int m() {
                         x
                     }
                 }
-                assert new B().m() == 0
+                assert new D().m() == 0
             """
-            def b = astTrees['B'][1]
-            assert  b.contains('GETFIELD A.x')
+            def d = astTrees['D'][1]
+            assert  d.contains('GETFIELD C.x')
         }
     }
 
@@ -250,21 +247,21 @@
     void testReadFieldFromSuperClass2() {
         assertScript '''
             package p
-            class A {
+            class C {
                 protected int x
             }
-            new p.A()
+            new p.C()
         '''
         assertScript '''
-            class B extends p.A {
+            class D extends p.C {
                 int m() {
                     x
                 }
             }
-            assert new B().m() == 0
+            assert new D().m() == 0
         '''
-        def b = astTrees['B'][1]
-        assert  b.contains('GETFIELD p/A.x')
+        def b = astTrees['D'][1]
+        assert  b.contains('GETFIELD p/C.x')
         assert !b.contains('INVOKEINTERFACE groovy/lang/GroovyObject.getProperty')
     }
 
@@ -272,47 +269,47 @@
     void testReadFieldFromSuperClass3() {
         assertScript '''
             package p
-            class A {
+            class C {
                 protected static int x
             }
-            new p.A()
+            new p.C()
         '''
         assertScript '''
-            class B extends p.A {
+            class D extends p.C {
                 static int m() {
                     x
                 }
             }
-            assert B.m() == 0
+            assert D.m() == 0
         '''
-        def b = astTrees['B'][1]
-        assert  b.contains('GETSTATIC B.x')
-        assert !b.contains('INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.getGroovyObjectProperty')
+        def d = astTrees['D'][1]
+        assert  d.contains('GETSTATIC D.x')
+        assert !d.contains('INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.getGroovyObjectProperty')
     }
 
     void testReadPropertyFromSuperClass() {
         ['', 'public', 'private', 'protected', '@groovy.transform.PackageScope'].each { mod ->
             assertScript """
-                class A {
+                class C {
                     $mod int x
                     int getX() { x }
                 }
-                class B extends A {
+                class D extends C {
                     int m() {
                         x
                     }
                 }
-                assert new B().m() == 0
+                assert new D().m() == 0
             """
-            def b = astTrees['B'][1]
-            assert !b.contains('GETFIELD A.x') : 'no GETFIELD in B'
-            assert  b.contains('INVOKEVIRTUAL B.getX') : 'getX() in B'
+            def d = astTrees['D'][1]
+            assert !d.contains('GETFIELD C.x') : 'no GETFIELD in D'
+            assert  d.contains('INVOKEVIRTUAL D.getX') : 'getX() in D'
         }
     }
 
     void testUseDirectReadFieldAccess() {
         assertScript '''
-            class A {
+            class C {
                 boolean getterCalled
 
                 protected int x
@@ -321,22 +318,22 @@
                     x
                 }
             }
-            class B extends A {
+            class D extends C {
                 void m() {
                     this.@x
                 }
             }
-            B b = new B()
-            b.m()
-            assert b.isGetterCalled() == false
+            D d = new D()
+            d.m()
+            assert d.isGetterCalled() == false
         '''
-        def b = astTrees['B'][1]
-        assert b.contains('GETFIELD A.x')
+        def d = astTrees['D'][1]
+        assert d.contains('GETFIELD C.x')
     }
 
     void testUseAttributeExternal() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -345,16 +342,16 @@
                     x = a
                 }
             }
-            A a = new A()
-            a.@x = 100
-            assert a.x == 100
-            assert a.isSetterCalled() == false
+            C c = new C()
+            c.@x = 100
+            assert c.x == 100
+            assert c.isSetterCalled() == false
         '''
     }
 
     void testUseAttributeExternalSafe() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -363,16 +360,16 @@
                     x = a
                 }
             }
-            A a = new A()
-            a?.@x = 100
-            assert a.x == 100
-            assert a.isSetterCalled() == false
+            C c = new C()
+            c?.@x = 100
+            assert c.x == 100
+            assert c.isSetterCalled() == false
         '''
     }
 
     void testUseAttributeExternalSafeWithNull() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -381,14 +378,14 @@
                     x = a
                 }
             }
-            A a = null
-            a?.@x = 100
+            C c = null
+            c?.@x = 100
         '''
     }
 
     void testUseSetterExternal() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -397,16 +394,16 @@
                     x = a
                 }
             }
-            A a = new A()
-            a.x = 100
-            assert a.x == 100
-            assert a.isSetterCalled() == true
+            C c = new C()
+            c.x = 100
+            assert c.x == 100
+            assert c.isSetterCalled() == true
         '''
     }
 
     void testUseAttributeExternalSpread() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -415,16 +412,16 @@
                     x = a
                 }
             }
-            List<A> a = [new A(), new A()]
-            a*.@x = 100
-          println a[0].x == 100
-          println a[0].isSetterCalled() == false
+            List<C> list = [new C(), new C()]
+            list*.@x = 100
+            assert list[0].x == 100
+            assert list[0].isSetterCalled() == false
         '''
     }
 
     void testUseAttributeExternalSpreadSafeWithNull() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -433,17 +430,17 @@
                     x = a
                 }
             }
-            List<A> a = [new A(), null]
-            a*.@x = 100
-            assert a[0].x == 100
-            assert a[0].isSetterCalled() == false
-            assert a[1] == null
+            List<C> list = [new C(), null]
+            list*.@x = 100
+            assert list[0].x == 100
+            assert list[0].isSetterCalled() == false
+            assert list[1] == null
         '''
     }
 
     void testUseAttributeExternalSpreadUsingSetter() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -452,16 +449,16 @@
                     x = a
                 }
             }
-            List<A> a = [new A(), new A()]
-            a*.x = 100
-            assert a[0].x == 100
-            assert a[0].isSetterCalled() == true
+            List<C> list = [new C(), new C()]
+            list*.x = 100
+            assert list[0].x == 100
+            assert list[0].isSetterCalled() == true
         '''
     }
 
     void testUseAttributeExternalSpreadSafeWithNullUsingSetter() {
         assertScript '''
-            class A {
+            class C {
                 boolean setterCalled
 
                 public int x
@@ -470,11 +467,11 @@
                     x = a
                 }
             }
-            List<A> a = [new A(), null]
-            a*.x = 100
-            assert a[0].x == 100
-            assert a[0].isSetterCalled() == true
-            assert a[1] == null
+            List<C> list = [new C(), null]
+            list*.x = 100
+            assert list[0].x == 100
+            assert list[0].isSetterCalled() == true
+            assert list[1] == null
         '''
     }
 
@@ -513,19 +510,18 @@
     void testPropertyWithMultipleSetters() {
         // we need to override the test because the AST is going to be changed
         assertScript '''
-            import org.codehaus.groovy.ast.expr.BinaryExpression
-            import org.codehaus.groovy.ast.expr.BooleanExpression
-            import org.codehaus.groovy.ast.stmt.AssertStatement
+            import org.codehaus.groovy.ast.expr.*
+            import org.codehaus.groovy.ast.stmt.*
             import org.codehaus.groovy.transform.sc.ListOfExpressionsExpression
 
-            class A {
+            class C {
                 private field
                 void setX(Integer a) {field=a}
                 void setX(String b) {field=b}
                 def getX(){field}
             }
 
-            @ASTTest(phase=INSTRUCTION_SELECTION,value={
+            @ASTTest(phase=INSTRUCTION_SELECTION, value={
                 lookup('test1').each { stmt ->
                     def exp = stmt.expression
                     assert exp instanceof ListOfExpressionsExpression
@@ -535,38 +531,34 @@
                     assert exp instanceof ListOfExpressionsExpression
                 }
             })
-            void testBody() {
-                def a = new A()
+            void test() {
+                def c = new C()
                 test1:
-                a.x = 1
-                assert a.x==1
+                c.x = 1
+                assert c.x==1
                 test2:
-                a.x = "3"
-                assert a.x == "3"
+                c.x = "3"
+                assert c.x == "3"
             }
-            testBody()
+            test()
         '''
     }
 
     void testCallSetterAsPropertyWithinFinallyBlockShouldNotThrowVerifyError() {
         try {
             assertScript '''
-                class Multi {
+                class C {
                    void setOut(int a) {}
                 }
-
-                void foo() {
-                   def m = new Multi()
-                   try {
-                   } finally {
-                      m.out = 1
-                   }
+                def c = new C()
+                try {
+                } finally {
+                    c.out = 1
                 }
-                foo()
             '''
         } finally {
             assert astTrees.values().any {
-                it.toString().contains 'INVOKEVIRTUAL Multi.setOut (I)V'
+                it.toString().contains 'INVOKEVIRTUAL C.setOut (I)V'
             }
         }
     }
@@ -574,26 +566,22 @@
     void testCallMultiSetterAsPropertyWithinFinallyBlockShouldNotThrowVerifyError() {
         try {
             assertScript '''
-                class Multi {
+                class C {
                    void setOut(int a) {}
                    void setOut(String a) {}
                 }
-
-                void foo() {
-                   def m = new Multi()
-                   try {
-                   } finally {
-                      m.out = 1
-                      m.out = 'foo'
-                   }
+                def c = new C()
+                try {
+                } finally {
+                    c.out = 1
+                    c.out = 'foo'
                 }
-                foo()
             '''
         } finally {
             assert astTrees.values().any {
                 def code = it.toString()
-                code.contains('INVOKEVIRTUAL Multi.setOut (I)V') &&
-                        code.contains('INVOKEVIRTUAL Multi.setOut (Ljava/lang/String;)V')
+                code.contains('INVOKEVIRTUAL C.setOut (I)V')
+                        && code.contains('INVOKEVIRTUAL C.setOut (Ljava/lang/String;)V')
             }
         }
     }
@@ -601,15 +589,15 @@
     // GROOVY-7698
     void testSafePropertyStyleSetterCalls() {
         assertScript '''
-            class Foo {
+            class C {
                 private String id
 
                 void setId(String id) {
                     this.id = id
                 }
             }
-            Foo foo = null
-            foo?.id = 'new'
+            C c = null
+            c?.id = 'new'
         '''
     }
 
@@ -703,25 +691,25 @@
     void testPrivateFieldMutationInAICUsesBridgeMethod() {
         try {
             assertScript '''
-                class A {
+                class C {
                     private int x
                     void test() {
-                        def aic = new Runnable() { void run() { A.this.x = 666 } }
+                        def aic = new Runnable() { void run() { C.this.x = 666 } }
                         aic.run()
                         assert x == 666
                     }
                 }
-                new A().test()
+                new C().test()
             '''
         } finally {
-            assert astTrees['A$1'][1].contains('INVOKESTATIC A.pfaccess$00 (LA;I)I')
+            assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 (LC;I)I')
         }
     }
 
     void testImplicitPrivateFieldMutationInAICUsesBridgeMethod() {
         try {
             assertScript '''
-                class A {
+                class C {
                     private int x
                     void test() {
                         def aic = new Runnable() { void run() { x = 666 } }
@@ -729,17 +717,17 @@
                         assert x == 666
                     }
                 }
-                new A().test()
+                new C().test()
             '''
         } finally {
-            assert astTrees['A$1'][1].contains('INVOKESTATIC A.pfaccess$00 (LA;I)I')
+            assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 (LC;I)I')
         }
     }
 
     void testPrivateStaticFieldMutationInAICUsesBridgeMethod() {
         try {
             assertScript '''
-                class A {
+                class C {
                     private static int x
                     void test() {
                         def aic = new Runnable() { void run() { x = 666 } }
@@ -747,17 +735,17 @@
                         assert x == 666
                     }
                 }
-                new A().test()
+                new C().test()
             '''
         } finally {
-            assert astTrees['A$1'][1].contains('INVOKESTATIC A.pfaccess$00 (LA;I)I')
+            assert astTrees['C$1'][1].contains('INVOKESTATIC C.pfaccess$00 (LC;I)I')
         }
     }
 
     void testMultiplePrivateFieldMutatorBridgeMethods() {
         try {
             assertScript '''
-                class A {
+                class C {
                     private int x
                     private String y
                     Closure mutate = { x = 1; y = 'abc' }
@@ -768,76 +756,75 @@
                         assert y == 'abc'
                     }
                 }
-                new A().test()
+                new C().test()
             '''
         } finally {
-            assert astTrees['A$_closure1'][1].contains('INVOKESTATIC A.pfaccess$00 (LA;I)I')
-            assert astTrees['A$_closure1'][1].contains('INVOKESTATIC A.pfaccess$01 (LA;Ljava/lang/String;)Ljava/lang/String;')
+            assert astTrees['C$_closure1'][1].contains('INVOKESTATIC C.pfaccess$00 (LC;I)I')
+            assert astTrees['C$_closure1'][1].contains('INVOKESTATIC C.pfaccess$01 (LC;Ljava/lang/String;)Ljava/lang/String;')
         }
     }
 
     void testPrivateFieldBridgeMethodsAreGeneratedAsNecessary() {
         try {
             assertScript '''
-                class A {
+                class C {
                     private int accessed = 0
                     private String mutated
                     private String accessedAndMutated = ''
-                    Closure c = {
+                    Closure cl = {
                         println accessed
                         mutated = 'abc'
                         println accessedAndMutated
                         accessedAndMutated = 'def'
                     }
-
                     void test() {
-                        c()
+                        cl()
                         assert mutated == 'abc'
                         assert accessedAndMutated == 'def'
                     }
                 }
-                new A().test()
+                new C().test()
             '''
         } finally {
-            def dump = astTrees['A'][1]
+            def dump = astTrees['C'][1]
             assert dump.contains('pfaccess$0') // accessor bridge method for 'accessed'
             assert !dump.contains('pfaccess$00') // no mutator bridge method for 'accessed'
             assert dump.contains('pfaccess$01') // mutator bridge method for 'mutated'
             assert dump.contains('pfaccess$1') // accessor bridge method for 'mutated' -- GROOVY-9385
             assert dump.contains('pfaccess$2') // accessor bridge method for 'accessedAndMutated'
             assert dump.contains('pfaccess$02') // mutator bridge method for 'accessedAndMutated'
-            dump = astTrees['A$_closure1'][1]
-            assert dump.contains('INVOKESTATIC A.pfaccess$2 (LA;)Ljava/lang/String;')
-            assert dump.contains('INVOKESTATIC A.pfaccess$02 (LA;Ljava/lang/String;)Ljava/lang/String;')
+            dump = astTrees['C$_closure1'][1]
+            assert dump.contains('INVOKESTATIC C.pfaccess$2 (LC;)Ljava/lang/String;')
+            assert dump.contains('INVOKESTATIC C.pfaccess$02 (LC;Ljava/lang/String;)Ljava/lang/String;')
         }
     }
 
     // GROOVY-8369
     void testPropertyAccessOnEnumClass() {
         assertScript '''
-            enum Foo { }
-            assert Foo.modifiers === Foo.getModifiers()
+            enum E { }
+            assert E.modifiers == E.getModifiers()
         '''
     }
 
     // GROOVY-8753
     void testPrivateFieldWithPublicGetter() {
         assertScript '''
-            class A {
+            class C {
                private List<String> fooNames = []
-               public A(Collection<String> names) {
+               public C(Collection<String> names) {
                   names.each { fooNames << it }
                }
                public List<String> getFooNames() { fooNames }
             }
-            assert new A(['foo1', 'foo2']).fooNames.size() == 2
+            assert new C(['foo1', 'foo2']).fooNames.size() == 2
         '''
     }
 
     // GROOVY-9683
     void testPrivateFieldAccessInClosure3() {
         assertScript '''
-            class A {
+            class C {
                 private static X = 'xxx'
                 void test() {
                     [:].with {
@@ -845,14 +832,14 @@
                     }
                 }
             }
-            new A().test()
+            new C().test()
         '''
     }
 
     // GROOVY-9695
     void testPrivateFieldAccessInClosure4() {
         assertScript '''
-            class A {
+            class C {
                 private static final X = 'xxx'
                 void test() {
                     Map m = [:]
@@ -864,11 +851,37 @@
                     assert m == [xxx:123]
                 }
             }
-            new A().test()
+            new C().test()
 
-            class B extends A {
+            class D extends C {
             }
-            new B().test()
+            new D().test()
+        '''
+    }
+
+    // GROOVY-11368
+    @Override
+    void testMapPropertyAccess9() {
+        String type = '''
+            class C implements Map<String,String> {
+                @Delegate Map<String,String> impl = [:]
+            }
+        '''
+        assertScript type + '''
+            def map = new C()
+            assert map.entry == null
+            assert map.empty != null
+            assert map.class != null
+            assert map.metaClass != null
+        '''
+        assertScript type + '''
+            def test(C map) { // no diff
+                assert map.entry == null
+                assert map.empty != null
+                assert map.class != null
+                assert map.metaClass != null
+            }
+            test(new C())
         '''
     }
 }