minor edits
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index bbca52a..9b30986 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -102,7 +102,6 @@
             DYNAMIC_TYPE = makeCached(Object.class),
             OBJECT_TYPE = DYNAMIC_TYPE,
             CLOSURE_TYPE = makeCached(Closure.class),
-            SERIALIZEDLAMBDA_TYPE = makeCached(SerializedLambda .class),
             GSTRING_TYPE = makeCached(GString.class),
             RANGE_TYPE = makeCached(Range.class),
             PATTERN_TYPE = makeCached(Pattern.class),
@@ -138,6 +137,7 @@
             ELEMENT_TYPE_TYPE = makeCached(ElementType.class),
             AUTOCLOSEABLE_TYPE = makeCached(AutoCloseable.class),
             SERIALIZABLE_TYPE = makeCached(Serializable.class),
+            SERIALIZEDLAMBDA_TYPE = makeCached(SerializedLambda.class),
 
             // uncached constants
             MAP_TYPE = makeWithoutCaching(Map.class),
diff --git a/src/main/java/org/codehaus/groovy/ast/GenericsType.java b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
index 1e68788..59e3168 100644
--- a/src/main/java/org/codehaus/groovy/ast/GenericsType.java
+++ b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
@@ -36,7 +36,7 @@
  */
 public class GenericsType extends ASTNode {
     public static final GenericsType[] EMPTY_ARRAY = new GenericsType[0];
-    
+
     private final ClassNode[] upperBounds;
     private final ClassNode lowerBound;
     private ClassNode type;
diff --git a/src/main/java/org/codehaus/groovy/ast/ModuleNode.java b/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
index 7033169..4e1376e 100644
--- a/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
@@ -127,7 +127,7 @@
     }
 
     public void addImport(String alias, ClassNode type) {
-        addImport(alias, type, new ArrayList<>());
+        addImport(alias, type, Collections.emptyList());
     }
 
     public void addImport(String alias, ClassNode type, List<AnnotationNode> annotations) {
diff --git a/src/main/java/org/codehaus/groovy/ast/VariableScope.java b/src/main/java/org/codehaus/groovy/ast/VariableScope.java
index 9a32e8e..4b0fbfc 100644
--- a/src/main/java/org/codehaus/groovy/ast/VariableScope.java
+++ b/src/main/java/org/codehaus/groovy/ast/VariableScope.java
@@ -24,15 +24,14 @@
 import java.util.Map;
 
 /**
- * Represents a variable scope. This is primarily used to determine variable sharing
- * across method and closure boundaries.
+ * Records declared and referenced variabes for a given scope.  Helps determine
+ * variable sharing across closure and method boundaries.
  */
-public class VariableScope  {
+public class VariableScope implements Cloneable {
 
     private VariableScope parent;
     private ClassNode classScope;
     private boolean inStaticContext;
-    private boolean resolvesDynamic;
 
     private Map<String, Variable> declaredVariables = Collections.emptyMap();
     private Map<String, Variable> referencedLocalVariables = Collections.emptyMap();
@@ -42,7 +41,7 @@
         super();
     }
 
-    public VariableScope(VariableScope parent) {
+    public VariableScope(final VariableScope parent) {
         this.parent = parent;
     }
 
@@ -51,7 +50,7 @@
     }
 
     public boolean isRoot() {
-        return parent == null;
+        return (parent == null);
     }
 
     /**
@@ -65,10 +64,10 @@
      * Returns true iff this scope corresponds to a class; as opposed to a method, "if" statement, block statement, etc.
      */
     public boolean isClassScope() {
-        return classScope != null;
+        return (classScope != null);
     }
 
-    public void setClassScope(ClassNode classScope) {
+    public void setClassScope(final ClassNode classScope) {
         this.classScope = classScope;
     }
 
@@ -76,29 +75,29 @@
         return inStaticContext;
     }
 
-    public void setInStaticContext(boolean inStaticContext) {
+    public void setInStaticContext(final boolean inStaticContext) {
         this.inStaticContext = inStaticContext;
     }
 
     //
 
-    public Variable getDeclaredVariable(String name) {
+    public Variable getDeclaredVariable(final String name) {
         return declaredVariables.get(name);
     }
 
-    public Variable getReferencedLocalVariable(String name) {
+    public Variable getReferencedLocalVariable(final String name) {
         return referencedLocalVariables.get(name);
     }
 
-    public Variable getReferencedClassVariable(String name) {
+    public Variable getReferencedClassVariable(final String name) {
         return referencedClassVariables.get(name);
     }
 
-    public boolean isReferencedLocalVariable(String name) {
+    public boolean isReferencedLocalVariable(final String name) {
         return referencedLocalVariables.containsKey(name);
     }
 
-    public boolean isReferencedClassVariable(String name) {
+    public boolean isReferencedClassVariable(final String name) {
         return referencedClassVariables.containsKey(name);
     }
 
@@ -159,25 +158,25 @@
         return getReferencedClassVariables().values().iterator();
     }
 
-    public void putDeclaredVariable(Variable var) {
+    public void putDeclaredVariable(final Variable var) {
         if (declaredVariables == Collections.EMPTY_MAP)
             declaredVariables = new LinkedHashMap<>();
         declaredVariables.put(var.getName(), var);
     }
 
-    public void putReferencedLocalVariable(Variable var) {
+    public void putReferencedLocalVariable(final Variable var) {
         if (referencedLocalVariables == Collections.EMPTY_MAP)
             referencedLocalVariables = new LinkedHashMap<>();
         referencedLocalVariables.put(var.getName(), var);
     }
 
-    public void putReferencedClassVariable(Variable var) {
+    public void putReferencedClassVariable(final Variable var) {
         if (referencedClassVariables == Collections.EMPTY_MAP)
             referencedClassVariables = new LinkedHashMap<>();
         referencedClassVariables.put(var.getName(), var);
     }
 
-    public Object removeReferencedClassVariable(String name) {
+    public Object removeReferencedClassVariable(final String name) {
         if (referencedClassVariables.isEmpty()) {
             return null;
         } else {
@@ -189,19 +188,18 @@
 
     // TODO: implement Cloneable and override Object.clone()
     public VariableScope copy() {
-        VariableScope copy = new VariableScope(parent);
-        copy.classScope = classScope;
-        copy.inStaticContext = inStaticContext;
-        copy.resolvesDynamic = resolvesDynamic;
-        if (!declaredVariables.isEmpty()) {
-            copy.declaredVariables = new LinkedHashMap<>(declaredVariables);
+        VariableScope that = new VariableScope(parent);
+        that.classScope = this.classScope;
+        that.inStaticContext = this.inStaticContext;
+        if (!this.declaredVariables.isEmpty()) {
+            that.declaredVariables = new LinkedHashMap<>(this.declaredVariables);
         }
-        if (!referencedLocalVariables.isEmpty()) {
-            copy.referencedLocalVariables = new LinkedHashMap<>(referencedLocalVariables);
+        if (!this.referencedLocalVariables.isEmpty()) {
+            that.referencedLocalVariables = new LinkedHashMap<>(this.referencedLocalVariables);
         }
-        if (!referencedClassVariables.isEmpty()) {
-            copy.referencedClassVariables = new LinkedHashMap<>(referencedClassVariables);
+        if (!this.referencedClassVariables.isEmpty()) {
+            that.referencedClassVariables = new LinkedHashMap<>(this.referencedClassVariables);
         }
-        return copy;
+        return that;
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java
index ccdceed..c8d1025 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/ClosureExpression.java
@@ -85,7 +85,7 @@
      * @return {@code true} if one or more explicit parameters are supplied
      */
     public boolean isParameterSpecified() {
-        return parameters != null && parameters.length > 0;
+        return (parameters != null && parameters.length > 0);
     }
 
     public VariableScope getVariableScope() {
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/ConstantExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/ConstantExpression.java
index a9036a2..d958795 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/ConstantExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/ConstantExpression.java
@@ -22,7 +22,7 @@
 import org.codehaus.groovy.ast.GroovyCodeVisitor;
 
 /**
- * Represents a constant expression such as null, true, false
+ * Represents a constant expression such as null, true, false.
  */
 public class ConstantExpression extends Expression {
     // The following fields are only used internally; every occurrence of a user-defined expression of the same kind
@@ -92,7 +92,7 @@
     }
 
     public String getText() {
-        return value == null ? "null" : value.toString();
+        return (value == null ? "null" : value.toString());
     }
 
     public String getConstantName() {
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java
index ae7d6c3..c877f56 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java
@@ -37,7 +37,9 @@
     /**
      * @see EmptyExpression#INSTANCE
      */
-    public EmptyExpression() {}
+    public EmptyExpression() {
+        super();
+    }
 
     @Override
     public Expression transformExpression(ExpressionTransformer transformer) {
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java
index 1199e33..5365b88 100644
--- a/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java
@@ -21,7 +21,6 @@
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.GroovyCodeVisitor;
 
-import java.util.Collections;
 import java.util.Map;
 
 public class EmptyStatement extends Statement {
@@ -29,10 +28,8 @@
     /**
      * @see EmptyStatement#INSTANCE
      */
-    public EmptyStatement() {}
-
-    protected EmptyStatement(Map<?, ?> metaDataMap) {
-        super.setMetaDataMap(metaDataMap);
+    public EmptyStatement() {
+        super();
     }
 
     @Override
@@ -51,7 +48,7 @@
      * Immutable singleton that is recommended for use when source range or any
      * other occurrence-specific metadata is not needed.
      */
-    public static final EmptyStatement INSTANCE = new EmptyStatement(Collections.EMPTY_MAP) {
+    public static final EmptyStatement INSTANCE = new EmptyStatement() {
 
         private void throwUnsupportedOperationException() {
             throw new UnsupportedOperationException("EmptyStatement.INSTANCE is immutable");
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 1e084dc..e9a4d60b2 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -481,8 +481,10 @@
                         redirect = ClassHelper.OBJECT_TYPE;
                     }
                     if (redirect.isGenericsPlaceHolder()) {
+                        // "T extends U" or "T super U"
                         type = redirect;
                     } else {
+                        // "T" or "T extends Thing" or "T super Thing"
                         type = ClassHelper.makeWithoutCaching(name);
                         type.setGenericsPlaceHolder(true);
                         type.setRedirect(redirect);
diff --git a/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java b/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java
index 42eb463..3974262 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java
@@ -85,7 +85,7 @@
         if (!checkIfValidEnumConstsAreUsed(node)) {
             return node;
         }
-        
+
         Map<String, Expression> attributes = node.getMembers();
         for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
             String attrName = entry.getKey();
@@ -97,7 +97,7 @@
         VMPluginFactory.getPlugin().configureAnnotation(node);
         return this.annotation;
     }
-    
+
     private boolean checkIfValidEnumConstsAreUsed(AnnotationNode node) {
         Map<String, Expression> attributes = node.getMembers();
         for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
@@ -106,7 +106,7 @@
         }
         return true;
     }
-    
+
     private boolean validateEnumConstant(Expression exp) {
         if (exp instanceof PropertyExpression) {
             PropertyExpression pe = (PropertyExpression) exp;
@@ -154,7 +154,7 @@
         // if it is an error, we have to test it at another place. But size==0 is
         // an error, because it means that no such attribute exists.
         if (methods.isEmpty()) {
-            addError("'" + attrName + "'is not part of the annotation " + classNode, node);
+            addError("'" + attrName + "'is not part of the annotation " + classNode.getNameWithoutPackage(), node);
             return ClassHelper.OBJECT_TYPE;
         }
         MethodNode method = (MethodNode) methods.get(0);
@@ -236,14 +236,11 @@
         } else {
             addError(base, exp);
         }
-        return ConstantExpression.EMPTY_EXPRESSION;
+        ConstantExpression ret = new ConstantExpression(null);
+        ret.setSourcePosition(exp);
+        return ret;
     }
 
-    /**
-     * @param attrName   the name
-     * @param expression the expression
-     * @param attrType   the type
-     */
     protected void visitAnnotationExpression(String attrName, AnnotationConstantExpression expression, ClassNode attrType) {
         AnnotationNode annotationNode = (AnnotationNode) expression.getValue();
         AnnotationVisitor visitor = new AnnotationVisitor(this.source, this.errorCollector);
@@ -310,5 +307,4 @@
             checkCircularReference(searchClass, method.getReturnType(), code.getExpression());
         }
     }
-
 }
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
index 75fbf73..4377263 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
@@ -755,8 +755,8 @@
             if (resultType != null) {
                 addMeta(expression).type = resultType;
                 opt.chainInvolvedType(resultType);
-                opt.chainInvolvedType(leftType);
                 opt.chainInvolvedType(rightType);
+                opt.chainInvolvedType(leftType);
             }
         }
 
@@ -781,16 +781,15 @@
 
         @Override
         public void visitDeclarationExpression(final DeclarationExpression expression) {
-            Expression right = expression.getRightExpression();
-            right.visit(this);
+            Expression rightExpression = expression.getRightExpression();
+            rightExpression.visit(this);
 
             ClassNode leftType = typeChooser.resolveType(expression.getLeftExpression(), node);
-            Expression rightExpression = expression.getRightExpression();
             ClassNode rightType = optimizeDivWithIntOrLongTarget(rightExpression, leftType);
-            if (rightType == null) rightType = typeChooser.resolveType(expression.getRightExpression(), node);
+            if (rightType == null) rightType = typeChooser.resolveType(rightExpression, node);
             if (isPrimitiveType(leftType) && isPrimitiveType(rightType)) {
                 // if right is a constant, then we optimize only if it makes a block complete, so we set a maybe
-                if (right instanceof ConstantExpression) {
+                if (rightExpression instanceof ConstantExpression) {
                     opt.chainCanOptimize(true);
                 } else {
                     opt.chainShouldOptimize(true);
@@ -868,8 +867,7 @@
 
             ClassNode originalResultType = typeChooser.resolveType(binExp, node);
             if (!originalResultType.equals(BigDecimal_TYPE)
-                    || !(isLongCategory(assignmentTartgetType)
-                    || isFloatingCategory(assignmentTartgetType))) {
+                    || !(isLongCategory(assignmentTartgetType) || isFloatingCategory(assignmentTartgetType))) {
                 return null;
             }
 
diff --git a/src/main/java/org/codehaus/groovy/control/ProcessingUnit.java b/src/main/java/org/codehaus/groovy/control/ProcessingUnit.java
index af3f7c3..162fa6c 100644
--- a/src/main/java/org/codehaus/groovy/control/ProcessingUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/ProcessingUnit.java
@@ -73,7 +73,7 @@
     }
 
     /**
-     * Get the CompilerConfiguration for this ProcessingUnit.
+     * Gets the CompilerConfiguration for this ProcessingUnit.
      */
     public CompilerConfiguration getConfiguration() {
         return configuration;
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 5230044..06e9df1 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -132,7 +132,7 @@
     private static class ConstructedNestedClass extends ClassNode {
         final ClassNode knownEnclosingType;
 
-        public ConstructedNestedClass(ClassNode outer, String inner) {
+        public ConstructedNestedClass(final ClassNode outer, final String inner) {
             super(outer.getName() + "$" + inner.replace('.', '$'), Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
             this.knownEnclosingType = outer;
             this.isPrimaryNode = false;
@@ -151,7 +151,7 @@
         }
 
         @Override
-        public String setName(String name) {
+        public String setName(final String name) {
             if (redirect() != this) {
                 return super.setName(name);
             } else {
@@ -172,7 +172,7 @@
         final String prefix;
         String className;
 
-        public ConstructedClassWithPackage(String pkg, String name) {
+        public ConstructedClassWithPackage(final String pkg, final String name) {
             super(pkg + name, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
             isPrimaryNode = false;
             this.prefix = pkg;
@@ -194,7 +194,7 @@
         }
 
         @Override
-        public String setName(String name) {
+        public String setName(final String name) {
             if (redirect() != this) {
                 return super.setName(name);
             } else {
@@ -216,7 +216,7 @@
     private static class LowerCaseClass extends ClassNode {
         final String className;
 
-        public LowerCaseClass(String name) {
+        public LowerCaseClass(final String name) {
             super(name, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
             isPrimaryNode = false;
             this.className = name;
@@ -237,7 +237,7 @@
         }
 
         @Override
-        public String setName(String name) {
+        public String setName(final String name) {
             if (redirect() != this) {
                 return super.setName(name);
             } else {
@@ -246,18 +246,27 @@
         }
     }
 
-    public ResolveVisitor(CompilationUnit compilationUnit) {
+    public ResolveVisitor(final CompilationUnit compilationUnit) {
         this.compilationUnit = compilationUnit;
         setClassNodeResolver(new ClassNodeResolver());
     }
 
-    public void startResolving(ClassNode node, SourceUnit source) {
+    public void setClassNodeResolver(final ClassNodeResolver classNodeResolver) {
+        this.classNodeResolver = classNodeResolver;
+    }
+
+    public void startResolving(final ClassNode node, final SourceUnit source) {
         this.source = source;
         visitClass(node);
     }
 
     @Override
-    protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
+    protected SourceUnit getSourceUnit() {
+        return source;
+    }
+
+    @Override
+    protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
         VariableScope oldScope = currentScope;
         currentScope = node.getVariableScope();
         Map<GenericsTypeName, GenericsType> oldPNames = genericParameterNames;
@@ -288,7 +297,7 @@
     }
 
     @Override
-    public void visitField(FieldNode node) {
+    public void visitField(final FieldNode node) {
         ClassNode t = node.getType();
         if (!fieldTypesChecked.contains(node)) {
             resolveOrFail(t, node);
@@ -297,7 +306,7 @@
     }
 
     @Override
-    public void visitProperty(PropertyNode node) {
+    public void visitProperty(final PropertyNode node) {
         Map<GenericsTypeName, GenericsType> oldPNames = genericParameterNames;
         if (node.isStatic() && !Traits.isTrait(node.getDeclaringClass())) {
             genericParameterNames = new HashMap<>();
@@ -311,7 +320,7 @@
         genericParameterNames = oldPNames;
     }
 
-    private boolean resolveToInner(ClassNode type) {
+    private boolean resolveToInner(final ClassNode type) {
         // we do not do our name mangling to find an inner class
         // if the type is a ConstructedClassWithPackage, because in this case we
         // are resolving the name at a different place already
@@ -331,7 +340,7 @@
         return false;
     }
 
-    private void resolveOrFail(ClassNode type, String msg, ASTNode node) {
+    private void resolveOrFail(final ClassNode type, final String msg, final ASTNode node) {
         if (resolve(type)) return;
         if (resolveToInner(type)) return;
         if (resolveToOuterNested(type)) return;
@@ -343,7 +352,7 @@
     // if the type to resolve is an inner class and it is in an outer class which is not resolved,
     // we set the resolved type to a placeholder class node, i.e. a ConstructedOuterNestedClass instance
     // when resolving the outer class later, we set the resolved type of ConstructedOuterNestedClass instance to the actual inner class node(SEE GROOVY-7812(#2))
-    private boolean resolveToOuterNested(ClassNode type) {
+    private boolean resolveToOuterNested(final ClassNode type) {
         CompileUnit compileUnit = currentClass.getCompileUnit();
         String typeName = type.getName();
 
@@ -398,7 +407,7 @@
         return toResolveFurther;
     }
 
-    private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeViaStaticImport(CompileUnit compileUnit, ImportNode importNode, String typeName, BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
+    private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeViaStaticImport(final CompileUnit compileUnit, final ImportNode importNode, final String typeName, final BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
         String importClassName = importNode.getClassName();
         ClassNode outerClassNode = compileUnit.getClass(importClassName);
 
@@ -410,7 +419,7 @@
         return constructedOuterNestedClassNode;
     }
 
-    private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNode(ClassNode type, ClassNode outerClassNode, BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
+    private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNode(final ClassNode type, final ClassNode outerClassNode, final BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
         String outerClassName = outerClassNode.getName();
 
         for (String typeName = type.getName(), ident = typeName; ident.indexOf('.') != -1; ) {
@@ -426,7 +435,7 @@
         return null;
     }
 
-    private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeForBaseType(CompileUnit compileUnit, String typeName, ClassNode cn, BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
+    private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeForBaseType(final CompileUnit compileUnit, final String typeName, final ClassNode cn, final BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
         if (!compileUnit.getClassesToCompile().containsValue(cn)) return null;
 
         String outerNestedClassName = cn.getName() + "$" + typeName;
@@ -435,21 +444,21 @@
         return constructedOuterNestedClassNode;
     }
 
-    private void resolveOrFail(ClassNode type, ASTNode node, boolean prefereImports) {
+    private void resolveOrFail(final ClassNode type, final ASTNode node, final boolean prefereImports) {
         resolveGenericsTypes(type.getGenericsTypes());
         if (prefereImports && resolveAliasFromModule(type)) return;
         resolveOrFail(type, node);
     }
 
-    private void resolveOrFail(ClassNode type, ASTNode node) {
+    private void resolveOrFail(final ClassNode type, final ASTNode node) {
         resolveOrFail(type, "", node);
     }
 
-    private boolean resolve(ClassNode type) {
+    protected boolean resolve(final ClassNode type) {
         return resolve(type, true, true, true);
     }
 
-    private boolean resolve(ClassNode type, boolean testModuleImports, boolean testDefaultImports, boolean testStaticInnerClasses) {
+    protected boolean resolve(final ClassNode type, final boolean testModuleImports, final boolean testDefaultImports, final boolean testStaticInnerClasses) {
         resolveGenericsTypes(type.getGenericsTypes());
         if (type.isResolved() || type.isPrimaryClassNode()) return true;
         if (type.isArray()) {
@@ -488,7 +497,7 @@
                 (testStaticInnerClasses && type.hasPackageName() && resolveFromStaticInnerClasses(type));
     }
 
-    private boolean resolveNestedClass(ClassNode type) {
+    protected boolean resolveNestedClass(final ClassNode type) {
         if (type instanceof ConstructedNestedClass || type instanceof ConstructedClassWithPackage) return false;
 
         // We have for example a class name A, are in class X
@@ -530,7 +539,7 @@
         return false;
     }
 
-    private boolean setRedirect(ClassNode type, ClassNode classToCheck) {
+    private boolean setRedirect(final ClassNode type, final ClassNode classToCheck) {
         String typeName = type.getName();
 
         Predicate<ClassNode> resolver = (ClassNode maybeOuter) -> {
@@ -559,13 +568,13 @@
         return false;
     }
 
-    private static String replaceLastPointWithDollar(String name) {
+    private static String replaceLastPointWithDollar(final String name) {
         int lastPointIndex = name.lastIndexOf('.');
 
         return name.substring(0, lastPointIndex) + "$" + name.substring(lastPointIndex + 1);
     }
 
-    private boolean resolveFromStaticInnerClasses(ClassNode type) {
+    protected boolean resolveFromStaticInnerClasses(final ClassNode type) {
         // a class consisting of a vanilla name can never be
         // a static inner class, because at least one dot is
         // required for this. Example: foo.bar -> foo$bar
@@ -593,7 +602,7 @@
         return false;
     }
 
-    private boolean resolveFromDefaultImports(ClassNode type) {
+    protected boolean resolveFromDefaultImports(final ClassNode type) {
         // we do not resolve a vanilla name starting with a lower case letter
         // try to resolve against a default import, because we know that the
         // default packages do not contain classes like these
@@ -626,7 +635,7 @@
 
     private static final EvictableCache<String, Set<String>> DEFAULT_IMPORT_CLASS_AND_PACKAGES_CACHE = new UnlimitedConcurrentCache<>();
 
-    private boolean resolveFromDefaultImports(ClassNode type, String[] packagePrefixes) {
+    protected boolean resolveFromDefaultImports(final ClassNode type, final String[] packagePrefixes) {
         String typeName = type.getName();
 
         for (String packagePrefix : packagePrefixes) {
@@ -652,7 +661,7 @@
         return false;
     }
 
-    private boolean resolveFromCompileUnit(ClassNode type) {
+    protected boolean resolveFromCompileUnit(final ClassNode type) {
         // look into the compile unit if there is a class with that name
         CompileUnit compileUnit = currentClass.getCompileUnit();
         if (compileUnit == null) return false;
@@ -664,7 +673,7 @@
         return false;
     }
 
-    private void ambiguousClass(ClassNode type, ClassNode iType, String name) {
+    private void ambiguousClass(final ClassNode type, final ClassNode iType, final String name) {
         if (type.getName().equals(iType.getName())) {
             addError("reference to " + name + " is ambiguous, both class " + type.getName() + " and " + iType.getName() + " match", type);
         } else {
@@ -672,7 +681,7 @@
         }
     }
 
-    private boolean resolveAliasFromModule(ClassNode type) {
+    private boolean resolveAliasFromModule(final ClassNode type) {
         // In case of getting a ConstructedClassWithPackage here we do not do checks for partial
         // matches with imported classes. The ConstructedClassWithPackage is already a constructed
         // node and any subclass resolving will then take place elsewhere
@@ -743,7 +752,7 @@
         return false;
     }
 
-    private boolean resolveFromModule(ClassNode type, boolean testModuleImports) {
+    protected boolean resolveFromModule(final ClassNode type, final boolean testModuleImports) {
         if (type instanceof ConstructedNestedClass) return false;
 
         // we decided if we have a vanilla name starting with a lower case
@@ -840,7 +849,7 @@
         return false;
     }
 
-    private boolean resolveToOuter(ClassNode type) {
+    protected boolean resolveToOuter(final ClassNode type) {
         String name = type.getName();
 
         // We do not need to check instances of LowerCaseClass
@@ -869,7 +878,8 @@
         return false;
     }
 
-    public Expression transform(Expression exp) {
+    @Override
+    public Expression transform(final Expression exp) {
         if (exp == null) return null;
         Expression ret;
         if (exp instanceof VariableExpression) {
@@ -898,7 +908,7 @@
         return ret;
     }
 
-    private static String lookupClassName(PropertyExpression pe) {
+    private static String lookupClassName(final PropertyExpression pe) {
         boolean doInitialClassTest = true;
         StringBuilder name = new StringBuilder(32);
         // this loop builds a name from right to left each name part
@@ -939,7 +949,7 @@
         return name.toString();
     }
 
-    private static Tuple2<StringBuilder, Boolean> makeClassName(boolean doInitialClassTest, StringBuilder name, String varName) {
+    private static Tuple2<StringBuilder, Boolean> makeClassName(final boolean doInitialClassTest, final StringBuilder name, final String varName) {
         if (doInitialClassTest) {
             // we are at the first name part. This is the right most part.
             // If this part is in lower case, then we do not need a class
@@ -948,23 +958,20 @@
             // can still be resolved to the class foo.Bar and the static
             // field bar.
             if (!testVanillaNameForClass(varName)) {
-                name = null;
+                return tuple(null, Boolean.TRUE);
             } else {
-                doInitialClassTest = false;
-                name = new StringBuilder(varName);
+                return tuple(new StringBuilder(varName), Boolean.FALSE);
             }
-        } else {
-            name.insert(0, varName + ".");
         }
-
-        return tuple(name, doInitialClassTest);
+        name.insert(0, varName + ".");
+        return tuple(name, Boolean.FALSE);
     }
 
     // iterate from the inner most to the outer and check for classes
     // this check will ignore a .class property, for Example Integer.class will be
     // a PropertyExpression with the ClassExpression of Integer as objectExpression
     // and class as property
-    private static Expression correctClassClassChain(PropertyExpression pe) {
+    private static Expression correctClassClassChain(final PropertyExpression pe) {
         LinkedList<Expression> stack = new LinkedList<Expression>();
         ClassExpression found = null;
         for (Expression it = pe; it != null; it = ((PropertyExpression) it).getObjectExpression()) {
@@ -1019,8 +1026,7 @@
         if (className != null) {
             ClassNode type = ClassHelper.make(className);
             if (resolve(type)) {
-                Expression ret = new ClassExpression(type);
-                return ret;
+                return new ClassExpression(type);
             }
         }
         if (objectExpression instanceof ClassExpression && pe.getPropertyAsString() != null) {
@@ -1043,13 +1049,13 @@
         return ret;
     }
 
-    private static boolean isVisibleNestedClass(ClassNode innerType, ClassNode outerType) {
+    private static boolean isVisibleNestedClass(final ClassNode innerType, final ClassNode outerType) {
         int modifiers = innerType.getModifiers();
         return Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)
                 || (!Modifier.isPrivate(modifiers) && Objects.equals(innerType.getPackageName(), outerType.getPackageName()));
     }
 
-    private boolean directlyImplementsTrait(ClassNode trait) {
+    private boolean directlyImplementsTrait(final ClassNode trait) {
         ClassNode[] interfaces = currentClass.getInterfaces();
         if (interfaces == null) {
             return currentClass.getSuperClass().equals(trait);
@@ -1062,7 +1068,7 @@
         return currentClass.getSuperClass().equals(trait);
     }
 
-    private void checkThisAndSuperAsPropertyAccess(PropertyExpression expression) {
+    private void checkThisAndSuperAsPropertyAccess(final PropertyExpression expression) {
         if (expression.isImplicitThis()) return;
         String prop = expression.getPropertyAsString();
         if (prop == null) return;
@@ -1093,7 +1099,7 @@
         }
     }
 
-    protected Expression transformVariableExpression(VariableExpression ve) {
+    protected Expression transformVariableExpression(final VariableExpression ve) {
         visitAnnotations(ve);
         Variable v = ve.getAccessedVariable();
 
@@ -1138,12 +1144,12 @@
         return ve;
     }
 
-    private static boolean testVanillaNameForClass(String name) {
+    private static boolean testVanillaNameForClass(final String name) {
         if (name == null || name.length() == 0) return false;
         return !Character.isLowerCase(name.charAt(0));
     }
 
-    protected Expression transformBinaryExpression(BinaryExpression be) {
+    protected Expression transformBinaryExpression(final BinaryExpression be) {
         Expression left = transform(be.getLeftExpression());
         if (be.getOperation().isA(Types.ASSIGNMENT_OPERATOR) && left instanceof ClassExpression) {
             ClassExpression ce = (ClassExpression) left;
@@ -1204,7 +1210,7 @@
         return be;
     }
 
-    protected Expression transformClosureExpression(ClosureExpression ce) {
+    protected Expression transformClosureExpression(final ClosureExpression ce) {
         boolean oldInClosure = inClosure;
         inClosure = true;
         for (Parameter para : getParametersSafe(ce)) {
@@ -1223,7 +1229,7 @@
         return ce;
     }
 
-    protected Expression transformConstructorCallExpression(ConstructorCallExpression cce) {
+    protected Expression transformConstructorCallExpression(final ConstructorCallExpression cce) {
         findPossibleOuterClassNodeForNonStaticInnerClassInstantiation(cce);
 
         ClassNode type = cce.getType();
@@ -1235,7 +1241,7 @@
         return cce.transformExpression(this);
     }
 
-    private void findPossibleOuterClassNodeForNonStaticInnerClassInstantiation(ConstructorCallExpression cce) {
+    private void findPossibleOuterClassNodeForNonStaticInnerClassInstantiation(final ConstructorCallExpression cce) {
         // GROOVY-8947: Fail to resolve non-static inner class outside of outer class
         // `new Computer().new Cpu(4)` will be parsed to `new Cpu(new Computer(), 4)`
         // so non-static inner class instantiation expression's first argument is a constructor call of outer class
@@ -1257,11 +1263,11 @@
         }
     }
 
-    private static String getDescription(ClassNode node) {
+    private static String getDescription(final ClassNode node) {
         return (node.isInterface() ? "interface" : "class") + " '" + node.getName() + "'";
     }
 
-    protected Expression transformMethodCallExpression(MethodCallExpression mce) {
+    protected Expression transformMethodCallExpression(final MethodCallExpression mce) {
         Expression args = transform(mce.getArguments());
         Expression method = transform(mce.getMethod());
         Expression object = transform(mce.getObjectExpression());
@@ -1277,7 +1283,7 @@
         return ret;
     }
 
-    protected Expression transformDeclarationExpression(DeclarationExpression de) {
+    protected Expression transformDeclarationExpression(final DeclarationExpression de) {
         visitAnnotations(de);
         Expression oldLeft = de.getLeftExpression();
         checkingVariableTypeInDeclaration = true;
@@ -1301,14 +1307,14 @@
         return newDeclExpr;
     }
 
-    // TODO get normal resolving to set declaring class
-    private void fixDeclaringClass(DeclarationExpression newDeclExpr) {
+    // TODO: get normal resolving to set declaring class
+    private void fixDeclaringClass(final DeclarationExpression newDeclExpr) {
         if (newDeclExpr.getDeclaringClass() == null && currentMethod != null) {
             newDeclExpr.setDeclaringClass(currentMethod.getDeclaringClass());
         }
     }
 
-    protected Expression transformAnnotationConstantExpression(AnnotationConstantExpression ace) {
+    protected Expression transformAnnotationConstantExpression(final AnnotationConstantExpression ace) {
         AnnotationNode an = (AnnotationNode) ace.getValue();
         ClassNode type = an.getClassNode();
         resolveOrFail(type, " for annotation", an);
@@ -1318,7 +1324,8 @@
         return ace;
     }
 
-    public void visitAnnotations(AnnotatedNode node) {
+    @Override
+    public void visitAnnotations(final AnnotatedNode node) {
         List<AnnotationNode> annotations = node.getAnnotations();
         if (annotations.isEmpty()) return;
         Map<String, AnnotationNode> tmpAnnotations = new HashMap<>();
@@ -1347,7 +1354,7 @@
         }
     }
 
-    private boolean isRepeatable(Class<?> annTypeClass) {
+    private boolean isRepeatable(final Class<?> annTypeClass) {
         Annotation[] annTypeAnnotations = annTypeClass.getAnnotations();
         for (Annotation annTypeAnnotation : annTypeAnnotations) {
             if (annTypeAnnotation.annotationType().getName().equals("java.lang.annotation.Repeatable")) {
@@ -1375,7 +1382,7 @@
         return exp;
     }
 
-    private void checkAnnotationMemberValue(Expression newValue) {
+    private void checkAnnotationMemberValue(final Expression newValue) {
         if (newValue instanceof PropertyExpression) {
             PropertyExpression pe = (PropertyExpression) newValue;
             if (!(pe.getObjectExpression() instanceof ClassExpression)) {
@@ -1389,7 +1396,8 @@
         }
     }
 
-    public void visitClass(ClassNode node) {
+    @Override
+    public void visitClass(final ClassNode node) {
         ClassNode oldNode = currentClass;
 
         currentClass = node;
@@ -1468,7 +1476,7 @@
     }
 
     // GROOVY-7812(#2): Static inner classes cannot be accessed from other files when running by 'groovy' command
-    private void resolveOuterNestedClassFurther(ClassNode node) {
+    private void resolveOuterNestedClassFurther(final ClassNode node) {
         CompileUnit compileUnit = currentClass.getCompileUnit();
 
         if (null == compileUnit) return;
@@ -1498,7 +1506,7 @@
         }
     }
 
-    private void checkCyclicInheritance(ClassNode originalNode, ClassNode parentToCompare, ClassNode[] interfacesToCompare) {
+    private void checkCyclicInheritance(final ClassNode originalNode, final ClassNode parentToCompare, final ClassNode[] interfacesToCompare) {
         if (!originalNode.isInterface()) {
             if (parentToCompare == null) return;
             if (originalNode == parentToCompare.redirect()) {
@@ -1532,7 +1540,8 @@
         }
     }
 
-    public void visitCatchStatement(CatchStatement cs) {
+    @Override
+    public void visitCatchStatement(final CatchStatement cs) {
         resolveOrFail(cs.getExceptionType(), cs);
         if (cs.getExceptionType() == ClassHelper.DYNAMIC_TYPE) {
             cs.getVariable().setType(ClassHelper.make(Exception.class));
@@ -1540,23 +1549,21 @@
         super.visitCatchStatement(cs);
     }
 
-    public void visitForLoop(ForStatement forLoop) {
+    @Override
+    public void visitForLoop(final ForStatement forLoop) {
         resolveOrFail(forLoop.getVariableType(), forLoop);
         super.visitForLoop(forLoop);
     }
 
-    public void visitBlockStatement(BlockStatement block) {
+    @Override
+    public void visitBlockStatement(final BlockStatement block) {
         VariableScope oldScope = currentScope;
         currentScope = block.getVariableScope();
         super.visitBlockStatement(block);
         currentScope = oldScope;
     }
 
-    protected SourceUnit getSourceUnit() {
-        return source;
-    }
-
-    private boolean resolveGenericsTypes(GenericsType[] types) {
+    private boolean resolveGenericsTypes(final GenericsType[] types) {
         if (types == null) return true;
         currentClass.setUsingGenerics(true);
         boolean resolved = true;
@@ -1567,11 +1574,11 @@
         return resolved;
     }
 
-    private void resolveGenericsHeader(GenericsType[] types) {
+    private void resolveGenericsHeader(final GenericsType[] types) {
         resolveGenericsHeader(types, null, 0);
     }
 
-    private void resolveGenericsHeader(GenericsType[] types, GenericsType rootType, int level) {
+    private void resolveGenericsHeader(final GenericsType[] types, final GenericsType rootType, final int level) {
         if (types == null) return;
         currentClass.setUsingGenerics(true);
         List<Tuple2<ClassNode, GenericsType>> upperBoundsWithGenerics = new LinkedList<>();
@@ -1638,7 +1645,7 @@
         }
     }
 
-    private boolean resolveGenericsType(GenericsType genericsType) {
+    private boolean resolveGenericsType(final GenericsType genericsType) {
         if (genericsType.isResolved()) return true;
         currentClass.setUsingGenerics(true);
         ClassNode type = genericsType.getType();
@@ -1674,11 +1681,7 @@
 
     }
 
-    public void setClassNodeResolver(ClassNodeResolver classNodeResolver) {
-        this.classNodeResolver = classNodeResolver;
-    }
-
-    private static Map<String, ClassNode> findHierClasses(ClassNode currentClass) {
+    private static Map<String, ClassNode> findHierClasses(final ClassNode currentClass) {
         Map<String, ClassNode> hierClasses = new LinkedHashMap<>();
         for (ClassNode classToCheck = currentClass; classToCheck != ClassHelper.OBJECT_TYPE; classToCheck = classToCheck.getSuperClass()) {
             if (classToCheck == null || hierClasses.containsKey(classToCheck.getName())) break;
diff --git a/src/main/java/org/codehaus/groovy/control/SourceUnit.java b/src/main/java/org/codehaus/groovy/control/SourceUnit.java
index f9b320c..7091222 100644
--- a/src/main/java/org/codehaus/groovy/control/SourceUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/SourceUnit.java
@@ -254,14 +254,10 @@
         String property = (String) AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty("groovy.ast"));
 
         if ("xml".equals(property)) {
-            saveAsXML(name, ast);
+            XStreamUtils.serialize(name, ast);
         }
     }
 
-    private static void saveAsXML(String name, ModuleNode ast) {
-        XStreamUtils.serialize(name, ast);
-    }
-
     //---------------------------------------------------------------------------
     // SOURCE SAMPLING
 
diff --git a/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java b/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
index d1afa34..c2c508f 100644
--- a/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
@@ -119,8 +119,6 @@
                 }
             }
 
-
-
             // invert the map, is now one to many
             transforms = new HashMap<ASTNode, List<ASTTransformation>>();
             for (Map.Entry<Class<? extends ASTTransformation>, Set<ASTNode>> entry : baseTransforms.entrySet()) {
@@ -204,7 +202,7 @@
 
         compilationUnit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
             public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
-                ASTTransformationCollectorCodeVisitor collector = 
+                ASTTransformationCollectorCodeVisitor collector =
                     new ASTTransformationCollectorCodeVisitor(source, compilationUnit.getTransformLoader());
                 collector.visitClass(classNode);
             }
@@ -230,11 +228,11 @@
             }
         }
     }
-    
+
     public static void addGlobalTransformsAfterGrab(ASTTransformationsContext context) {
         doAddGlobalTransforms(context, false);
     }
-    
+
     public static void addGlobalTransforms(ASTTransformationsContext context) {
         doAddGlobalTransforms(context, true);
     }
@@ -293,7 +291,6 @@
                             compilationUnit.getErrorCollector().addError(new SimpleMessage(
                                     "IOException reading the service definition at "
                                             + service.toExternalForm() + " because of exception " + ioe.toString(), null));
-                            //noinspection UnnecessaryContinue
                             continue;
                         }
                     }
@@ -306,9 +303,9 @@
                 null));
         }
 
-        // record the transforms found in the first scan, so that in the 2nd scan, phase operations 
-        // can be added for only for new transforms that have come in 
-        if(isFirstScan) {
+        // record the transforms found in the first scan, so that in the 2nd scan, phase operations
+        // can be added for only for new transforms that have come in
+        if (isFirstScan) {
             for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
                 context.getGlobalTransformNames().add(entry.getKey());
             }
@@ -319,14 +316,13 @@
             addPhaseOperationsForGlobalTransforms(context.getCompilationUnit(), transformNames, isFirstScan);
         }
     }
-    
+
     private static void addPhaseOperationsForGlobalTransforms(CompilationUnit compilationUnit,
             Map<String, URL> transformNames, boolean isFirstScan) {
         GroovyClassLoader transformLoader = compilationUnit.getTransformLoader();
         for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
             try {
                 Class gTransClass = transformLoader.loadClass(entry.getKey(), false, true, false);
-                //no inspection unchecked
                 GroovyASTTransformation transformAnnotation = (GroovyASTTransformation) gTransClass.getAnnotation(GroovyASTTransformation.class);
                 if (transformAnnotation == null) {
                     compilationUnit.getErrorCollector().addWarning(new WarningMessage(
@@ -347,8 +343,8 @@
                         public void call(SourceUnit source) throws CompilationFailedException {
                             instance.visit(new ASTNode[] {source.getAST()}, source);
                         }
-                    }; 
-                    if(isFirstScan) {
+                    };
+                    if (isFirstScan) {
                         compilationUnit.addPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
                     } else {
                         compilationUnit.addNewPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
@@ -366,4 +362,3 @@
         }
     }
 }
-
diff --git a/src/main/java/org/codehaus/groovy/transform/AnnotationCollectorTransform.java b/src/main/java/org/codehaus/groovy/transform/AnnotationCollectorTransform.java
index f41feac..bf94211 100644
--- a/src/main/java/org/codehaus/groovy/transform/AnnotationCollectorTransform.java
+++ b/src/main/java/org/codehaus/groovy/transform/AnnotationCollectorTransform.java
@@ -62,6 +62,7 @@
 
 /**
  * This class is the base for any annotation alias processor.
+ *
  * @see AnnotationCollector
  * @see AnnotationCollectorTransform#visit(AnnotationNode, AnnotationNode, AnnotatedNode, SourceUnit)
  */
diff --git a/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java
index e0e3b20..16a85f8 100644
--- a/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java
@@ -260,7 +260,6 @@
         } catch (Exception e) {
             return null;
         }
-
     }
 
 
diff --git a/src/main/java/org/codehaus/groovy/transform/NewifyASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/NewifyASTTransformation.java
index ae71b14..4cc060f 100644
--- a/src/main/java/org/codehaus/groovy/transform/NewifyASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/NewifyASTTransformation.java
@@ -345,7 +345,8 @@
 
     private void checkDuplicateNameClashes(ListExpression list) {
         final Set<String> seen = new HashSet<String>();
-        @SuppressWarnings("unchecked") final List<ClassExpression> classes = (List) list.getExpressions();
+        @SuppressWarnings("unchecked")
+        List<ClassExpression> classes = (List) list.getExpressions();
         for (ClassExpression ce : classes) {
             final String name = ce.getType().getNameWithoutPackage();
             if (seen.contains(name)) {
@@ -363,7 +364,8 @@
     }
 
     private void checkClassLevelClashes(ListExpression list) {
-        @SuppressWarnings("unchecked") final List<ClassExpression> classes = (List) list.getExpressions();
+        @SuppressWarnings("unchecked")
+        List<ClassExpression> classes = (List) list.getExpressions();
         for (ClassExpression ce : classes) {
             final String name = ce.getType().getNameWithoutPackage();
             if (findClassWithMatchingBasename(name)) {
@@ -373,10 +375,10 @@
         }
     }
 
-
     private boolean isNewifyCandidate(MethodCallExpression mce) {
-        return mce.getObjectExpression() == VariableExpression.THIS_EXPRESSION
-                || (auto && isNewMethodStyle(mce));
+        return (auto && isNewMethodStyle(mce)) || (mce.isImplicitThis()
+                && mce.getObjectExpression() instanceof VariableExpression
+                && ((VariableExpression) mce.getObjectExpression()).isThisExpression());
     }
 
     private static boolean isNewMethodStyle(MethodCallExpression mce) {
@@ -428,7 +430,8 @@
         }
 
         if (classesToNewify != null) {
-            @SuppressWarnings("unchecked") final List<ClassExpression> classes = (List) classesToNewify.getExpressions();
+            @SuppressWarnings("unchecked")
+            List<ClassExpression> classes = (List) classesToNewify.getExpressions();
             for (ClassExpression ce : classes) {
                 if (ce.getType().getNameWithoutPackage().equals(nameWithoutPackage)) {
                     return true;
@@ -505,11 +508,10 @@
         return source;
     }
 
-
     private static class NewifyClassData {
         final String name;
         final ClassNode type;
-        List<ClassNode> types = null;
+        List<ClassNode> types;
 
         public NewifyClassData(final String name, final ClassNode type) {
             this.name = name;
@@ -524,6 +526,4 @@
             types.add(additionalType);
         }
     }
-
-
 }
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java b/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java
index d65d9d4..df8f8b6 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java
@@ -45,7 +45,7 @@
  * @since 3.0.0
  */
 public abstract class AbstractExtensionMethodCache {
-    private final EvictableCache<ClassLoader, Map<String, List<MethodNode>>> cache = new StampedCommonCache<>(new WeakHashMap<>());
+    final EvictableCache<ClassLoader, Map<String, List<MethodNode>>> cache = new StampedCommonCache<>(new WeakHashMap<>());
 
     public Map<String, List<MethodNode>> get(ClassLoader loader) {
         return cache.getAndPut(loader, this::getMethodsFromClassLoader);
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 10de207..5c2823d 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -162,31 +162,31 @@
     protected static final ExtensionMethodCache EXTENSION_METHOD_CACHE = ExtensionMethodCache.INSTANCE;
 
     protected static final Map<ClassNode, Integer> NUMBER_TYPES = Maps.of(
-            byte_TYPE, 0,
-            Byte_TYPE, 0,
-            short_TYPE, 1,
-            Short_TYPE, 1,
-            int_TYPE, 2,
+            byte_TYPE,    0,
+            Byte_TYPE,    0,
+            short_TYPE,   1,
+            Short_TYPE,   1,
+            int_TYPE,     2,
             Integer_TYPE, 2,
-            Long_TYPE, 3,
-            long_TYPE, 3,
-            float_TYPE, 4,
-            Float_TYPE, 4,
-            double_TYPE, 5,
-            Double_TYPE, 5
+            Long_TYPE,    3,
+            long_TYPE,    3,
+            float_TYPE,   4,
+            Float_TYPE,   4,
+            double_TYPE,  5,
+            Double_TYPE,  5
     );
 
     protected static final Map<String, Integer> NUMBER_OPS = Maps.of(
-            "plus", PLUS,
-            "minus", MINUS,
-            "multiply", MULTIPLY,
-            "div", DIVIDE,
-            "or", BITWISE_OR,
-            "and", BITWISE_AND,
-            "xor", BITWISE_XOR,
-            "mod", MOD,
-            "intdiv", INTDIV,
-            "leftShift", LEFT_SHIFT,
+            "plus",       PLUS,
+            "minus",      MINUS,
+            "multiply",   MULTIPLY,
+            "div",        DIVIDE,
+            "or",         BITWISE_OR,
+            "and",        BITWISE_AND,
+            "xor",        BITWISE_XOR,
+            "mod",        MOD,
+            "intdiv",     INTDIV,
+            "leftShift",  LEFT_SHIFT,
             "rightShift", RIGHT_SHIFT,
             "rightShiftUnsigned", RIGHT_SHIFT_UNSIGNED
     );
@@ -233,6 +233,10 @@
         }
     };
 
+    public static void clearExtensionMethodCache() {
+        EXTENSION_METHOD_CACHE.cache.clearAll();
+    }
+
     /**
      * Returns true for expressions of the form x[...]
      *
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index 8ca1c18..a12584c 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -219,8 +219,8 @@
         for (final MethodNode methodNode : methods) {
             boolean declared = methodNode.getDeclaringClass() == cNode;
             if (declared) {
-                if (!methodNode.isSynthetic() && (methodNode.isProtected() || methodNode.getModifiers()==0)) {
-                    unit.addError(new SyntaxException("Cannot have protected/package private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")",
+                if (!methodNode.isSynthetic() && (methodNode.isProtected() || (!methodNode.isPrivate() && !methodNode.isPublic()))) {
+                    unit.addError(new SyntaxException("Cannot have protected/package-private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")",
                             methodNode.getLineNumber(), methodNode.getColumnNumber()));
                     return null;
                 }
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
index 8cb68af..b1b965d 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
@@ -55,8 +55,9 @@
 /**
  * This expression transformer is used internally by the {@link org.codehaus.groovy.transform.trait.TraitASTTransformation
  * trait} AST transformation to change the receiver of a message on "this" into a static method call on the trait helper
- * class. <p></p>
- * In a nutshell, code like the following method definition in a trait:<p></p> <code>void foo() { this.bar() }</code> is
+ * class.
+ * <p>
+ * In a nutshell, code like the following method definition in a trait: <code>void foo() { this.bar() }</code> is
  * transformed into: <code>void foo() { TraitHelper$bar(this) }</code>
  *
  * @since 2.3.0
@@ -204,7 +205,7 @@
                 method,
                 ArgumentListExpression.EMPTY_ARGUMENTS
         );
-        mce.setSourcePosition(exp);
+        mce.setSourcePosition(exp instanceof PropertyExpression ? ((PropertyExpression) exp).getProperty() : exp);
         mce.setImplicitThis(false);
         return mce;
     }
@@ -349,7 +350,6 @@
         return transformed;
     }
 
-
     private Expression transformMethodCallOnThis(final MethodCallExpression call) {
         Expression method = call.getMethod();
         Expression arguments = call.getArguments();
diff --git a/src/test/gls/annotations/closures/AnnotationClosureThisObjectCallTest.groovy b/src/test/gls/annotations/closures/AnnotationClosureThisObjectCallTest.groovy
index 8761923..a3431e8 100644
--- a/src/test/gls/annotations/closures/AnnotationClosureThisObjectCallTest.groovy
+++ b/src/test/gls/annotations/closures/AnnotationClosureThisObjectCallTest.groovy
@@ -18,7 +18,8 @@
  */
 package gls.annotations.closures
 
-class AnnotationClosureThisObjectCallTest extends AnnotationClosureExhaustiveTestSupport {
+final class AnnotationClosureThisObjectCallTest extends AnnotationClosureExhaustiveTestSupport {
+
     Class getAnnotationClass() { AnnWithClassElement }
 
     Class getAnnotatedClass() { CallOnThisObject }
@@ -33,6 +34,7 @@
 
 @AnnWithClassElement(elem = { this.answer() })
 class CallOnThisObject {
+
     @AnnWithClassElement(elem = { this.answer() })
     private aField
 
@@ -41,7 +43,8 @@
 
     @AnnWithClassElement(elem = { this.answer() })
     def aMethod(@AnnWithClassElement(elem = { this.answer() }) aParam) {
+
         @AnnWithClassElement(elem = { this.answer() })
         def aLocal
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/org/codehaus/groovy/runtime/powerassert/AssertionTestUtil.groovy b/src/test/org/codehaus/groovy/runtime/powerassert/AssertionTestUtil.groovy
index 0aac26a..c7c677b 100644
--- a/src/test/org/codehaus/groovy/runtime/powerassert/AssertionTestUtil.groovy
+++ b/src/test/org/codehaus/groovy/runtime/powerassert/AssertionTestUtil.groovy
@@ -18,21 +18,26 @@
  */
 package org.codehaus.groovy.runtime.powerassert
 
+import groovy.transform.AutoFinal
 import org.junit.Assert
 
 /**
  * Utility methods for testing power assertions.
  */
+@AutoFinal
+final class AssertionTestUtil {
 
-abstract class AssertionTestUtil {
-    static fails(Closure assertion) {
+    private AssertionTestUtil() {
+    }
+
+    static fails(Closure<Void> assertion) {
         try {
             assertion.call();
             Assert.fail("assertion should have failed but didn't")
         } catch (PowerAssertionError expected) {}
     }
 
-    static isNotTransformed(Closure failingAssertion) {
+    static isNotTransformed(Closure<Void> failingAssertion) {
         try {
             failingAssertion()
             throw new RuntimeException("assertion should have failed but didn't")
@@ -42,7 +47,7 @@
         }
     }
 
-    static isRendered(String expectedRendering, Closure failingAssertion) {
+    static isRendered(String expectedRendering, Closure<Void> failingAssertion) {
         try {
             failingAssertion.call();
             Assert.fail("assertion should have failed but didn't")