You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/04/16 15:37:11 UTC

[groovy] branch master updated: remove antlr2

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

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


The following commit(s) were added to refs/heads/master by this push:
     new fee8d39  remove antlr2
fee8d39 is described below

commit fee8d39c539d65d5c851fb7fab4e57cfaa76a5cc
Author: Paul King <pa...@asert.com.au>
AuthorDate: Thu Apr 16 12:59:03 2020 +1000

    remove antlr2
---
 build.gradle                                       |   43 -
 src/main/antlr2/org/codehaus/groovy/antlr/groovy.g | 4074 --------------------
 .../antlr2/org/codehaus/groovy/antlr/java/java.g   | 2047 ----------
 .../codehaus/groovy/antlr/ASTParserException.java  |   54 -
 .../codehaus/groovy/antlr/ASTRuntimeException.java |   56 -
 .../groovy/antlr/AntlrASTProcessSnippets.java      |   94 -
 .../codehaus/groovy/antlr/AntlrASTProcessor.java   |   33 -
 .../codehaus/groovy/antlr/AntlrParserPlugin.java   | 3175 ---------------
 .../groovy/antlr/AntlrParserPluginFactory.java     |   30 -
 .../org/codehaus/groovy/antlr/GroovySourceAST.java |  168 -
 .../codehaus/groovy/antlr/GroovySourceToken.java   |   98 -
 .../java/org/codehaus/groovy/antlr/LineColumn.java |   61 -
 src/main/java/org/codehaus/groovy/antlr/Main.java  |  189 -
 .../org/codehaus/groovy/antlr/SourceBuffer.java    |  130 -
 .../java/org/codehaus/groovy/antlr/SourceInfo.java |   77 -
 .../groovy/antlr/UnicodeEscapingReader.java        |  190 -
 .../groovy/antlr/UnicodeLexerSharedInputState.java |   50 -
 .../org/codehaus/groovy/antlr/java/Groovifier.java |   75 -
 .../groovy/antlr/java/Java2GroovyConverter.java    |  231 --
 .../groovy/antlr/java/Java2GroovyMain.java         |   36 -
 .../groovy/antlr/java/Java2GroovyProcessor.java    |  185 -
 .../groovy/antlr/java/PreJava2GroovyConverter.java |  148 -
 .../java/org/codehaus/groovy/antlr/package.html    |   29 -
 .../groovy/antlr/treewalker/CompositeVisitor.java  | 1181 ------
 .../antlr/treewalker/FlatNodeListTraversal.java    |   59 -
 .../groovy/antlr/treewalker/MindMapPrinter.java    |  377 --
 .../groovy/antlr/treewalker/NodeAsHTMLPrinter.java |  316 --
 .../groovy/antlr/treewalker/NodeCollector.java     |   42 -
 .../groovy/antlr/treewalker/NodePrinter.java       |   49 -
 .../groovy/antlr/treewalker/PreOrderTraversal.java |   43 -
 .../antlr/treewalker/SourceCodeTraversal.java      |  258 --
 .../groovy/antlr/treewalker/SourcePrinter.java     | 1093 ------
 .../groovy/antlr/treewalker/TraversalHelper.java   |  555 ---
 .../codehaus/groovy/antlr/treewalker/Visitor.java  |  257 --
 .../groovy/antlr/treewalker/VisitorAdapter.java    |  255 --
 .../codehaus/groovy/antlr/treewalker/package.html  |   29 -
 .../groovy/control/ParserPluginFactory.java        |    3 +-
 .../org/codehaus/groovy/control/SourceUnit.java    |   43 +-
 src/test/gls/generics/GenericsUsageTest.groovy     |  137 +-
 src/test/groovy/bugs/Groovy5318.groovy             |    7 +-
 src/test/groovy/bugs/Groovy8446.groovy             |    7 +-
 .../groovy/transform/stc/DelegatesToSTCTest.groovy |   24 +-
 .../groovy/transform/stc/GenericsSTCTest.groovy    |   11 +-
 .../groovy/transform/stc/MethodCallsSTCTest.groovy |   11 +-
 .../groovy/antlr/AnnotationSourceParsingTest.java  |   14 +-
 .../groovy/antlr/EnumSourceParsingTest.java        |  351 +-
 .../codehaus/groovy/antlr/GStringEndTest.groovy    |   28 +-
 .../codehaus/groovy/antlr/GroovySourceASTTest.java |   49 -
 .../codehaus/groovy/antlr/SourceBufferTest.java    |   87 -
 .../codehaus/groovy/antlr/SourceParserTest.java    |   52 -
 .../antlr/treewalker/CompositeVisitorTest.java     |  113 -
 .../groovy/antlr/treewalker/Java2GroovyTest.java   |   47 -
 .../groovy/antlr/treewalker/LineColumnChecker.java |   56 -
 .../groovy/antlr/treewalker/LineColumnTest.java    |   61 -
 .../antlr/treewalker/MindMapPrinterTest.java       |   93 -
 .../antlr/treewalker/NodeAsHTMLPrinterTest.java    |   91 -
 .../groovy/antlr/treewalker/NodePrinterTest.java   |   59 -
 .../groovy/antlr/treewalker/SourcePrinterTest.java |  887 -----
 .../antlr/treewalker/TraversalTestHelper.java      |   70 -
 .../antlr/treewalker/UnimplementedSyntaxTest.java  |  249 --
 .../codehaus/groovy/ast/LineColumnCheckTest.groovy |    7 +-
 subprojects/groovy-groovydoc/build.gradle          |    1 -
 .../completion/ReflectionCompleterTest.groovy      |   51 +-
 subprojects/parser-antlr4/build.gradle             |    6 -
 .../apache/groovy/parser/antlr4/TestUtils.groovy   |   61 +-
 65 files changed, 344 insertions(+), 18119 deletions(-)

diff --git a/build.gradle b/build.gradle
index bf7c67c..4e0b819 100644
--- a/build.gradle
+++ b/build.gradle
@@ -122,14 +122,12 @@ repositories {
 configurations {
     compilerCompile
     tools
-    antlr2
     spec
 }
 
 ext {
     antVersion = '1.10.7'
     asmVersion = '8.0.1'
-    antlrVersion = '2.7.7'
     antlr4Version = '4.7.4'
     bridgerVersion = '1.5.Final'
     coberturaVersion = '1.9.4.1'
@@ -164,7 +162,6 @@ dependencies {
     // for internal usage of things like Opcode
     api "org.ow2.asm:asm:$asmVersion" // marked as api but manually excluded later in assemble.gradle - modules will use shaded version
     // for internal usage by the parser but manually excluded later in assemble.gradle - modules will use shaded version
-    api "antlr:antlr:$antlrVersion"
     implementation "org.ow2.asm:asm-analysis:$asmVersion"
     implementation "org.ow2.asm:asm-commons:$asmVersion"
     implementation "org.ow2.asm:asm-tree:$asmVersion"
@@ -204,8 +201,6 @@ dependencies {
     tools "org.ow2.asm:asm:$asmVersion"
     tools "com.thoughtworks.qdox:qdox:$qdoxVersion"
 
-    antlr2 "org.apache.ant:ant-antlr:$antVersion"
-
     testImplementation project(':groovy-ant')
     testImplementation project(':groovy-xml')
     testImplementation project(':groovy-dateutil')
@@ -218,14 +213,12 @@ ext.generatedDirectory = "${buildDir}/generated/sources"
 sourceSets {
     main {
         java {
-            srcDir "$generatedDirectory/antlr2/src/main"
             if (!JavaVersion.current().isJava9Compatible()) {
                 exclude '**/v9/*'
                 exclude '**/vm9/*'
             }
         }
         groovy {
-            srcDir "$generatedDirectory/antlr2/src/main"
             if (!JavaVersion.current().isJava9Compatible()) {
                 exclude '**/v9/*'
                 exclude '**/vm9/*'
@@ -235,11 +228,6 @@ sourceSets {
             srcDirs = ['src/resources']
         }
     }
-    antlr2 {
-        resources {
-            srcDirs = ['src/main/antlr2']
-        }
-    }
     test {
         groovy {
             srcDirs = ['src/test']
@@ -262,7 +250,6 @@ task sourceJar(type: Jar) {
     classifier = 'sources'
     duplicatesStrategy = DuplicatesStrategy.EXCLUDE
     from sourceSets.main.allSource
-    from sourceSets.antlr2.allSource
 }
 
 subprojects {
@@ -275,37 +262,7 @@ subprojects {
 
 apply from: 'subprojects/parser-antlr4/build.gradle'
 
-task ensureGrammars {
-    outputs.cacheIf { true }
-    description = 'Ensure all the Antlr2 generated files are up to date.'
-    ext.antlrDirectory = "$projectDir/src/main/antlr2/org/codehaus/groovy/antlr"
-    ext.javaParserDirectory = "$ext.antlrDirectory/java"
-    ext.genPath = "$generatedDirectory/antlr2/src/main/org/codehaus/groovy/antlr"
-    ext.groovyOutDir = "$ext.genPath/parser"
-    ext.javaOutDir = "$ext.genPath/java"
-    inputs.dir(antlrDirectory)
-    outputs.dir(groovyOutDir)
-    outputs.dir(javaOutDir)
-    doFirst {
-        new File(groovyOutDir).mkdirs()
-        new File(javaOutDir).mkdirs()
-        ant {
-            taskdef(name: 'antlr2',
-                    classname: 'org.apache.tools.ant.taskdefs.optional.ANTLR',
-                    classpath: configurations.antlr2.asPath)
-
-            antlr2(target: "$ext.antlrDirectory/groovy.g", outputdirectory: ext.groovyOutDir) {
-                classpath path: configurations.compileClasspath.asPath
-            }
-            antlr2(target: "$ext.javaParserDirectory/java.g", outputdirectory: ext.javaOutDir) {
-                classpath path: configurations.compileClasspath.asPath
-            }
-        }
-    }
-}
-
 compileJava {
-    dependsOn ensureGrammars, generateGrammarSource
     options.fork(memoryMaximumSize: javacMain_mx)
 
     doLast {
diff --git a/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g b/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g
deleted file mode 100644
index 1f70720..0000000
--- a/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g
+++ /dev/null
@@ -1,4074 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-header {
-package org.codehaus.groovy.antlr.parser;
-
-import java.io.*;
-import java.util.*;
-
-import antlr.CommonToken;
-import antlr.InputBuffer;
-import antlr.LexerSharedInputState;
-import antlr.TokenStreamRecognitionException;
-
-import org.codehaus.groovy.antlr.*;
-}
-
-/** JSR-241 Groovy Recognizer.
- *
- * Run 'java Main [-showtree] directory-full-of-groovy-files'
- *
- * [The -showtree option pops up a Swing frame that shows
- *  the AST constructed from the parser.]
- *
- * Contributing authors:
- *              John Mitchell           johnm@non.net
- *              Terence Parr            parrt@magelang.com
- *              John Lilley             jlilley@empathy.com
- *              Scott Stanchfield       thetick@magelang.com
- *              Markus Mohnen           mohnen@informatik.rwth-aachen.de
- *              Peter Williams          pete.williams@sun.com
- *              Allan Jacobs            Allan.Jacobs@eng.sun.com
- *              Steve Messick           messick@redhills.com
- *              James Strachan          jstrachan@protique.com
- *              John Pybus              john@pybus.org
- *              John Rose               rose00@mac.com
- *              Jeremy Rayner           groovy@ross-rayner.com
- *              Alex Popescu            the.mindstorm@gmail.com
- *              Martin Kempf            mkempf@hsr.ch
- *              Reto Kleeb              rkleeb@hsr.ch
- *
- * Version 1.00 December 9, 1997 -- initial release
- * Version 1.01 December 10, 1997
- *              fixed bug in octal def (0..7 not 0..8)
- * Version 1.10 August 1998 (parrt)
- *              added tree construction
- *              fixed definition of WS,comments for mac,pc,unix newlines
- *              added unary plus
- * Version 1.11 (Nov 20, 1998)
- *              Added "shutup" option to turn off last ambig warning.
- *              Fixed inner class def to allow named class defs as statements
- *              synchronized requires compound not simple statement
- *              add [] after builtInType DOT class in primaryExpression
- *              "const" is reserved but not valid..removed from modifiers
- * Version 1.12 (Feb 2, 1999)
- *              Changed LITERAL_xxx to xxx in tree grammar.
- *              Updated java.g to use tokens {...} now for 2.6.0 (new feature).
- *
- * Version 1.13 (Apr 23, 1999)
- *              Didn't have (stat)? for else clause in tree parser.
- *              Didn't gen ASTs for interface extends.  Updated tree parser too.
- *              Updated to 2.6.0.
- * Version 1.14 (Jun 20, 1999)
- *              Allowed final/abstract on local classes.
- *              Removed local interfaces from methods
- *              Put instanceof precedence where it belongs...in relationalExpr
- *                      It also had expr not type as arg; fixed it.
- *              Missing ! on SEMI in classBlock
- *              fixed: (expr) + "string" was parsed incorrectly (+ as unary plus).
- *              fixed: didn't like Object[].class in parser or tree parser
- * Version 1.15 (Jun 26, 1999)
- *              Screwed up rule with instanceof in it. :(  Fixed.
- *              Tree parser didn't like (expr).something; fixed.
- *              Allowed multiple inheritance in tree grammar. oops.
- * Version 1.16 (August 22, 1999)
- *              Extending an interface built a wacky tree: had extra EXTENDS.
- *              Tree grammar didn't allow multiple superinterfaces.
- *              Tree grammar didn't allow empty var initializer: {}
- * Version 1.17 (October 12, 1999)
- *              ESC lexer rule allowed 399 max not 377 max.
- *              java.tree.g didn't handle the expression of synchronized
- *              statements.
- * Version 1.18 (August 12, 2001)
- *              Terence updated to Java 2 Version 1.3 by
- *              observing/combining work of Allan Jacobs and Steve
- *              Messick.  Handles 1.3 src.  Summary:
- *              o  primary didn't include boolean.class kind of thing
- *              o  constructor calls parsed explicitly now:
- *                 see explicitConstructorInvocation
- *              o  add strictfp modifier
- *              o  missing objBlock after new expression in tree grammar
- *              o  merged local class definition alternatives, moved after declaration
- *              o  fixed problem with ClassName.super.field
- *              o  reordered some alternatives to make things more efficient
- *              o  long and double constants were not differentiated from int/float
- *              o  whitespace rule was inefficient: matched only one char
- *              o  add an examples directory with some nasty 1.3 cases
- *              o  made Main.java use buffered IO and a Reader for Unicode support
- *              o  supports UNICODE?
- *                 Using Unicode charVocabulary makes code file big, but only
- *                 in the bitsets at the end. I need to make ANTLR generate
- *                 unicode bitsets more efficiently.
- * Version 1.19 (April 25, 2002)
- *              Terence added in nice fixes by John Pybus concerning floating
- *              constants and problems with super() calls.  John did a nice
- *              reorg of the primary/postfix expression stuff to read better
- *              and makes f.g.super() parse properly (it was METHOD_CALL not
- *              a SUPER_CTOR_CALL).  Also:
- *
- *              o  "finally" clause was a root...made it a child of "try"
- *              o  Added stuff for asserts too for Java 1.4, but *commented out*
- *                 as it is not backward compatible.
- *
- * Version 1.20 (October 27, 2002)
- *
- *        Terence ended up reorging John Pybus' stuff to
- *        remove some nondeterminisms and some syntactic predicates.
- *        Note that the grammar is stricter now; e.g., this(...) must
- *      be the first statement.
- *
- *        Trinary ?: operator wasn't working as array name:
- *                (isBig ? bigDigits : digits)[i];
- *
- *        Checked parser/tree parser on source for
- *                Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4,
- *              and the 110k-line jGuru server source.
- *
- * Version 1.21 (October 17, 2003)
- *  Fixed lots of problems including:
- *  Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g
- *  He found a problem/fix with floating point that start with 0
- *  Ray also fixed problem that (int.class) was not recognized.
- *  Thorsten van Ellen noticed that \n are allowed incorrectly in strings.
- *  TJP fixed CHAR_LITERAL analogously.
- *
- * Version 1.21.2 (March, 2003)
- *        Changes by Matt Quail to support generics (as per JDK1.5/JSR14)
- *        Notes:
- *        o We only allow the "extends" keyword and not the "implements"
- *              keyword, since that's what JSR14 seems to imply.
- *        o Thanks to Monty Zukowski for his help on the antlr-interest
- *              mail list.
- *        o Thanks to Alan Eliasen for testing the grammar over his
- *              Fink source base
- *
- * Version 1.22 (July, 2004)
- *        Changes by Michael Studman to support Java 1.5 language extensions
- *        Notes:
- *        o Added support for annotations types
- *        o Finished off Matt Quail's generics enhancements to support bound type arguments
- *        o Added support for new for statement syntax
- *        o Added support for static import syntax
- *        o Added support for enum types
- *        o Tested against JDK 1.5 source base and source base of jdigraph project
- *        o Thanks to Matt Quail for doing the hard part by doing most of the generics work
- *
- * Version 1.22.1 (July 28, 2004)
- *        Bug/omission fixes for Java 1.5 language support
- *        o Fixed tree structure bug with classOrInterface - thanks to Pieter Vangorpto for
- *              spotting this
- *        o Fixed bug where incorrect handling of SR and BSR tokens would cause type
- *              parameters to be recognised as type arguments.
- *        o Enabled type parameters on constructors, annotations on enum constants
- *              and package definitions
- *        o Fixed problems when parsing if ((char.class.equals(c))) {} - solution by Matt Quail at Cenqua
- *
- * Version 1.22.2 (July 28, 2004)
- *        Slight refactoring of Java 1.5 language support
- *        o Refactored for/"foreach" productions so that original literal "for" literal
- *          is still used but the for sub-clauses vary by token type
- *        o Fixed bug where type parameter was not included in generic constructor's branch of AST
- *
- * Version 1.22.3 (August 26, 2004)
- *        Bug fixes as identified by Michael Stahl; clean up of tabs/spaces
- *        and other refactorings
- *        o Fixed typeParameters omission in identPrimary and newStatement
- *        o Replaced GT reconcilliation code with simple semantic predicate
- *        o Adapted enum/assert keyword checking support from Michael Stahl's java15 grammar
- *        o Refactored typeDefinition production and field productions to reduce duplication
- *
- * Version 1.22.4 (October 21, 2004)
- *    Small bux fixes
- *    o Added typeArguments to explicitConstructorInvocation, e.g. new <String>MyParameterised()
- *    o Added typeArguments to postfixExpression productions for anonymous inner class super
- *      constructor invocation, e.g. new Outer().<String>super()
- *    o Fixed bug in array declarations identified by Geoff Roy
- *
- * Version 1.22.4.g.1
- *    o I have taken java.g for Java1.5 from Michael Studman (1.22.4)
- *      and have applied the groovy.diff from java.g (1.22) by John Rose
- *      back onto the new root (1.22.4) - Jeremy Rayner (Jan 2005)
- *
- * Version 1.22.4.g.2
- *    o mkempf, rkleeb, Dec 2007
- *    o fixed various rules so that they call the correct Create Method
- *      to make sure that the line information are correct
- *
- * Based on an original grammar released in the PUBLIC DOMAIN
- */
-
-class GroovyRecognizer extends Parser;
-options {
-    k = 2;                            // two token lookahead
-    exportVocab=Groovy;               // Call its vocabulary "Groovy"
-    codeGenMakeSwitchThreshold = 2;   // Some optimizations
-    codeGenBitsetTestThreshold = 3;
-    defaultErrorHandler = false;      // Don't generate parser error handlers
-    buildAST = true;
-}
-
-tokens {
-    BLOCK; MODIFIERS; OBJBLOCK; SLIST; METHOD_DEF; VARIABLE_DEF;
-    INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; TRAIT_DEF;
-    PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE;
-    PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP;
-    POST_INC; POST_DEC; METHOD_CALL; EXPR;
-    IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION;
-    FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract";
-    UNUSED_GOTO="goto"; UNUSED_CONST="const"; UNUSED_DO="do";
-    STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; CTOR_IDENT; VARIABLE_PARAMETER_DEF;
-    STRING_CONSTRUCTOR; STRING_CTOR_MIDDLE;
-    CLOSABLE_BLOCK; IMPLICIT_PARAMETERS;
-    SELECT_SLOT; DYNAMIC_MEMBER;
-    LABELED_ARG; SPREAD_ARG; SPREAD_MAP_ARG; //deprecated - SCOPE_ESCAPE;
-    LIST_CONSTRUCTOR; MAP_CONSTRUCTOR;
-    FOR_IN_ITERABLE;
-    STATIC_IMPORT; ENUM_DEF; ENUM_CONSTANT_DEF; FOR_EACH_CLAUSE; ANNOTATION_DEF; ANNOTATIONS;
-    ANNOTATION; ANNOTATION_MEMBER_VALUE_PAIR; ANNOTATION_FIELD_DEF; ANNOTATION_ARRAY_INIT;
-    TYPE_ARGUMENTS; TYPE_ARGUMENT; TYPE_PARAMETERS; TYPE_PARAMETER; WILDCARD_TYPE;
-    TYPE_UPPER_BOUNDS; TYPE_LOWER_BOUNDS; CLOSURE_LIST;MULTICATCH;MULTICATCH_TYPES;
-}
-
-{
-    /** This factory is the correct way to wire together a Groovy parser and lexer. */
-    public static GroovyRecognizer make(GroovyLexer lexer) {
-        GroovyRecognizer parser = new GroovyRecognizer(lexer.plumb());
-        parser.lexer = lexer;
-        lexer.parser = parser;
-        parser.getASTFactory().setASTNodeClass(GroovySourceAST.class);
-        return parser;
-    }
-    // Create a scanner that reads from the input stream passed to us...
-    public static GroovyRecognizer make(InputStream in) { return make(new GroovyLexer(in)); }
-    public static GroovyRecognizer make(Reader in) { return make(new GroovyLexer(in)); }
-    public static GroovyRecognizer make(InputBuffer in) { return make(new GroovyLexer(in)); }
-    public static GroovyRecognizer make(LexerSharedInputState in) { return make(new GroovyLexer(in)); }
-
-    @SuppressWarnings("unused")
-    private static GroovySourceAST dummyVariableToForceClassLoaderToFindASTClass = new GroovySourceAST();
-
-    List warningList = new ArrayList();
-    public List getWarningList() { return warningList; }
-
-    GroovyLexer lexer;
-    public GroovyLexer getLexer() { return lexer; }
-    public void setFilename(String f) { lexer.setFilename(f); super.setFilename(f); }
-
-    @Deprecated
-    public void setSourceBuffer(SourceBuffer sourceBuffer) {
-    }
-
-    /**
-     * Creates an AST node with the token type and text passed in, but
-     * with the same background information as another supplied Token (e.g.&nbsp;line numbers).
-     * To be used in place of antlr tree construction syntax,
-     * i.e. #[TOKEN,"text"]  becomes  create(TOKEN,"text",anotherToken)
-     */
-    public AST create(int type, String txt, AST first) {
-        AST t = astFactory.create(type,txt);
-        if ( t != null && first != null) {
-            // first copy details from first token
-            t.initialize(first);
-            // then ensure that type and txt are specific to this new node
-            t.initialize(type,txt);
-        }
-        return t;
-    }
-
-    private AST attachLast(AST t, Object last) {
-        if ((t instanceof GroovySourceAST) && (last instanceof SourceInfo)) {
-            SourceInfo lastInfo = (SourceInfo) last;
-            GroovySourceAST node = (GroovySourceAST)t;
-            node.setColumnLast(lastInfo.getColumn());
-            node.setLineLast(lastInfo.getLine());
-            // This is a good point to call node.setSnippet(),
-            // but it bulks up the AST too much for production code.
-        }
-        return t;
-    }
-
-    public AST create(int type, String txt, Token first, Token last) {
-        return attachLast(create(type, txt, astFactory.create(first)), last);
-    }
-
-    public AST create(int type, String txt, AST first, Token last) {
-        return attachLast(create(type, txt, first), last);
-    }
-
-    public AST create(int type, String txt, AST first, AST last) {
-        return attachLast(create(type, txt, first), last);
-    }
-
-    public Token cloneToken(Token t) {
-        CommonToken clone = new CommonToken(t.getType(),t.getText());
-        clone.setLine(t.getLine());
-        clone.setColumn(t.getColumn());
-        return clone;
-    }
-
-    // stuff to adjust ANTLR's tracing machinery
-    public static boolean tracing = false;  // only effective if antlr.Tool is run with -traceParser
-    public void traceIn(String rname) throws TokenStreamException {
-        if (!GroovyRecognizer.tracing)  return;
-        super.traceIn(rname);
-    }
-    public void traceOut(String rname) throws TokenStreamException {
-        if (!GroovyRecognizer.tracing)  return;
-        if (returnAST != null)  rname += returnAST.toStringList();
-        super.traceOut(rname);
-    }
-
-    // Error handling.  This is a funnel through which parser errors go, when the parser can suggest a solution.
-    public void requireFailed(String problem, String solution) throws SemanticException {
-        // TODO: Needs more work.
-        Token lt = null;
-        int lineNum = Token.badToken.getLine(), colNum = Token.badToken.getColumn();
-        try {
-            lt = LT(1);
-            if(lt != null) {
-                lineNum = lt.getLine();
-                colNum = lt.getColumn();
-            }
-        }
-        catch (TokenStreamException ee) {
-            if(ee instanceof TokenStreamRecognitionException) {
-                lineNum = ((TokenStreamRecognitionException) ee).recog.getLine();
-                colNum = ((TokenStreamRecognitionException) ee).recog.getColumn();
-            }
-        }
-        throw new SemanticException(problem + ";\n   solution: " + solution,
-                                    getFilename(), lineNum, colNum);
-    }
-
-    public void addWarning(String warning, String solution) {
-        Token lt = null;
-        try { lt = LT(1); }
-        catch (TokenStreamException ee) { }
-        if (lt == null)  lt = Token.badToken;
-
-        Map row = new HashMap();
-        row.put("warning",  warning);
-        row.put("solution", solution);
-        row.put("filename", getFilename());
-        row.put("line",     Integer.valueOf(lt.getLine()));
-        row.put("column",   Integer.valueOf(lt.getColumn()));
-
-        warningList.add(row);
-    }
-
-    // Convenience method for checking of expected error syndromes.
-    private void require(boolean z, String problem, String solution) throws SemanticException {
-        if (!z)  requireFailed(problem, solution);
-    }
-
-    private boolean matchGenericTypeBrackets(boolean z, String problem, String solution) throws SemanticException {
-        if (!z)  matchGenericTypeBracketsFailed(problem, solution);
-        return z;
-    }
-
-    public void matchGenericTypeBracketsFailed(String problem, String solution) throws SemanticException {
-        Token lt = null;
-        int lineNum = Token.badToken.getLine(), colNum = Token.badToken.getColumn();
-
-        try {
-            lt = LT(1);
-            if(lt != null) {
-                lineNum = lt.getLine();
-                colNum = lt.getColumn();
-            }
-        }
-        catch (TokenStreamException ee) {
-            if(ee instanceof TokenStreamRecognitionException) {
-                lineNum = ((TokenStreamRecognitionException) ee).recog.getLine();
-                colNum = ((TokenStreamRecognitionException) ee).recog.getColumn();
-            }
-        }
-
-        throw new SemanticException(problem + ";\n   solution: " + solution,
-                                    getFilename(), lineNum, colNum);
-   }
-
-    // Query a name token to see if it begins with a capital letter.
-    // This is used to tell the difference (w/o symbol table access) between {String x} and {println x}.
-    private boolean isUpperCase(Token x) {
-        if (x == null || x.getType() != IDENT)  return false;  // cannot happen?
-        String xtext = x.getText();
-        return (xtext.length() > 0 && Character.isUpperCase(xtext.charAt(0)));
-    }
-
-    private AST currentClass = null;  // current enclosing class (for constructor recognition)
-    // Query a name token to see if it is identical with the current class name.
-    // This is used to distinguish constructors from other methods.
-    private boolean isConstructorIdent(Token x) {
-        if (currentClass == null)  return false;
-        if (currentClass.getType() != IDENT)  return false;  // cannot happen?
-        String cname = currentClass.getText();
-
-        if (x == null || x.getType() != IDENT)  return false;  // cannot happen?
-        return cname.equals(x.getText());
-    }
-
-    // Scratch variable for last 'sep' token.
-    // Written by the 'sep' rule, read only by immediate callers of 'sep'.
-    // (Not entirely clean, but better than a million xx=sep occurrences.)
-    private int sepToken = EOF;
-
-    // Scratch variable for last argument list; tells whether there was a label.
-    // Written by 'argList' rule, read only by immediate callers of 'argList'.
-    private boolean argListHasLabels = false;
-
-    // Scratch variable, holds most recently completed pathExpression.
-    // Read only by immediate callers of 'pathExpression' and 'expression'.
-    private AST lastPathExpression = null;
-
-    // Inherited attribute pushed into most expression rules.
-    // If not zero, it means that the left context of the expression
-    // being parsed is a statement boundary or an initializer sign '='.
-    // Only such expressions are allowed to reach across newlines
-    // to pull in an LCURLY and appended block.
-    private final int LC_STMT = 1, LC_INIT = 2;
-
-    /**
-     * Counts the number of LT seen in the typeArguments production.
-     * It is used in semantic predicates to ensure we have seen
-     * enough closing '>' characters; which actually may have been
-     * either GT, SR or BSR tokens.
-     */
-    private int ltCounter = 0;
-
-    /* This symbol is used to work around a known ANTLR limitation.
-     * In a loop with syntactic predicate, ANTLR needs help knowing
-     * that the loop exit is a second alternative.
-     * Example usage:  ( (LCURLY)=> block | {ANTLR_LOOP_EXIT}? )*
-     * Probably should be an ANTLR RFE.
-     */
-    ////// Original comment in Java grammar:
-    // Unfortunately a syntactic predicate can only select one of
-    // multiple alternatives on the same level, not break out of
-    // an enclosing loop, which is why this ugly hack (a fake
-    // empty alternative with always-false semantic predicate)
-    // is necessary.
-    @SuppressWarnings("unused")
-    private static final boolean ANTLR_LOOP_EXIT = false;
-}
-
-// Compilation Unit: In Groovy, this is a single file or script. This is the start
-// rule for this parser
-compilationUnit
-    :
-        // The very first characters of the file may be "#!".  If so, ignore the first line.
-        (SH_COMMENT!)?
-
-        // we can have comments at the top of a file
-        nls!
-
-        // A compilation unit starts with an optional package definition
-        (   (annotationsOpt "package") => packageDefinition
-        |   (statement[EOF])?
-        )
-
-        // The main part of the script is a sequence of any number of statements.
-        // Semicolons and/or significant newlines serve as separators.
-        ( sep! (statement[sepToken])? )*
-        EOF!
-    ;
-
-/** A Groovy script or simple expression.  Can be anything legal inside {...}. */
-snippetUnit
-    :   nls! blockBody[EOF]
-    ;
-
-// Package statement: optional annotations followed by "package" then the package identifier
-packageDefinition
-        {Token first = LT(1);}
-    :   an:annotationsOpt! "package"! id:identifier!
-        {
-            #packageDefinition = #(create(PACKAGE_DEF,"package",first,LT(1)), an, id);
-        }
-    ;
-
-// Import statement: import followed by a package or class name
-importStatement
-        {Token first = LT(1); boolean isStatic = false;}
-    :   an:annotationsOpt "import"! ("static"! {isStatic = true;})? is:identifierStar!
-        {
-            if (!isStatic) {
-                #importStatement = #(create(IMPORT,"import",first,LT(1)), an, is);
-            } else {
-                #importStatement = #(create(STATIC_IMPORT,"static_import",first,LT(1)), an, is);
-            }
-        }
-    ;
-
-// Protected type definitions production for reuse in other productions
-protected typeDefinitionInternal[AST mods]
-    :   cd:classDefinition[#mods]       // inner class
-        {#typeDefinitionInternal = #cd;}
-    |   td:traitDefinition[#mods]       // inner trait
-        {#typeDefinitionInternal = #td;}
-    |   id:interfaceDefinition[#mods]   // inner interface
-        {#typeDefinitionInternal = #id;}
-    |   ed:enumDefinition[#mods]        // inner enum
-        {#typeDefinitionInternal = #ed;}
-    |   ad:annotationDefinition[#mods]  // inner annotation
-        {#typeDefinitionInternal = #ad;}
-    ;
-
-/** A declaration is the creation of a reference or primitive-type variable,
- *  or (if arguments are present) of a method.
- *  Generically, this is called a 'variable' definition, even in the case of a class field or method.
- *  It may start with the modifiers and/or a declaration keyword "def".
- *  It may also start with the modifiers and a capitalized type name.
- *  <p>
- *  AST effect: Create a separate Type/Var tree for each var in the var list.
- *  Must be guarded, as in (declarationStart) => declaration.
- */
-declaration!
-    :
-        // method/variable using a 'def' or a modifier; type is optional
-        m:modifiers
-        (t:typeSpec[false])?
-        v:variableDefinitions[#m, #t]
-        {#declaration = #v;}
-    |
-        // method/variable using a type only
-        t2:typeSpec[false]
-        v2:variableDefinitions[null,#t2]
-        {#declaration = #v2;}
-    ;
-
-genericMethod!
-    :
-        // method using a 'def' or a modifier; type is optional
-        m:modifiers
-        p:typeParameters
-        t:typeSpec[false]
-        v:variableDefinitions[#m, #t]
-        {
-            #genericMethod = #v;
-            AST old = #v.getFirstChild();
-            #genericMethod.setFirstChild(#p);
-            #p.setNextSibling(old);
-        }
-    ;
-
-/** A declaration with one declarator and no initialization, like a parameterDeclaration.
- *  Used to parse loops like <code>for (int x in y)</code> (up to the <code>in</code> keyword).
- */
-singleDeclarationNoInit!
-    :
-        // method/variable using a 'def' or a modifier; type is optional
-        m:modifiers
-        (t:typeSpec[false])?
-        v:singleVariable[#m, #t]
-        {#singleDeclarationNoInit = #v;}
-    |
-        // method/variable using a type only
-        t2:typeSpec[false]
-        v2:singleVariable[null,#t2]
-        {#singleDeclarationNoInit = #v2;}
-    ;
-
-/** A declaration with one declarator and optional initialization, like a parameterDeclaration.
- *  Used to parse declarations used for both binding and effect, in places like argument
- *  lists and <code>while</code> statements.
- */
-singleDeclaration
-    :   sd:singleDeclarationNoInit!
-        { #singleDeclaration = #sd; }
-        (varInitializer)?
-    ;
-
-/** Used only as a lookahead predicate, before diving in and parsing a declaration.
- *  A declaration can be unambiguously introduced with "def", an annotation or a modifier token like "final".
- *  It may also be introduced by a simple identifier whose first character is an uppercase letter,
- *  as in {String x}.  A declaration can also be introduced with a built in type like 'int' or 'void'.
- *  Brackets (array and generic) are allowed, as in {List[] x} or {int[][] y}.
- *  Anything else is parsed as a statement of some sort (expression or command).
- *  <p>
- *  (In the absence of explicit method-call parens, we assume a capitalized name is a type name.
- *  Yes, this is a little hacky.  Alternatives are to complicate the declaration or command
- *  syntaxes, or to have the parser query the symbol table.  Parse-time queries are evil.
- *  And we want both {String x} and {println x}.  So we need a syntactic razor-edge to slip
- *  between 'println' and 'String'.)
- */
-declarationStart!
-    :   (     ("def" nls)
-            | modifier nls
-            | annotation nls
-            | (   upperCaseIdent
-                |   builtInType
-                |   qualifiedTypeName
-              ) (typeArguments)? (LBRACK balancedTokens RBRACK)*
-        )+
-        ( IDENT | STRING_LITERAL )
-    ;
-
-/**
- * lookahead predicate for usage of generics in methods
- * as parameter for the method. Example:
- * static <T> T foo(){}
- * <T> must be first after the modifier.
- * This rule allows more and does no exact match, but it
- * is only a lookahead, not the real rule.
- */
-genericMethodStart!
-    :   (     "def" nls
-            | modifier nls
-            | annotation nls
-        )+ LT
-    ;
-
-qualifiedTypeName!
-    :
-        IDENT DOT (IDENT DOT)* upperCaseIdent
-    ;
-
-/** Used to look ahead for a constructor
- */
-constructorStart!
-    :
-        modifiersOpt! id:IDENT! {isConstructorIdent(id)}? nls! LPAREN!
-    ;
-
-/** Used only as a lookahead predicate for nested type definitions. */
-typeDefinitionStart!
-    :   modifiersOpt! ("class" | "interface" | "enum" | "trait" | AT "interface")
-    ;
-
-/** An IDENT token whose spelling is required to start with an uppercase letter.
- *  In the case of a simple statement {UpperID name} the identifier is taken to be a type name, not a command name.
- */
-upperCaseIdent
-    :   {isUpperCase(LT(1))}?
-        IDENT
-    ;
-
-// A type specification is a type name with possible brackets afterwards
-// (which would make it an array type).
-// Set addImagNode true for types inside expressions, not declarations.
-typeSpec[boolean addImagNode]
-    :    classTypeSpec[addImagNode]
-    |    builtInTypeSpec[addImagNode]
-    ;
-
-// also check that 'classOrInterfaceType[false]' is a suitable substitution for 'identifier'
-
-// A class type specification is a class type with either:
-// - possible brackets afterwards
-//   (which would make it an array type).
-// - generic type arguments after
-classTypeSpec[boolean addImagNode]  {Token first = LT(1);}
-    :   ct:classOrInterfaceType[false]!
-        declaratorBrackets[#ct]
-        {
-            if ( addImagNode ) {
-                #classTypeSpec = #(create(TYPE,"TYPE",first,LT(1)), #classTypeSpec);
-            }
-        }
-    ;
-
-// A non-built in type name, with possible type parameters
-classOrInterfaceType[boolean addImagNode]  {Token first = LT(1);}
-    :   i1:IDENT^ (typeArguments|typeArgumentsDiamond)?
-
-        (   options{greedy=true;}: // match as many as possible
-            d:DOT!
-            i2:IDENT! (ta:typeArguments!)?
-            {#i1 = #(create(DOT,".",first,LT(1)), i1, i2, ta);}
-        )*
-        {
-            #classOrInterfaceType = #i1;
-            if ( addImagNode ) {
-                #classOrInterfaceType = #(create(TYPE,"TYPE",first,LT(1)), #classOrInterfaceType);
-            }
-        }
-    ;
-
-// A specialised form of typeSpec where built in types must be arrays
-typeArgumentSpec
-    :   classTypeSpec[true]
-    |   builtInTypeArraySpec[true]
-    ;
-
-// A generic type argument is a class type, a possibly bounded wildcard type or a built-in type array
-typeArgument  {Token first = LT(1);}
-    :   (   typeArgumentSpec
-        |   wildcardType
-        )
-        {#typeArgument = #(create(TYPE_ARGUMENT,"TYPE_ARGUMENT",first,LT(1)), #typeArgument);}
-    ;
-
-// Wildcard type indicating all types (with possible constraint)
-wildcardType
-    :   QUESTION
-        (("extends" | "super") => typeArgumentBounds)?
-        {#wildcardType.setType(WILDCARD_TYPE);}
-    ;
-
-typeArgumentsDiamond
-{Token first = LT(1);}
-    :   LT! GT! nls!
-    {#typeArgumentsDiamond = #(create(TYPE_ARGUMENTS,"TYPE_ARGUMENTS",first,LT(1)), #typeArgumentsDiamond);}
-    ;
-
-// Type arguments to a class or interface type
-typeArguments
-{Token first = LT(1);
-int currentLtLevel = 0;}
-    :
-        {currentLtLevel = ltCounter;}
-        LT! {ltCounter++;} nls!
-        typeArgument
-        (   options{greedy=true;}: // match as many as possible
-            {inputState.guessing !=0 || ltCounter == currentLtLevel + 1}?
-            COMMA! nls! typeArgument
-        )*
-        nls!
-        (   // turn warning off since Antlr generates the right code,
-            // plus we have our semantic predicate below
-            options{generateAmbigWarnings=false;}:
-            typeArgumentsOrParametersEnd
-        )?
-
-        // make sure we have gobbled up enough '>' characters
-        // if we are at the "top level" of nested typeArgument productions
-        {matchGenericTypeBrackets(((currentLtLevel != 0) || ltCounter == currentLtLevel),
-        "Missing closing bracket '>' for generics types", "Please specify the missing bracket!")}?
-
-        {#typeArguments = #(create(TYPE_ARGUMENTS,"TYPE_ARGUMENTS",first,LT(1)), #typeArguments);}
-    ;
-
-// this gobbles up *some* amount of '>' characters, and counts how many
-// it gobbled.
-protected typeArgumentsOrParametersEnd
-    :   GT! {ltCounter-=1;}
-    |   SR! {ltCounter-=2;}
-    |   BSR! {ltCounter-=3;}
-    ;
-
-// Restriction on wildcard types based on super class or derived class
-typeArgumentBounds
-    {Token first = LT(1);boolean isUpperBounds = false;}
-    :
-        ( "extends"! {isUpperBounds=true;} | "super"! ) nls! classOrInterfaceType[true] nls!
-        {
-            if (isUpperBounds)
-            {
-                #typeArgumentBounds = #(create(TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS",first,LT(1)), #typeArgumentBounds);
-            }
-            else
-            {
-                #typeArgumentBounds = #(create(TYPE_LOWER_BOUNDS,"TYPE_LOWER_BOUNDS",first,LT(1)), #typeArgumentBounds);
-            }
-        }
-    ;
-
-// A builtin type array specification is a builtin type with brackets afterwards
-builtInTypeArraySpec[boolean addImagNode]  {Token first = LT(1);}
-    :   bt:builtInType!
-        (   (LBRACK)=>   // require at least one []
-            declaratorBrackets[#bt]
-        |   {require(false,
-                          "primitive type parameters not allowed here",
-                           "use the corresponding wrapper type, such as Integer for int"
-                           );}
-        )
-        {
-            if ( addImagNode ) {
-                #builtInTypeArraySpec = #(create(TYPE,"TYPE",first,LT(1)), #builtInTypeArraySpec);
-            }
-        }
-    ;
-
-// A builtin type specification is a builtin type with possible brackets
-// afterwards (which would make it an array type).
-builtInTypeSpec[boolean addImagNode]  {Token first = LT(1);}
-    :   bt:builtInType!
-        declaratorBrackets[#bt]
-        {
-            if ( addImagNode ) {
-                #builtInTypeSpec = #(create(TYPE,"TYPE",first,LT(1)), #builtInTypeSpec);
-            }
-        }
-    ;
-
-// A type name. which is either a (possibly qualified and parameterized)
-// class name or a primitive (builtin) type
-type
-    :   classOrInterfaceType[false]
-    |   builtInType
-    ;
-
-// The primitive types.
-builtInType
-    :   "void"
-    |   "boolean"
-    |   "byte"
-    |   "char"
-    |   "short"
-    |   "int"
-    |   "float"
-    |   "long"
-    |   "double"
-    ;
-
-// A (possibly-qualified) java identifier. We start with the first IDENT
-// and expand its name by adding dots and following IDENTS
-identifier {Token first = LT(1);}
-    :   i1:IDENT!
-        (   options { greedy = true; } :
-            d:DOT! nls! i2:IDENT!
-            {#i1 = #(create(DOT,".",first,LT(1)), i1, i2);}
-        )*
-        {#identifier = #i1;}
-    ;
-
-identifierStar {Token first = LT(1);}
-    :   i1:IDENT!
-        (   options { greedy = true; } :
-            d1:DOT! nls! i2:IDENT!
-            {#i1 = #(create(DOT,".",first,LT(1)), i1, i2);}
-        )*
-        (   d2:DOT!  nls! s:STAR!
-            {#i1 = #(create(DOT,".",first,LT(1)), i1, s);}
-        |   "as"! nls! alias:IDENT!
-            {#i1 = #(create(LITERAL_as,"as",first,LT(1)), i1, alias);}
-        )?
-        {#identifierStar = #i1;}
-    ;
-
-modifiersInternal
-        { int seenDef = 0; }
-    :
-        (
-            // Without this hush, there is a warning that @IDENT and @interface
-            // can follow modifiersInternal.  But how is @IDENT possible after
-            // modifiersInternal?  And how is @interface possible inside modifiersInternal?
-            // Is there an antlr bug?
-            options{generateAmbigWarnings=false;}:
-
-            // 'def' is an empty modifier, for disambiguating declarations
-            {seenDef++ == 0}?       // do not allow multiple "def" tokens
-            "def"! nls!
-        |
-            // Note: Duplication of modifiers is detected when walking the AST.
-            modifier nls!
-        |
-            {break; /* go out of the ()+ loop*/}
-            AT "interface"
-        |
-            annotation nls!
-        )+
-    ;
-
-/** A list of one or more modifier, annotation, or "def". */
-modifiers  {Token first = LT(1);}
-    :   modifiersInternal
-        {#modifiers = #(create(MODIFIERS,"MODIFIERS",first,LT(1)), #modifiers);}
-    ;
-
-/** A list of zero or more modifiers, annotations, or "def". */
-modifiersOpt  {Token first = LT(1);}
-    :   (
-            // See comment above on hushing warnings.
-            options{generateAmbigWarnings=false;}:
-            modifiersInternal
-        )?
-        {#modifiersOpt = #(create(MODIFIERS,"MODIFIERS",first,LT(1)), #modifiersOpt);}
-    ;
-
-// modifiers for Java classes, interfaces, class/instance vars and methods
-modifier
-    :   "private"
-    |   "public"
-    |   "protected"
-    |   "static"
-    |   "transient"
-    |   "final"
-    |   "abstract"
-    |   "native"
-    |   "threadsafe"
-    |   "synchronized"
-    |   "volatile"
-    |   "strictfp"
-    ;
-
-annotation!  {Token first = LT(1);}
-    :   AT! i:identifier nls! (options{greedy=true;}: LPAREN! (args:annotationArguments)? RPAREN!)?
-        {#annotation = #(create(ANNOTATION,"ANNOTATION",first,LT(1)), i, args);}
-    ;
-
-annotationsInternal
-    :   (
-            options{generateAmbigWarnings=false;}:
-            {break; /* go out of the ()* loop*/}
-            AT "interface"
-        |
-            annotation nls!
-        )*
-    ;
-
-annotationsOpt  {Token first = LT(1);}
-    :   (
-            // See comment above on hushing warnings.
-            options{generateAmbigWarnings=false;}:
-            annotationsInternal
-        )?
-        {#annotationsOpt = #(create(ANNOTATIONS,"ANNOTATIONS",first,LT(1)), #annotationsOpt);}
-    ;
-
-annotationArguments
-    :   v:annotationMemberValueInitializer
-        {Token itkn = new Token(IDENT,"value"); AST i; #i = #(create(IDENT,"value",itkn,itkn));
-         #annotationArguments = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",LT(1),LT(1)), i, v);}
-        | annotationMemberValuePairs
-    ;
-
-annotationMemberValuePairs
-    :   annotationMemberValuePair (
-            COMMA! nls! annotationMemberValuePair
-        )*
-    ;
-
-annotationMemberValuePair!  {Token first = LT(1);}
-    :   i:annotationIdent ASSIGN! nls! v:annotationMemberValueInitializer
-        {#annotationMemberValuePair = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",first,LT(1)), i, v);}
-    ;
-
-annotationIdent
-    :   IDENT
-    |   keywordPropertyNames
-    ;
-
-annotationMemberValueInitializer
-    :   conditionalExpression[0] | annotation
-    ;
-
-superClassClause!
-    {Token first = LT(1);}
-    :
-        ( "extends" nls! c:classOrInterfaceType[false] nls! )?
-        {#superClassClause = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)), c);}
-    ;
-
-// Definition of a Java class
-classDefinition![AST modifiers]
-{Token first = cloneToken(LT(1));AST prevCurrentClass = currentClass;
-if (modifiers != null) {
-     first.setLine(modifiers.getLine());
-     first.setColumn(modifiers.getColumn());
-}}
-    :   "class" IDENT nls!
-       { currentClass = #IDENT; }
-        // it _might_ have type parameters
-        (tp:typeParameters nls!)?
-        // it _might_ have a superclass...
-        sc:superClassClause
-        // it might implement some interfaces...
-        ic:implementsClause
-        // now parse the body of the class
-        cb:classBlock
-        {#classDefinition = #(create(CLASS_DEF,"CLASS_DEF",first,LT(1)), modifiers, IDENT, tp, sc, ic, cb);}
-        { currentClass = prevCurrentClass; }
-    ;
-
-// Definition of a Trait
-traitDefinition![AST modifiers]
-{Token first = cloneToken(LT(1));AST prevCurrentClass = currentClass;
-if (modifiers != null) {
-     first.setLine(modifiers.getLine());
-     first.setColumn(modifiers.getColumn());
-}}
-    :   "trait" IDENT nls!
-       { currentClass = #IDENT; }
-        // it _might_ have type parameters
-        (tp:typeParameters nls!)?
-        // it _might_ have a superclass...
-        sc:superClassClause
-        // it might implement some interfaces...
-        ic:implementsClause
-        // now parse the body of the class
-        cb:classBlock
-        {#traitDefinition = #(create(TRAIT_DEF,"TRAIT_DEF",first,LT(1)), modifiers, IDENT, tp, sc, ic, cb);}
-        { currentClass = prevCurrentClass; }
-    ;
-
-// Definition of a Java Interface
-interfaceDefinition![AST modifiers]  {Token first = cloneToken(LT(1));
-                                      if (modifiers != null) {
-                                          first.setLine(modifiers.getLine());
-                                          first.setColumn(modifiers.getColumn());
-                                      }}
-    :   "interface" IDENT nls!
-        // it _might_ have type parameters
-        (tp:typeParameters nls!)?
-        // it might extend some other interfaces
-        ie:interfaceExtends
-        // now parse the body of the interface (looks like a class...)
-        ib:interfaceBlock
-        {#interfaceDefinition = #(create(INTERFACE_DEF,"INTERFACE_DEF",first,LT(1)), modifiers, IDENT, tp, ie, ib);}
-    ;
-
-enumDefinition![AST modifiers]  {Token first = cloneToken(LT(1)); AST prevCurrentClass = currentClass;
-                                 if (modifiers != null) {
-                                     first.setLine(modifiers.getLine());
-                                     first.setColumn(modifiers.getColumn());
-                                 }}
-    :   "enum" IDENT
-            { currentClass = #IDENT; }
-        nls!
-        // it might implement some interfaces...
-        ic:implementsClause
-        nls!
-        // now parse the body of the enum
-        eb:enumBlock
-        {#enumDefinition = #(create(ENUM_DEF,"ENUM_DEF",first,LT(1)), modifiers, IDENT, ic, eb);}
-        { currentClass = prevCurrentClass; }
-    ;
-
-annotationDefinition![AST modifiers]  {Token first = cloneToken(LT(1));
-                                      if (modifiers != null) {
-                                          first.setLine(modifiers.getLine());
-                                          first.setColumn(modifiers.getColumn());
-                                      }}
-    :   AT "interface" IDENT nls!
-        // now parse the body of the annotation
-        ab:annotationBlock
-        {#annotationDefinition = #(create(ANNOTATION_DEF,"ANNOTATION_DEF",first,LT(1)), modifiers, IDENT, ab);}
-    ;
-
-typeParameters
-{Token first = LT(1);int currentLtLevel = 0;}
-    :
-        {currentLtLevel = ltCounter;}
-        LT! {ltCounter++;} nls!
-        typeParameter (COMMA! nls! typeParameter)*
-        nls!
-        (typeArgumentsOrParametersEnd)?
-
-        // make sure we have gobbled up enough '>' characters
-        // if we are at the "top level" of nested typeArgument productions
-        {matchGenericTypeBrackets(((currentLtLevel != 0) || ltCounter == currentLtLevel),
-        "Missing closing bracket '>' for generics types", "Please specify the missing bracket!")}?
-
-        {#typeParameters = #(create(TYPE_PARAMETERS,"TYPE_PARAMETERS",first,LT(1)), #typeParameters);}
-    ;
-
-typeParameter  {Token first = LT(1);}
-    :
-        // I'm pretty sure Antlr generates the right thing here:
-        (id:IDENT) ( options{generateAmbigWarnings=false;}: typeParameterBounds )?
-        {#typeParameter = #(create(TYPE_PARAMETER,"TYPE_PARAMETER",first,LT(1)), #typeParameter);}
-    ;
-
-typeParameterBounds  {Token first = LT(1);}
-    :
-        "extends"! nls! classOrInterfaceType[true]
-        (BAND! nls! classOrInterfaceType[true])*
-        {#typeParameterBounds = #(create(TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS",first,LT(1)), #typeParameterBounds);}
-    ;
-
-// This is the body of a class. You can have classFields and extra semicolons.
-classBlock  {Token first = LT(1);}
-    :   LCURLY!
-        ( classField )? ( sep! ( classField )? )*
-        RCURLY!
-        {#classBlock = #(create(OBJBLOCK,"OBJBLOCK",first,LT(1)), #classBlock);}
-    ;
-
-// This is the body of an interface. You can have interfaceField and extra semicolons.
-interfaceBlock  {Token first = LT(1);}
-    :   LCURLY!
-        ( interfaceField )? ( sep! ( interfaceField )? )*
-        RCURLY!
-        {#interfaceBlock = #(create(OBJBLOCK,"OBJBLOCK",first,LT(1)), #interfaceBlock);}
-    ;
-
-// This is the body of an annotation. You can have annotation fields and extra semicolons,
-// That's about it (until you see what an annotation field is...)
-annotationBlock  {Token first = LT(1);}
-    :   LCURLY!
-        ( annotationField )? ( sep! ( annotationField )? )*
-        RCURLY!
-        {#annotationBlock = #(create(OBJBLOCK,"OBJBLOCK",first,LT(1)), #annotationBlock);}
-    ;
-
-// This is the body of an enum. You can have zero or more enum constants
-// followed by any number of fields like a regular class
-enumBlock  {Token first = LT(1);}
-    :   LCURLY! nls!
-        (
-            // Need a syntactic predicate, since enumConstants
-            // can start with foo() as well as classField.
-            // (It's a true ambiguity, visible in the specification.
-            // To resolve in practice, use "def" before a real method.)
-            (enumConstantsStart) => enumConstants
-        |   (classField)?
-        )
-        ( sep! (classField)? )*
-        RCURLY!
-        {#enumBlock = #(create(OBJBLOCK,"OBJBLOCK",first,LT(1)), #enumBlock);}
-    ;
-
-/** Guard for enumConstants. */
-enumConstantsStart
-    :   annotationsOpt IDENT (LCURLY | LPAREN | nls (SEMI | COMMA | declarationStart | RCURLY))
-    ;
-
-/** Comma-separated list of one or more enum constant definitions. */
-enumConstants
-    :
-        enumConstant
-        ( options {generateAmbigWarnings=false;} :
-            (nls enumConstantsEnd) => {break;} // GROOVY-4438, GROOVY-9184
-        |
-            nls! COMMA! (
-                (nls enumConstantsEnd) => {break;} // GROOVY-8507, GROOVY-9301
-            |
-                (nls annotationsOpt IDENT) => nls! enumConstant
-            |
-                (nls classField) => {break;}
-            )
-        )*
-    ;
-
-enumConstantsEnd
-    options {generateAmbigWarnings=false;}
-    :   SEMI | RCURLY | declarationStart | constructorStart | typeDefinitionStart
-    ;
-
-// An annotation field
-annotationField!  {Token first = LT(1);}
-    :   mods:modifiersOpt!
-        (   td:typeDefinitionInternal[#mods]
-            {#annotationField = #td;}
-        |   t:typeSpec[false]               // annotation field
-            (
-                // Need a syntactic predicate, since variableDefinitions
-                // can start with foo() also.  Since method defs are not legal
-                // in this context, there's no harm done.
-                (IDENT LPAREN)=>
-                i:IDENT              // the name of the field
-                LPAREN! RPAREN!
-
-                ( "default" nls! amvi:annotationMemberValueInitializer )?
-
-                {#annotationField = #(create(ANNOTATION_FIELD_DEF,"ANNOTATION_FIELD_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)), t), i, amvi);}
-            |   v:variableDefinitions[#mods,#t]    // variable
-                {#annotationField = #v;}
-            )
-        )
-    ;
-
-//An enum constant may have optional parameters and may have a
-//a class body
-enumConstant!  {Token first = LT(1);}
-    :   an:annotationsOpt // Note:  Cannot start with "def" or another modifier.
-        i:IDENT
-        (   LPAREN!
-            a:argList
-            RPAREN!
-        )?
-        ( b:enumConstantBlock )?
-        {#enumConstant = #(create(ENUM_CONSTANT_DEF,"ENUM_CONSTANT_DEF",first,LT(1)), an, i, a, b);}
-    ;
-
-//The class-like body of an enum constant
-enumConstantBlock  {Token first = LT(1);}
-    :   LCURLY!
-        (enumConstantField)? ( sep! (enumConstantField)? )*
-        RCURLY!
-        {#enumConstantBlock = #(create(OBJBLOCK,"OBJBLOCK",first,LT(1)), #enumConstantBlock);}
-    ;
-
-//An enum constant field is just like a class field but without
-//the possibility of a constructor definition or a static initializer
-
-// TODO - maybe allow 'declaration' production within this production,
-// but how to disallow constructors and static initializers...
-enumConstantField! {Token first = LT(1);}
-    :   (
-            (typeDefinitionStart)=>
-            mods:modifiersOpt!
-            td:typeDefinitionInternal[#mods]
-            {#enumConstantField = #td;}
-        |
-            (modifiers)=>
-            m1:modifiers
-            (tp1:typeParameters)? (t1:typeSpec[false])?
-            e1:enumConstantFieldInternal[#m1, #tp1, #t1, #first]
-            {#enumConstantField = #e1;}
-        |
-            m2:modifiersOpt!
-            (tp2:typeParameters)? t2:typeSpec[false]
-            e2:enumConstantFieldInternal[#m2, #tp2, #t2, #first]
-            {#enumConstantField = #e2;}
-        )
-    |   cs:compoundStatement
-        {#enumConstantField = #(create(INSTANCE_INIT,"INSTANCE_INIT",first,LT(1)), cs);}
-    ;
-
-protected enumConstantFieldInternal![AST mods, AST tp, AST t, Token first]
-    :
-        // Need a syntactic predicate to avoid potential ambiguity
-        (IDENT LPAREN)=>
-        IDENT
-
-        // parse the formal parameter declarations.
-        LPAREN! param:parameterDeclarationList RPAREN!
-
-        // get the list of declared exceptions
-        ((nls "throws") => tc:throwsClause)?
-
-        ( s2:compoundStatement )?
-        {
-            #enumConstantFieldInternal = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)),
-                    mods,
-                    #(create(TYPE,"TYPE",first,LT(1)), t),
-                    IDENT,
-                    param,
-                    tc,
-                    s2);
-            if (tp != null) {
-                AST old = #enumConstantFieldInternal.getFirstChild();
-                #enumConstantFieldInternal.setFirstChild(#tp);
-                #tp.setNextSibling(old);
-            }
-        }
-
-    |   v:variableDefinitions[#mods,#t]
-        {#enumConstantFieldInternal = #v;}
-    ;
-
-// An interface can extend several other interfaces...
-interfaceExtends  {Token first = LT(1);}
-    :   (
-            e:"extends"! nls!
-            classOrInterfaceType[true] ( COMMA! nls! classOrInterfaceType[true] )* nls!
-        )?
-        {#interfaceExtends = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)), #interfaceExtends);}
-    ;
-
-// A class can implement several interfaces...
-implementsClause  {Token first = LT(1);}
-    :   (
-            i:"implements"! nls!
-            classOrInterfaceType[true] ( COMMA! nls! classOrInterfaceType[true] )* nls!
-        )?
-        {#implementsClause = #(create(IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE",first,LT(1)), #implementsClause);}
-    ;
-
-// Now the various things that can be defined inside a class
-classField!  {Token first = LT(1);}
-    :   // method, constructor, or variable declaration
-        (constructorStart)=>
-        mc:modifiersOpt! ctor:constructorDefinition[#mc]
-        {#classField = #ctor;}
-    |
-        (genericMethodStart)=>
-        dg:genericMethod
-        {#classField = #dg;}
-    |
-        (multipleAssignmentDeclarationStart)=>
-        mad:multipleAssignmentDeclaration
-        {#classField = #mad;}
-    |
-        (declarationStart)=>
-        dd:declaration
-        {#classField = #dd;}
-    |
-        // type definition
-        (typeDefinitionStart)=>
-        mods:modifiersOpt!
-        (   td:typeDefinitionInternal[#mods]
-                {#classField = #td;}
-        )
-
-    // "static { ... }" class initializer
-    |   "static" nls! s3:compoundStatement
-        {#classField = #(create(STATIC_INIT,"STATIC_INIT",first,LT(1)), s3);}
-
-    // "{ ... }" instance initializer
-    |   s4:compoundStatement
-        {#classField = #(create(INSTANCE_INIT,"INSTANCE_INIT",first,LT(1)), s4);}
-    ;
-
-// Now the various things that can be defined inside an interface
-interfaceField!
-    :   // method or variable declaration or inner interface
-        (declarationStart)=>
-        d:declaration
-        {#interfaceField = #d;}
-    |
-        (genericMethodStart)=>
-        dg:genericMethod
-        {#interfaceField = #dg;}
-    |
-        // type definition
-        (typeDefinitionStart)=>
-        mods:modifiersOpt
-        (   td:typeDefinitionInternal[#mods]
-            {#interfaceField = #td;}
-        )
-    ;
-
-constructorBody  {Token first = LT(1);}
-     :   LCURLY! nls!
-         (   (explicitConstructorInvocation) =>   // Java compatibility hack
-                 eci:explicitConstructorInvocation! (sep! bb1:blockBody[sepToken]!)?
-             |   bb2:blockBody[EOF]!
-         )
-         RCURLY!
-         {LT(0).setColumn(LT(0).getColumn() + 1);
-          if (#eci != null)
-              #constructorBody = #(create(SLIST,"{",first,LT(0)), eci, bb1);
-          else
-              #constructorBody = #(create(SLIST,"{",first,LT(0)), bb2);
-         }
-     ;
-
-/** Catch obvious constructor calls, but not the expr.super(...) calls */
-explicitConstructorInvocation
-    :   (typeArguments)?
-        (   "this"! lp1:LPAREN^ argList RPAREN!
-            {#lp1.setType(CTOR_CALL);}
-        |   "super"! lp2:LPAREN^ argList RPAREN!
-            {#lp2.setType(SUPER_CTOR_CALL);}
-        )
-    ;
-
-listOfVariables[AST mods, AST t, Token first]
-    :
-        variableDeclarator[getASTFactory().dupTree(mods),
-                           getASTFactory().dupTree(t),first]
-        (   COMMA! nls!
-            {first = LT(1);}
-            variableDeclarator[getASTFactory().dupTree(mods),
-                               getASTFactory().dupTree(t),first]
-        )*
-    ;
-
-multipleAssignmentDeclarationStart
-    :
-        (modifier nls | annotation nls)* "def" nls LPAREN
-    ;
-
-typeNamePairs[AST mods, Token first]
-    :
-        (t:typeSpec[false]!)?
-        singleVariable[getASTFactory().dupTree(mods),#t]
-        (   COMMA! nls!
-            {first = LT(1);}
-            (tn:typeSpec[false]!)?
-            singleVariable[getASTFactory().dupTree(mods),#tn]
-        )*
-    ;
-
-multipleAssignmentDeclaration {Token first = cloneToken(LT(1));}
-    :
-        mods:modifiers!
-        (t:typeSpec[false]!)?
-        LPAREN^ nls! typeNamePairs[#mods,first] RPAREN!
-        ASSIGN^ nls!
-        (
-          (LPAREN nls IDENT (COMMA nls IDENT)* RPAREN ASSIGN) => multipleAssignment[0]
-          | assignmentExpression[0]
-        )
-        {#multipleAssignmentDeclaration=#(create(VARIABLE_DEF,"VARIABLE_DEF",first,LT(1)), #mods, #(create(TYPE,"TYPE",first,LT(1)), #t), #multipleAssignmentDeclaration);}
-    ;
-
-/** The tail of a declaration.
-  * Either v1, v2, ... (with possible initializers) or else m(args){body}.
-  * The two arguments are the modifier list (if any) and the declaration head (if any).
-  * The declaration head is the variable type, or (for a method) the return type.
-  * If it is missing, then the variable type is taken from its initializer (if there is one).
-  * Otherwise, the variable type defaults to 'any'.
-  * DECIDE:  Method return types default to the type of the method body, as an expression.
-  */
-variableDefinitions[AST mods, AST t] {Token first = cloneToken(LT(1));
-                       if (mods != null) {
-                           first.setLine(mods.getLine());
-                           first.setColumn(mods.getColumn());
-                       } else if (t != null) {
-                           first.setLine(t.getLine());
-                           first.setColumn(t.getColumn());
-                       }}
-    :
-        listOfVariables[mods,t,first]
-    |
-        // The parser allows a method definition anywhere a variable definition is accepted.
-
-        (   id:IDENT
-        |   qid:STRING_LITERAL          {#qid.setType(IDENT);}  // use for operator definitions, etc.
-        )
-
-        // parse the formal parameter declarations.
-        LPAREN! param:parameterDeclarationList! RPAREN!
-
-        // get the list of exceptions that this method is
-        // declared to throw
-        ((nls "throws") => tc:throwsClause!)?
-
-        // the method body is an open block
-        // but, it may have an optional constructor call (for constructors only)
-        // this constructor clause is only used for constructors using 'def'
-        // which look like method declarations
-        // since the block is optional and nls is part of sep we have to be sure
-        // a newline is followed by a block or ignore the nls too
-        ((nls! LCURLY) => (nlsWarn! mb:openBlock!))?
-
-        {
-         if (#qid != null) #id = #qid;
-         #variableDefinitions = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)), t), id, param, tc, mb);
-        }
-    ;
-
-/** I've split out constructors separately; we could maybe integrate back into variableDefinitions
- *  later on if we maybe simplified 'def' to be a type declaration?
- */
-constructorDefinition[AST mods]  {Token first = cloneToken(LT(1));
-                                  if (mods != null) {
-                                           first.setLine(mods.getLine());
-                                           first.setColumn(mods.getColumn());
-                                  }}
-    :
-        id:IDENT
-
-        // parse the formal parameter declarations
-        LPAREN! param:parameterDeclarationList! RPAREN!
-
-        // get the list of exceptions that this method is
-        // declared to throw
-        ((nls "throws") => tc:throwsClause!)? nlsWarn!
-
-        cb:constructorBody!
-        {#constructorDefinition = #(create(CTOR_IDENT,"CTOR_IDENT",first,LT(0)), mods, param, tc, cb);}
-     ;
-
-/** Declaration of a variable. This can be a class/instance variable,
- *  or a local variable in a method
- *  It can also include possible initialization.
- */
-variableDeclarator![AST mods, AST t,Token first]
-    :
-        id:variableName
-        (v:varInitializer)?
-        {#variableDeclarator = #(create(VARIABLE_DEF,"VARIABLE_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)), t), id, v);}
-    ;
-
-/** Used in cases where a declaration cannot have commas, or ends with the "in" operator instead of '='. */
-singleVariable![AST mods, AST t]  {Token first = LT(1);}
-    :
-        id:variableName
-        {#singleVariable = #(create(VARIABLE_DEF,"VARIABLE_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)),t), id);}
-    ;
-
-variableName
-    :   IDENT
-    ;
-
-/** After some type names, where zero or more empty bracket pairs are allowed.
- *  We use ARRAY_DECLARATOR to represent this.
- */
-declaratorBrackets[AST typ]
-    :   {#declaratorBrackets=typ;}
-        (
-            // A following list constructor might conflict with index brackets; prefer the declarator.
-            options {greedy=true;} :
-            LBRACK!
-            RBRACK!
-            {#declaratorBrackets = #(create(ARRAY_DECLARATOR,"[",typ,LT(1)), #declaratorBrackets);}
-        )*
-    ;
-
-/** An assignment operator '=' followed by an expression.  (Never empty.) */
-varInitializer
-    :   ASSIGN^ nls! expressionStatementNoCheck
-        // In {T x = y}, the left-context of y is that of an initializer.
-    ;
-
-// This is a list of exception classes that the method is declared to throw
-throwsClause
-    :   nls! "throws"^ nls! identifier ( COMMA! nls! identifier )*
-    ;
-
-/** A list of zero or more formal parameters.
- *  If a parameter is variable length (e.g. String... myArg) it should be
- *  to the right of any other parameters of the same kind.
- *  General form:  (req, ..., opt, ..., [rest], key, ..., [restKeys], [block]
- *  This must be sorted out after parsing, since the various declaration forms
- *  are impossible to tell apart without backtracking.
- */
-parameterDeclarationList  {Token first = LT(1);}
-    :
-        (
-            parameterDeclaration
-            (   COMMA! nls!
-                parameterDeclaration
-            )*
-        )?
-        {#parameterDeclarationList = #(create(PARAMETERS,"PARAMETERS",first,LT(1)), #parameterDeclarationList);}
-    ;
-
-/** A formal parameter for a method or closure. */
-parameterDeclaration!
-        { Token first = LT(1);boolean spreadParam = false; }
-    :
-        pm:parameterModifiersOpt
-        (   options {greedy=true;} :
-            t:typeSpec[false]
-        )?
-
-        // TODO:  What do formal parameters for keyword arguments look like?
-
-        // Java-style var args
-        ( TRIPLE_DOT! { spreadParam = true; } )?
-
-        id:IDENT
-
-        // allow an optional default value expression
-        (exp:varInitializer)?
-
-        {
-            if (spreadParam) {
-                #parameterDeclaration = #(create(VARIABLE_PARAMETER_DEF,"VARIABLE_PARAMETER_DEF",first,LT(1)), pm, #(create(TYPE,"TYPE",first,LT(1)), t), id, exp);
-            } else {
-                #parameterDeclaration = #(create(PARAMETER_DEF,"PARAMETER_DEF",first,LT(1)), pm, #(create(TYPE,"TYPE",first,LT(1)), t), id, exp);
-            }
-        }
-    ;
-
-multicatch_types
-{Token first = LT(1);}
-    :
-        nls!
-        classOrInterfaceType[false]
-        (
-            BOR! nls! classOrInterfaceType[false]
-        )*
-
-        {#multicatch_types = #(create(MULTICATCH_TYPES,"MULTICATCH_TYPES",first,LT(1)), #multicatch_types);}
-    ;
-
-multicatch
-{Token first = LT(1);}
-    :   nls! (FINAL)? ("def")? (m:multicatch_types)? id:IDENT!
-        {
-          #multicatch = #(create(MULTICATCH,"MULTICATCH",first,LT(1)), m, id);
-        }
-    ;
-
-parameterModifiersOpt
-        { Token first = LT(1);int seenDef = 0; }
-        //final and/or def can appear amongst annotations in any order
-    :   (   {seenDef++ == 0}?       // do not allow multiple "def" tokens
-            "def"!  nls!            // redundant, but allowed for symmetry
-        |   "final" nls!
-        |   annotation nls!
-        )*
-        {#parameterModifiersOpt = #(create(MODIFIERS,"MODIFIERS",first,LT(1)), #parameterModifiersOpt);}
-    ;
-
-/** Closure parameters are exactly like method parameters,
- *  except that they are not enclosed in parentheses, but rather
- *  are prepended to the front of a block, just after the brace.
- *  They are separated from the closure body by a CLOSABLE_BLOCK_OP token '->'.
- */
-// With '|' there would be restrictions on bitwise-or expressions.
-closableBlockParamsOpt[boolean addImplicit]
-    :   (parameterDeclarationList nls CLOSABLE_BLOCK_OP)=>
-        parameterDeclarationList nls! CLOSABLE_BLOCK_OP! nls!
-    |   {addImplicit}?
-        implicitParameters
-    |
-        /* else do not parse any parameters at all */
-    ;
-
-/** Lookahead to check whether a block begins with explicit closure arguments. */
-closableBlockParamsStart!
-    :
-        nls parameterDeclarationList nls CLOSABLE_BLOCK_OP
-    ;
-
-/** Simple names, as in {x|...}, are completely equivalent to {(def x)|...}.  Build the right AST. */
-closableBlockParam!  {Token first = LT(1);}
-    :   id:IDENT!
-        {#closableBlockParam = #(create(PARAMETER_DEF,"PARAMETER_DEF",first,LT(1)), #(create(MODIFIERS,"MODIFIERS",first,LT(1))), #(create(TYPE,"TYPE",first,LT(1))), id);}
-    ;
-
-// Compound statement. This is used in many contexts:
-// Inside a class definition prefixed with "static":
-// it is a class initializer
-// Inside a class definition without "static":
-// it is an instance initializer
-// As the body of a method
-// As a completely independent braced block of code inside a method
-// it starts a new scope for variable definitions
-// In Groovy, this is called an "open block".  It cannot have closure arguments.
-
-compoundStatement
-    :   openBlock
-    ;
-
-/** An open block is not allowed to have closure arguments. */
-openBlock  {Token first = LT(1);}
-    :   LCURLY! nls!
-        // AST type of SLIST means "never gonna be a closure"
-        bb:blockBody[EOF]!
-        RCURLY!
-        {#openBlock = #(create(SLIST,"{",first,LT(1)), bb);}
-
-    ;
-
-/** A block body is a parade of zero or more statements or expressions. */
-blockBody[int prevToken]
-    :
-        (statement[prevToken])? (sep! (statement[sepToken])?)*
-    ;
-
-/** A block which is known to be a closure, even if it has no apparent arguments.
- *  A block inside an expression or after a method call is always assumed to be a closure.
- *  Only labeled, unparameterized blocks which occur directly as substatements are kept open.
- */
-closableBlock  {Token first = LT(1);}
-    :   LCURLY! nls!
-        cbp:closableBlockParamsOpt[true]!
-        bb:blockBody[EOF]!
-        RCURLY!
-        {#closableBlock = #(create(CLOSABLE_BLOCK,"{",first,LT(1)), cbp, bb);}
-    ;
-
-/** A block known to be a closure, but which omits its arguments, is given this placeholder.
- *  A subsequent pass is responsible for deciding if there is an implicit 'it' parameter,
- *  or if the parameter list should be empty.
- */
-implicitParameters  {Token first = LT(1);}
-    :   {   #implicitParameters = #(create(IMPLICIT_PARAMETERS,"IMPLICIT_PARAMETERS",first,LT(1)));  }
-    ;
-
-/** A sub-block of a block can be either open or closable.
- *  It is closable if and only if there are explicit closure arguments.
- *  Compare this to a block which is appended to a method call,
- *  which is given closure arguments, even if they are not explicit in the code.
- */
-openOrClosableBlock  {Token first = LT(1);}
-    :   LCURLY! nls!
-        cp:closableBlockParamsOpt[false]!
-        bb:blockBody[EOF]!
-        RCURLY!
-        {
-            if (#cp == null)
-                #openOrClosableBlock = #(create(SLIST,"{",first,LT(1)), bb);
-            else
-                #openOrClosableBlock = #(create(CLOSABLE_BLOCK,"{",first,LT(1)), cp, bb);
-        }
-    ;
-
-/** A statement is an element of a block.
- *  Typical statements are declarations (which are scoped to the block)
- *  and expressions.
- */
-statement[int prevToken]
-{boolean sce = false; Token first = LT(1); AST casesGroup_AST = null;}
-    // prevToken is NLS if previous statement is separated only by a newline
-
-    :  (genericMethodStart)=>
-        genericMethod
-
-    |  (multipleAssignmentDeclarationStart)=>
-        multipleAssignmentDeclaration
-
-    // declarations are ambiguous with "ID DOT" relative to expression
-    // statements. Must backtrack to be sure. Could use a semantic
-    // predicate to test symbol table to see what the type was coming
-    // up, but that's pretty hard without a symbol table ;)
-    |  (declarationStart)=>
-        declaration
-
-    // Attach a label to the front of a statement
-    // This block is executed for effect, unless it has an explicit closure argument.
-    |
-       (IDENT COLON)=>
-        pfx:statementLabelPrefix!
-        {#statement = #pfx;}  // nest it all under the label prefix
-        (   (LCURLY) => openOrClosableBlock
-        |   statement[COLON]
-        )
-
-    // An expression statement. This could be a method call,
-    // assignment statement, or any other expression evaluated for
-    // side-effects.
-    // The prevToken is used to check for dumb expressions like +1.
-    |    es:expressionStatement[prevToken]
-        //{#statement = #(create(EXPR,"EXPR",first,LT(1)), es);}
-
-    // If-else statement
-    |   "if"! LPAREN! ale:assignmentLessExpression! RPAREN! nlsWarn! ifCbs:compatibleBodyStatement!
-        (
-            // CONFLICT: the old "dangling-else" problem...
-            //           ANTLR generates proper code matching
-            //                       as soon as possible.  Hush warning.
-            options {
-                    warnWhenFollowAmbig = false;
-            }
-        :   // lookahead to check if we're entering an 'else' clause
-            ( (sep!)? "else"! )=>
-            (sep!)?  // allow SEMI here for compatibility with Java
-            "else"! nlsWarn! elseCbs:compatibleBodyStatement!
-        )?
-        {#statement = #(create(LITERAL_if,"if",first,LT(1)), ale, ifCbs, elseCbs);}
-
-    // For statement
-    |   forStatement
-
-    // While statement
-    |   "while"! LPAREN! sce=while_sce:strictContextExpression[false]! RPAREN! nlsWarn!
-        (s:SEMI! | while_cbs:compatibleBodyStatement!)
-        {
-            if (#s != null)
-                #statement = #(create(LITERAL_while,"Literal_while",first,LT(1)), while_sce, s);
-            else
-                #statement = #(create(LITERAL_while,"Literal_while",first,LT(1)), while_sce, while_cbs);
-        }
-
-    // Import statement.  Can be used in any scope.  Has "import x as y" also.
-    |   (annotationsOpt "import") => importStatement
-
-    // class definition
-    |   m:modifiersOpt! typeDefinitionInternal[#m]
-
-    // switch/case statement
-    |   "switch"! LPAREN! sce=switchSce:strictContextExpression[false]! RPAREN! nlsWarn! LCURLY! nls!
-        ( cg:casesGroup!
-          //expand the list of nodes for each catch statement
-              {casesGroup_AST = #(null, casesGroup_AST, cg);})*
-        RCURLY!
-        {#statement = #(create(LITERAL_switch,"switch",first,LT(1)),switchSce,casesGroup_AST);}
-
-    // exception try-catch block
-    |   tryBlock
-
-    // synchronize a statement
-    |   "synchronized"! LPAREN! sce=synch_sce:strictContextExpression[false]! RPAREN! nlsWarn! synch_cs:compoundStatement!
-        {#statement = #(create(LITERAL_synchronized,"synchronized",first,LT(1)), synch_sce, synch_cs);}
-
-    |   branchStatement
-    ;
-
-forStatement {Token first = LT(1);}
-    :   "for"!
-        LPAREN!
-        (   (SEMI | (strictContextExpression[true] SEMI)) => cl:closureList!
-        |   // the coast is clear; it's a modern Groovy for statement
-            fic:forInClause!
-        )
-        RPAREN! nls!
-        (s:SEMI! | forCbs:compatibleBodyStatement!)                                  // statement to loop over
-        {
-            if (#cl != null) {
-                if (#s != null)
-                    #forStatement = #(create(LITERAL_for,"for",first,LT(1)), cl, s);
-                else
-                    #forStatement = #(create(LITERAL_for,"for",first,LT(1)), cl, forCbs);
-            } else {
-                if (#s != null)
-                    #forStatement = #(create(LITERAL_for,"for",first,LT(1)), fic, s);
-                else
-                    #forStatement = #(create(LITERAL_for,"for",first,LT(1)), fic, forCbs);
-            }
-        }
-
-    ;
-
-closureList
-    {Token first = LT(1); boolean sce=false;}
-    :
-
-        (   sce=strictContextExpression[true]
-            |    {astFactory.addASTChild(currentAST,astFactory.create(EMPTY_STAT, "EMPTY_STAT"));}
-        )
-        (
-                SEMI! sce=strictContextExpression[true]
-           |    SEMI! {astFactory.addASTChild(currentAST,astFactory.create(EMPTY_STAT, "EMPTY_STAT"));}
-        )+
-        {#closureList = #(create(CLOSURE_LIST,"CLOSURE_LIST",first,LT(1)), #closureList);}
-    ;
-
-forInClause
-    :   (   (declarationStart)=>
-            decl:singleDeclarationNoInit
-        |   IDENT
-        )
-        (
-            i:"in"^         {#i.setType(FOR_IN_ITERABLE);}
-            shiftExpression[0]
-        |
-            { addWarning(
-              "A colon at this point is legal Java but not recommended in Groovy.",
-              "Use the 'in' keyword."
-              );
-            require(#decl != null,
-                "Java-style for-each statement requires a type declaration."
-                ,
-                "Use the 'in' keyword, as for (x in y) {...}"
-                );
-            }
-            c:COLON^         {#c.setType(FOR_IN_ITERABLE);}
-            expression[0]
-        )
-    ;
-
-/** In Java, "if", "while", and "for" statements can take random, non-braced statements as their bodies.
- *  Support this practice, even though it isn't very Groovy.
- */
-compatibleBodyStatement {Token first = LT(1);}
-    :   (LCURLY)=>
-        compoundStatement
-    // comma sep decl case converted to multiple statements so must be wrapped in SLIST when single statement occurs after if/while/for
-    |  (declarationStart (varInitializer)? COMMA)=>
-        de:declaration
-        {#compatibleBodyStatement = #(create(SLIST,"CBSLIST",first,LT(1)), de);}
-    |
-        statement[EOF]
-    ;
-
-/** In Groovy, return, break, continue, throw, and assert can be used in a parenthesized expression context.
- *  Example:  println (x || (return));  println assert x, "won't print a false value!"
- *  If an optional expression is missing, its value is void (this coerces to null when a value is required).
- */
-branchStatement {Token first = LT(1);}
-    :
-    // Return an expression
-        "return"!
-        ( returnE:expression[0]! )?
-        {#branchStatement = #(create(LITERAL_return,"return",first,LT(1)), returnE);}
-
-
-    // break:  get out of a loop, or switch, or method call
-    // continue:  do next iteration of a loop, or leave a closure
-    |   "break"!
-        ( breakI:IDENT! )?
-        {#branchStatement = #(create(LITERAL_break,"break",first,LT(1)), breakI);}
-
-    | "continue"!
-        ( contI:IDENT! )?
-        {#branchStatement = #(create(LITERAL_continue,"continue",first,LT(1)), contI);}
-
-    // throw an exception
-    |   "throw"! throwE:expression[0]!
-        {#branchStatement = #(create(LITERAL_throw,"throw",first,LT(1)), throwE);}
-
-
-    // groovy assertion...
-    |   "assert"! assertAle: assignmentLessExpression!
-        (   options {greedy=true;} :
-            (   COMMA! nls! // TODO:  gratuitous change caused failures
-            |   COLON! nls! // standard Java syntax, but looks funny in Groovy
-            )
-            assertE:expression[0]!
-        )?
-        {#branchStatement = #(create(LITERAL_assert,"assert",first,LT(1)), assertAle, assertE);}
-    ;
-
-/** A labeled statement, consisting of a vanilla identifier followed by a colon. */
-// Note:  Always use this lookahead, to keep antlr from panicking: (IDENT COLON)=>
-statementLabelPrefix
-    :   IDENT c:COLON^ {#c.setType(LABELED_STAT);} nls!
-    ;
-
-/** An expression statement can be any general expression.
- *  <p>
- *  An expression statement can also be a <em>command</em>,
- *  which is a simple method call in which the outermost parentheses are omitted.
- *  <p>
- *  Certain "suspicious" looking forms are flagged for the user to disambiguate.
- */
-// DECIDE: A later semantic pass can flag dumb expressions that don't occur in
-//         positions where their value is not used, e.g., <code>{1+1;println}</code>
-expressionStatement[int prevToken]
-        { Token first = LT(1); }
-    :
-        ( (suspiciousExpressionStatementStart) =>
-            checkSuspiciousExpressionStatement[prevToken]
-        )?
-        esn:expressionStatementNoCheck
-        { #expressionStatement = #(create(EXPR,"EXPR",first,LT(1)), #esn); }
-    ;
-
-expressionStatementNoCheck
-        { boolean isPathExpr = true; }
-    :
-        // Checks are now out of the way; here's the real rule:
-        head:expression[LC_STMT]
-        { isPathExpr = (#head == lastPathExpression); }
-        (
-            // A path expression (e.g., System.out.print) can take arguments.
-            {LA(1)!=LITERAL_else && isPathExpr}?
-            cmd:commandArgumentsGreedy[#head]!
-            {
-                #expressionStatementNoCheck = #cmd;
-            }
-        )?
-    ;
-
-/**
- *  If two statements are separated by newline (not SEMI), the second had
- *  better not look like the latter half of an expression.  If it does, issue a warning.
- *  <p>
- *  Also, if the expression starts with a closure, it needs to
- *  have an explicit parameter list, in order to avoid the appearance of a
- *  compound statement.  This is a hard error.
- *  <p>
- *  These rules are different from Java's "dumb expression" restriction.
- *  Unlike Java, Groovy blocks can end with arbitrary (even dumb) expressions,
- *  as a consequence of optional 'return' and 'continue' tokens.
- * <p>
- *  To make the programmer's intention clear, a leading closure must have an
- *  explicit parameter list, and must not follow a previous statement separated
- *  only by newlines.
- */
-checkSuspiciousExpressionStatement[int prevToken]
-    :
-        (~LCURLY | LCURLY closableBlockParamsStart)=>  //FIXME too much lookahead
-        // Either not a block, or a block with an explicit closure parameter list.
-        (   {prevToken == NLS}?
-            {   addWarning(
-                "Expression statement looks like it may continue a previous statement",
-                "Either remove the previous newline, or add an explicit semicolon ';'.");
-            }
-        )?
-    |
-        // Else we have a block without any visible closure parameters.
-        {prevToken == NLS}?
-        // if prevToken is NLS, we have double trouble; issue a double warning
-        // Example:  obj.foo \n {println x}
-        // Might be appended block:  obj.foo {println x}
-        // Might be closure expression:  obj.foo ; {x->println x}
-        // Might be open block:  obj.foo ; L:{println x}
-        {   require(false,
-            "Ambiguous expression could be a parameterless closure expression, "+
-            "an isolated open code block, or it may continue a previous statement",
-            "Add an explicit parameter list, e.g. {it -> ...}, or force it to be treated "+
-            "as an open block by giving it a label, e.g. L:{...}, "+
-            "and also either remove the previous newline, or add an explicit semicolon ';'"
-            );
-        }
-    |
-        {prevToken != NLS}?
-        // If prevToken is SEMI or something else, issue a single warning:
-        // Example:  obj.foo ; {println x}
-        // Might be closure expression:  obj.foo ; {x->println x}
-        // Might be open block:  obj.foo ; L:{println x}
-        {   require(false,
-            "Ambiguous expression could be either a parameterless closure expression or "+
-            "an isolated open code block",
-            "Add an explicit closure parameter list, e.g. {it -> ...}, or force it to "+
-            "be treated as an open block by giving it a label, e.g. L:{...}");
-        }
-    ;
-
-/** Lookahead for suspicious statement warnings and errors. */
-suspiciousExpressionStatementStart
-    :
-        (   (PLUS | MINUS)
-        |   (LBRACK | LPAREN | LCURLY)
-        )
-        // TODO:  Expand this set?
-    ;
-
-// Support for switch/case:
-casesGroup  {Token first = LT(1);}
-    :   (   // CONFLICT: to which case group do the statements bind?
-            // ANTLR generates proper code: it groups the
-            // many "case"/"default" labels together then
-            // follows them with the statements
-            options {
-                greedy = true;
-            }
-            :
-            aCase
-        )+
-        caseSList
-        {#casesGroup = #(create(CASE_GROUP,"CASE_GROUP",first,LT(1)), #casesGroup);}
-    ;
-
-aCase
-    :   ("case"^ expression[0] | "default") COLON! nls!
-    ;
-
-caseSList  {Token first = LT(1);}
-    :   statement[COLON] (sep! (statement[sepToken])?)*
-        {#caseSList = #(create(SLIST,"SLIST",first,LT(1)), #caseSList);}
-    ;
-
-// The initializer for a for loop
-forInit  {Token first = LT(1);}
-    :   // if it looks like a declaration, it is
-        (declarationStart)=> declaration
-    |   // else it's a comma-separated list of expressions
-        (controlExpressionList)?
-        {#forInit = #(create(FOR_INIT,"FOR_INIT",first,LT(1)), #forInit);}
-    ;
-
-forCond  {Token first = LT(1); boolean sce=false;}
-    :   (sce=strictContextExpression[false])?
-        {#forCond = #(create(FOR_CONDITION,"FOR_CONDITION",first,LT(1)), #forCond);}
-    ;
-
-forIter  {Token first = LT(1);}
-    :   (controlExpressionList)?
-        {#forIter = #(create(FOR_ITERATOR,"FOR_ITERATOR",first,LT(1)), #forIter);}
-    ;
-
-// an exception handler try/catch block
-tryBlock {Token first = LT(1);List catchNodes = new ArrayList();AST newHandler_AST = null;}
-    :   "try"! nlsWarn! tryCs:compoundStatement!
-            ( options {greedy=true;} : {!(LA(1) == NLS && LA(2) == LPAREN)}? nls! h:handler!
-
-              //expand the list of nodes for each catch statement
-              {newHandler_AST = #(null,newHandler_AST,h);}   )*
-            ( options {greedy=true;} :  nls! fc:finallyClause!)?
-
-        {#tryBlock = #(create(LITERAL_try,"try",first,LT(1)), tryCs, newHandler_AST, fc);}
-    ;
-
-finallyClause {Token first = LT(1);}
-    :   "finally"! nlsWarn! finallyCs:compoundStatement!
-        {#finallyClause = #(create(LITERAL_finally,"finally",first,LT(1)), finallyCs);}
-    ;
-
-// an exception handler
-handler {Token first = LT(1);}
-    :   "catch"! LPAREN! pd:multicatch! RPAREN! nlsWarn! handlerCs:compoundStatement!
-        {#handler = #(create(LITERAL_catch,"catch",first,LT(1)), pd, handlerCs);}
-    ;
-
-/** A member name (x.y) or element name (x[y]) can serve as a command name,
- *  which may be followed by a list of arguments.
- *  Unlike parenthesized arguments, these must be plain expressions,
- *  without labels or spread operators.
- */
-commandArguments[AST head]
-{
-    Token first = LT(1);
-}
-    :
-        commandArgument ( options {greedy=true;}: COMMA! nls! commandArgument )*
-        // println 2+2 //OK
-        // println(2+2) //OK
-        // println (2)+2 //BAD
-        // println((2)+2) //OK
-        // (println(2)+2) //OK
-        // compare (2), 2 //BAD
-        // compare( (2), 2 ) //OK
-        // foo.bar baz{bat}, bang{boz} //OK
-        {
-            AST elist = #(create(ELIST,"ELIST",first,LT(1)), #commandArguments);
-            AST headid = #(create(METHOD_CALL,"<command>",first,LT(1)), head, elist);
-            #commandArguments = headid;
-        }
-    ;
-
-commandArgumentsGreedy[AST head]
-{
-    AST prev = #head;
-}
-    :
-        // argument to the already existing method name
-        (
-            ({#prev==null || #prev.getType()!=METHOD_CALL}? commandArgument) => (
-                first : commandArguments[head]!
-                { #prev = #first; }
-            )
-            |
-        )
-        // we start a series of methods and arguments
-        (   options { greedy = true; } :
-            (   options { greedy = true; } :
-                // method name
-                pre:primaryExpression!
-                { #prev = #(create(DOT, ".", #prev), #prev, #pre); }
-                // what follows is either a normal argument, parens,
-                // an appended block, an index operation, or nothing
-                // parens (a b already processed):
-                //      a b c() d e -> a(b).c().d(e)
-                //      a b c()() d e -> a(b).c().call().d(e)
-                // index (a b already processed):
-                //      a b c[x] d e -> a(b).c[x].d(e)
-                //      a b c[x][y] d e -> a(b).c[x][y].d(e)
-                // block (a b already processed):
-                //      a b c {x} d e -> a(b).c({x}).d(e)
-                //
-                // parens/block completes method call
-                // index makes method call to property get with index
-                //
-                (options {greedy=true;}:
-                (pathElementStart) =>
-                    (
-                        pc:pathChain[LC_STMT,#prev]!
-                        { #prev = #pc; }
-                    )
-                |
-                    (   ca:commandArguments[#prev]!
-                        { #prev = #ca; }
-                    )
-                )?
-            )*
-        )
-        { #commandArgumentsGreedy = prev; }
-    ;
-
-commandArgument
-    :
-        (argumentLabel COLON nls!) => (
-            argumentLabel c:COLON^ nls! expression[0]  { #c.setType(LABELED_ARG); }
-        )
-        | expression[0]
-    ;
-
-// expressions
-// Note that most of these expressions follow the pattern
-//   thisLevelExpression :
-//         nextHigherPrecedenceExpression
-//                 (OPERATOR nextHigherPrecedenceExpression)*
-// which is a standard recursive definition for a parsing an expression.
-// The operators have the following precedences:
-//      lowest  ( 15)  = **= *= /= %= += -= <<= >>= >>>= &= ^= |= (assignments)
-//              ( 14)  ?: (conditional expression and elvis)
-//              ( 13)  || (logical or)
-//              ( 12)  && (logical and)
-//              ( 11)  | ()binary or
-//              ( 10)  ^ (binary xor)
-//              (  9)  & (binary and)
-//              (8.5)  =~ ==~ (regex find/match)
-//              (  8)  == != <=> === !== (equals, not equals, compareTo)
-//              (  7)  < <= > >= instanceof as in (relational, in, instanceof, type coercion)
-//              (  6)  << >> >>> .. ..< (shift, range)
-//              (  5)  + - (addition, subtraction)
-//              (  4)  * / % (multiply div modulo)
-//              (  3)  ++ -- + - (pre dec/increment, unary signs)
-//              (  2)  ** (power)
-//              (  1)  ~ ! $ (type) (negate, not, typecast)
-//                     ?. * *. *: (safe dereference, spread, spread-dot, spread-map)
-//                     . .& .@ (member access, method closure, field/attribute access)
-//                     [] ++ -- (list/map/array index, post inc/decrement)
-//                     () {} [] (method call, closableBlock, list/map literal)
-//                     new () (object creation, explicit parenthesis)
-//
-// the last two are not usually on a precedence chart; I put them in
-// to point out that new has a higher precedence than '.', so you
-// can validly use
-//       new Frame().show()
-//
-// Note that the above precedence levels map to the rules below...
-// Once you have a precedence chart, writing the appropriate rules as below
-// is usually very straightforward
-
-
-// the mother of all expressions
-// This nonterminal is not used for expression statements, which have a more restricted syntax
-// due to possible ambiguities with other kinds of statements.  This nonterminal is used only
-// in contexts where we know we have an expression.  It allows general Java-type expressions.
-expression[int lc_stmt]
-    :
-//        (LPAREN typeSpec[true] RPAREN expression[lc_stmt])=>
-//            lp:LPAREN^ {#lp.setType(TYPECAST);} typeSpec[true] RPAREN!
-//            expression[lc_stmt]
-//    |
-       (LPAREN nls IDENT (COMMA nls IDENT)* RPAREN ASSIGN) =>
-        m:multipleAssignment[lc_stmt] {#expression=#m;}
-    |   assignmentExpression[lc_stmt]
-    ;
-
-multipleAssignment[int lc_stmt] {Token first = cloneToken(LT(1));}
-    :   LPAREN^ nls! listOfVariables[null,null,first] RPAREN!
-        ASSIGN^ nls!
-        (
-          (LPAREN nls IDENT (COMMA nls IDENT)* RPAREN ASSIGN) => multipleAssignment[lc_stmt]
-          | assignmentExpression[lc_stmt]
-        )
-    ;
-
-// This is a list of expressions.
-// Used for backward compatibility, in a few places where
-// comma-separated lists of Java expression statements and declarations are required.
-controlExpressionList  {Token first = LT(1); boolean sce=false;}
-    :   sce=strictContextExpression[false] (COMMA! nls! sce=strictContextExpression[false])*
-        {#controlExpressionList = #(create(ELIST,"ELIST",first,LT(1)), controlExpressionList);}
-    ;
-
-pathChain[int lc_stmt, AST prefix]
-    :
-        (
-            options {
-                // \n{foo} could match here or could begin a new statement
-                // We do want to match here. Turn off warning.
-                greedy=true;
-                // This turns the ambiguity warning of the second alternative
-                // off. See below. (The "ANTLR_LOOP_EXIT" predicate makes it non-issue)
-                //@@ warnWhenFollowAmbig=false;
-            }
-            // Parsing of this chain is greedy.  For example, a pathExpression may be a command name
-            // followed by a command argument, but that command argument cannot begin with an LPAREN,
-            // since a parenthesized expression is greedily attached to the pathExpression as a method argument.
-            // The lookahead is also necessary to reach across newline in foo \n {bar}.
-            // (Apparently antlr's basic approximate LL(k) lookahead is too weak for this.)
-        :   (pathElementStart)=>
-            nls!
-            pe:pathElement[prefix]!
-            { prefix = #pe; }
-        |
-            {lc_stmt == LC_STMT || lc_stmt == LC_INIT}?
-            (nls LCURLY)=>
-            nlsWarn!
-            apb:appendedBlock[prefix]!
-            { prefix = #apb; }
-        )+
-
-        { #pathChain = prefix; }
-    ;
-
-/** A "path expression" is a name or other primary, possibly qualified by various
- *  forms of dot, and/or followed by various kinds of brackets.
- *  It can be used for value or assigned to, or else further qualified, indexed, or called.
- *  It is called a "path" because it looks like a linear path through a data structure.
- *  Examples:  x.y, x?.y, x*.y, x.@y; x[], x[y], x[y,z]; x(), x(y), x(y,z); x{s}; a.b[n].c(x).d{s}
- *  (Compare to a C lvalue, or LeftHandSide in the JLS section 15.26.)
- *  General expressions are built up from path expressions, using operators like '+' and '='.
- */
-pathExpression[int lc_stmt]
-        { AST prefix = null; }
-    :
-        pre:primaryExpression!
-        { prefix = #pre; }
-        (
-            options {
-                // \n{foo} could match here or could begin a new statement
-                // We do want to match here. Turn off warning.
-                greedy=true;
-                // This turns the ambiguity warning of the second alternative
-                // off. See below. (The "ANTLR_LOOP_EXIT" predicate makes it non-issue)
-                //@@ warnWhenFollowAmbig=false;
-            }
-            // Parsing of this chain is greedy.  For example, a pathExpression may be a command name
-            // followed by a command argument, but that command argument cannot begin with an LPAREN,
-            // since a parenthesized expression is greedily attached to the pathExpression as a method argument.
-            // The lookahead is also necessary to reach across newline in foo \n {bar}.
-            // (Apparently antlr's basic approximate LL(k) lookahead is too weak for this.)
-        :   (pathElementStart)=>
-            nls!
-            pe:pathElement[prefix]!
-            { prefix = #pe; }
-        |
-            {lc_stmt == LC_STMT || lc_stmt == LC_INIT}?
-            (nls LCURLY)=>
-            nlsWarn!
-            apb:appendedBlock[prefix]!
-            { prefix = #apb; }
-        )*
-        {
-            #pathExpression = prefix;
-            lastPathExpression = #pathExpression;
-        }
-    ;
-
-pathElement[AST prefix] {Token operator = LT(1);}
-        // The primary can then be followed by a chain of .id, (a), [a], and {...}
-    :
-        { #pathElement = prefix; }
-        ( nls!
-            ( SPREAD_DOT!     // Spread operator:  x*.y  ===  x?.collect{it.y}
-            |
-              OPTIONAL_DOT!   // Optional-null operator:  x?.y  === (x==null)?null:x.y
-            |
-              MEMBER_POINTER! // Member pointer operator: foo.&y == foo.metaClass.getMethodPointer(foo, "y")
-            |
-              DOT!            // The all-powerful dot.
-            )
-        ) nls!
-        (ta:typeArguments!)?
-        np:namePart!
-        { #pathElement = #(create(operator.getType(),operator.getText(),prefix,LT(1)), prefix, ta, np); }
-
-    |
-        mca:methodCallArgs[prefix]!
-        {   #pathElement = #mca;  }
-    |
-        // Can always append a block, as foo{bar}
-        apb:appendedBlock[prefix]!
-        {   #pathElement = #apb;  }
-    |
-        // Element selection is always an option, too.
-        // In Groovy, the stuff between brackets is a general argument list,
-        // since the bracket operator is transformed into a method call.
-        ipa:indexPropertyArgs[prefix]!
-        {   #pathElement = #ipa;  }
-    ;
-
-pathElementStart!
-    :   (nls! ( DOT
-                |   SPREAD_DOT
-                |   OPTIONAL_DOT
-                |   MEMBER_POINTER ) )
-        |   LBRACK
-        |   LPAREN
-        |   LCURLY
-    ;
-
-/** This is the grammar for what can follow a dot:  x.a, x.@a, x.&a, x.'a', etc.
- *  Note: <code>typeArguments</code> is handled by the caller of <code>namePart</code>.
- */
-namePart  {Token first = LT(1);}
-    :
-        (   ats:AT^     {#ats.setType(SELECT_SLOT);}  )?
-        // foo.@bar selects the field (or attribute), not property
-
-        (   IDENT
-        |   sl:STRING_LITERAL {#sl.setType(IDENT);}
-            // foo.'bar' is in all ways same as foo.bar, except that bar can have an arbitrary spelling
-        |   dynamicMemberName
-        |
-            openBlock
-            // PROPOSAL, DECIDE:  Is this inline form of the 'with' statement useful?
-            // Definition:  a.{foo} === {with(a) {foo}}
-            // May cover some path expression use-cases previously handled by dynamic scoping (closure delegates).
-
-            // let's allow common keywords as property names
-        |   keywordPropertyNames
-        )
-
-        // (No, x.&@y is not needed; just say x.&y as Slot or some such.)
-    ;
-
-/*
- * Allowed keywords after dot (as a member name) and before colon (as a label).
- * Includes all Java keywords plus "as", "def", "in", and "trait".
- */
-keywordPropertyNames
-    :   (
-          "as"
-        | "assert"
-        | "break"
-        | "case"
-        | "catch"
-        | "class"
-        | "const"
-        | "continue"
-        | "def"
-        | "default"
-        | "do"
-        | "else"
-        | "enum"
-        | "extends"
-        | "false"
-        | "finally"
-        | "for"
-        | "goto"
-        | "if"
-        | "implements"
-        | "import"
-        | "in"
-        | "instanceof"
-        | "interface"
-        | "new"
-        | "null"
-        | "package"
-        | "return"
-        | "super"
-        | "switch"
-        | "this"
-        | "throw"
-        | "throws"
-        | "trait"
-        | "true"
-        | "try"
-        | "while"
-        | modifier
-        | builtInType
-        )
-        { #keywordPropertyNames.setType(IDENT); }
-    ;
-
-/** If a dot is followed by a parenthesized or quoted expression, the member is computed dynamically,
- *  and the member selection is done only at runtime.  This forces a statically unchecked member access.
- */
-dynamicMemberName  {Token first = LT(1);}
-    :   (   pe:parenthesizedExpression!
-            {#dynamicMemberName = #(create(EXPR,"EXPR",first,LT(1)),pe);}
-        |   stringConstructorExpression
-        )
-        { #dynamicMemberName = #(create(DYNAMIC_MEMBER, "DYNAMIC_MEMBER",first,LT(1)), #dynamicMemberName); }
-    ;
-
-/** An expression may be followed by one or both of (...) and {...}.
- *  Note: If either is (...) or {...} present, it is a method call.
- *  The {...} is appended to the argument list, and matches a formal of type Closure.
- *  If there is no method member, a property (or field) is used instead, and must itself be callable.
- *  <p>
- *  If the methodCallArgs are absent, it is a property reference.
- *  If there is no property, it is treated as a field reference, but never a method reference.
- *  <p>
- *  Arguments in the (...) can be labeled, and the appended block can be labeled also.
- *  If there is a mix of unlabeled and labeled arguments,
- *  all the labeled arguments must follow the unlabeled arguments,
- *  except that the closure (labeled or not) is always a separate final argument.
- *  Labeled arguments are collected up and passed as a single argument to a formal of type Map.
- *  <p>
- *  Therefore, f(x,y, a:p, b:q) {s} is equivalent in all ways to f(x,y, [a:p,b:q], {s}).
- *  Spread arguments of sequence type count as unlabeled arguments,
- *  while spread arguments of map type count as labeled arguments.
- *  (This distinction must sometimes be checked dynamically.)
- *
- *  A plain unlabeled argument is allowed to match a trailing Map or Closure argument:
- *  f(x, a:p) {s}  ===  f(*[ x, [a:p], {s} ])
- */
-// AST is [METHOD_CALL, callee, ELIST? CLOSABLE_BLOCK?].
-// Note that callee is often of the form x.y but not always.
-// If the callee is not of the form x.y, then an implicit .call is needed.
-// Parameter callee is only "null" when called from newExpression
-methodCallArgs[AST callee]
-    :
-        LPAREN!
-        al:argList!
-        RPAREN!
-        { if (callee != null && callee.getFirstChild() != null) {
-              //method call like obj.method()
-              #methodCallArgs = #(create(METHOD_CALL,"(",callee.getFirstChild(),LT(1)), callee, al);
-          } else {
-              //method call like method() or new Expr(), in the latter case "callee" is null
-              #methodCallArgs = #(create(METHOD_CALL,"(",callee, LT(1)), callee, al);
-          }
-        }
-    ;
-
-/** An appended block follows any expression.
- *  If the expression is not a method call, it is given an empty argument list.
- */
-appendedBlock[AST callee]
-    :
-        /*  FIXME DECIDE: should appended blocks accept labels?
-        (   (IDENT COLON nls LCURLY)=>
-            IDENT c:COLON^ {#c.setType(LABELED_ARG);} nls!
-        )? */
-        cb:closableBlock!
-        {
-            // If the callee is itself a call, flatten the AST.
-            if (callee != null && callee.getType() == METHOD_CALL) {
-                #appendedBlock = #(create(METHOD_CALL, "(",callee,LT(1)),
-                                   callee.getFirstChild(), cb);
-            } else {
-                #appendedBlock = #(create(METHOD_CALL, "{",callee,LT(1)), callee, cb);
-            }
-        }
-    ;
-
-/** An expression may be followed by [...].
- *  Unlike Java, these brackets may contain a general argument list,
- *  which is passed to the array element operator, which can make of it what it wants.
- *  The brackets may also be empty, as in T[].  This is how Groovy names array types.
- *  <p>Returned AST is [INDEX_OP, indexee, ELIST].
- */
-indexPropertyArgs[AST indexee]
-    :
-        lb:LBRACK
-        al:argList!
-        RBRACK!
-        { if (indexee != null && indexee.getFirstChild() != null) {
-              //expression like obj.index[]
-              #indexPropertyArgs = #(create(INDEX_OP, "INDEX_OP",indexee.getFirstChild(),LT(1)), lb, indexee, al);
-          } else {
-              //expression like obj[]
-              #indexPropertyArgs = #(create(INDEX_OP, "INDEX_OP",indexee,LT(1)), lb, indexee, al);
-          }
-        }
-    ;
-
-// assignment expression (level 15)
-assignmentExpression[int lc_stmt]
-    :   conditionalExpression[lc_stmt]
-        (
-            (   ASSIGN^
-            |   PLUS_ASSIGN^
-            |   MINUS_ASSIGN^
-            |   STAR_ASSIGN^
-            |   DIV_ASSIGN^
-            |   MOD_ASSIGN^
-            |   SR_ASSIGN^
-            |   BSR_ASSIGN^
-            |   SL_ASSIGN^
-            |   BAND_ASSIGN^
-            |   BXOR_ASSIGN^
-            |   BOR_ASSIGN^
-            |   STAR_STAR_ASSIGN^
-            )
-            nls!
-            expressionStatementNoCheck
-            // If left-context of {x = y} is a statement boundary,
-            // define the left-context of y as an initializer.
-        )?
-    ;
-
-// conditional test (level 14)
-conditionalExpression[int lc_stmt]
-    :   logicalOrExpression[lc_stmt]
-        (
-          (nls! ELVIS_OPERATOR)=> nls! ELVIS_OPERATOR^ nls! conditionalExpression[0]
-          | (nls! QUESTION)=> nls! QUESTION^ nls! assignmentExpression[0] nls! COLON! nls! conditionalExpression[0]
-        )?
-    ;
-
-// logical or (||)  (level 13)
-logicalOrExpression[int lc_stmt]
-    :   logicalAndExpression[lc_stmt] (LOR^ nls! logicalAndExpression[0])*
-    ;
-
-// logical and (&&)  (level 12)
-logicalAndExpression[int lc_stmt]
-    :   inclusiveOrExpression[lc_stmt] (LAND^ nls! inclusiveOrExpression[0])*
-    ;
-
-// bitwise or non-short-circuiting or (|)  (level 11)
-inclusiveOrExpression[int lc_stmt]
-    :   exclusiveOrExpression[lc_stmt] (BOR^ nls! exclusiveOrExpression[0])*
-    ;
-
-// exclusive or (^)  (level 10)
-exclusiveOrExpression[int lc_stmt]
-    :   andExpression[lc_stmt] (BXOR^ nls! andExpression[0])*
-    ;
-
-// bitwise or non-short-circuiting and (&)  (level 9)
-andExpression[int lc_stmt]
-    :   regexExpression[lc_stmt] (BAND^ nls! regexExpression[0])*
-    ;
-
-// regex find and match (=~ and ==~) (level 8.5)
-// jez: moved =~ closer to precedence of == etc, as...
-// 'if (foo =~ "a.c")' is very close in intent to 'if (foo == "abc")'
-regexExpression[int lc_stmt]
-    :   equalityExpression[lc_stmt] ((REGEX_FIND^ | REGEX_MATCH^) nls! equalityExpression[0])*
-    ;
-
-// equality/inequality (==/!=) (level 8)
-equalityExpression[int lc_stmt]
-    :   relationalExpression[lc_stmt] ((NOT_EQUAL^ | EQUAL^ |IDENTICAL^ |NOT_IDENTICAL^ | COMPARE_TO^) nls! relationalExpression[0])*
-    ;
-
-// boolean relational expressions (level 7)
-relationalExpression[int lc_stmt]
-    :   shiftExpression[lc_stmt]
-        (   options {greedy=true;} : (
-                (   LT^
-                |   GT^
-                |   LE^
-                |   GE^
-                |   "in"^
-                )
-                nls!
-                shiftExpression[0]
-
-            )
-            |   "instanceof"^ nls! typeSpec[true]
-            |   "as"^         nls! typeSpec[true] //TODO: Rework to allow type expression?
-        )?
-    ;
-
-// bit shift expressions (level 6)
-shiftExpression[int lc_stmt]
-    :   additiveExpression[lc_stmt]
-        (
-            ((SL^ | SR^ | BSR^)
-            |   RANGE_INCLUSIVE^
-            |   RANGE_EXCLUSIVE^
-            )
-            nls!
-            additiveExpression[0]
-        )*
-    ;
-
-// binary addition/subtraction (level 5)
-additiveExpression[int lc_stmt]
-    :   multiplicativeExpression[lc_stmt]
-        (
-            options {greedy=true;} :
-            // Be greedy here, to favor {x+y} instead of {print +value}
-            (PLUS^ | MINUS^) nls!
-            multiplicativeExpression[0]
-        )*
-    ;
-
-// multiplication/division/modulo (level 4)
-multiplicativeExpression[int lc_stmt]
-    :    ( INC^ nls!  powerExpressionNotPlusMinus[0] ((STAR^ | DIV^ | MOD^ )  nls!  powerExpression[0])* )
-    |    ( DEC^ nls!  powerExpressionNotPlusMinus[0] ((STAR^ | DIV^ | MOD^ )  nls!  powerExpression[0])* )
-    |    ( MINUS^ {#MINUS.setType(UNARY_MINUS);} nls!   powerExpressionNotPlusMinus[0] ((STAR^ | DIV^ | MOD^ )  nls!  powerExpression[0])* )
-    |    ( PLUS^ {#PLUS.setType(UNARY_PLUS);} nls!   powerExpressionNotPlusMinus[0] ((STAR^ | DIV^ | MOD^ )  nls!  powerExpression[0])* )
-    |    (  powerExpressionNotPlusMinus[lc_stmt] ((STAR^ | DIV^ | MOD^ )  nls!  powerExpression[0])* )
-    ;
-
-// ++(prefix)/--(prefix)/+(unary)/-(unary) (level 3)
-unaryExpression[int lc_stmt]
-    :   INC^ nls! unaryExpression[0]
-    |   DEC^ nls! unaryExpression[0]
-    |   MINUS^   {#MINUS.setType(UNARY_MINUS);}   nls! unaryExpression[0]
-    |   PLUS^    {#PLUS.setType(UNARY_PLUS);}     nls! unaryExpression[0]
-    |   unaryExpressionNotPlusMinus[lc_stmt]
-    ;
-
-// math power operator (**) (level 2)
-powerExpression[int lc_stmt]
-    :   unaryExpression[lc_stmt] (STAR_STAR^ nls! unaryExpression[0])*
-    ;
-
-// math power operator (**) (level 2)
-// (without ++(prefix)/--(prefix)/+(unary)/-(unary))
-// The different rules are needed to avoid ambiguous selection
-// of alternatives.
-powerExpressionNotPlusMinus[int lc_stmt]
-    :   unaryExpressionNotPlusMinus[lc_stmt] (STAR_STAR^ nls! unaryExpression[0])*
-    ;
-
-// ~(BNOT)/!(LNOT)/(type casting) (level 1)
-unaryExpressionNotPlusMinus[int lc_stmt]
-    :   BNOT^ nls! unaryExpression[0]
-    |   LNOT^ nls! unaryExpression[0]
-    |   (   // subrule allows option to shut off warnings
-            options {
-                    // "(int" ambig with postfixExpr due to lack of sequence
-                    // info in linear approximate LL(k). It's ok. Shut up.
-                    generateAmbigWarnings=false;
-            }
-        :   // If typecast is built in type, must be numeric operand
-            // Have to backtrack to see if operator follows
-            // FIXME: DECIDE: This syntax is wormy.  Can we deprecate or remove?
-            (LPAREN builtInTypeSpec[true] RPAREN unaryExpression[0])=>
-            lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN!
-            unaryExpression[0]
-
-            // Have to backtrack to see if operator follows. If no operator
-            // follows, it's a typecast. No semantic checking needed to parse.
-            // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)"
-            // FIXME: DECIDE: This syntax is wormy.  Can we deprecate or remove?
-            // TODO:  Rework this mess for Groovy.
-        |   (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus[0])=>
-            lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN!
-            unaryExpressionNotPlusMinus[0]
-
-        |   postfixExpression[lc_stmt]
-        )
-    ;
-
-// qualified names, array expressions, method invocation, post inc/dec (level 1)
-postfixExpression[int lc_stmt]
-    :
-        pathExpression[lc_stmt]
-        (
-            options {greedy=true;} :
-            // possibly add on a post-increment or post-decrement.
-            // allows INC/DEC on too much, but semantics can check
-            in:INC^ {#in.setType(POST_INC);}
-        |   de:DEC^ {#de.setType(POST_DEC);}
-        )?
-    ;
-
-// the basic element of an expression
-primaryExpression {Token first = LT(1);}
-    :   IDENT
-    |   constant
-    |   newExpression
-    |   "this"
-    |   "super"
-    |   pe:parenthesizedExpression!             // (general stuff...)
-        {#primaryExpression = #(create(EXPR,"EXPR",first,LT(1)),pe);}
-    |   closableBlockConstructorExpression
-    |   listOrMapConstructorExpression
-    |   stringConstructorExpression         // "foo $bar baz"; presented as multiple tokens
-    |   builtInType
-    ;
-
-// Note:  This is guaranteed to be an EXPR AST.
-// That is, parentheses are preserved, in case the walker cares about them.
-// They are significant sometimes, as in (f(x)){y} vs. f(x){y}.
-parenthesizedExpression
-{   Token first = LT(1);
-    Token declaration = null;
-    boolean hasClosureList=false;
-    boolean firstContainsDeclaration=false;
-    boolean sce=false;
-}
-    :   LPAREN!
-           { declaration=LT(1); }
-           firstContainsDeclaration = strictContextExpression[true]
-           (SEMI!
-             {hasClosureList=true;}
-             (sce=strictContextExpression[true] | { astFactory.addASTChild(currentAST,astFactory.create(EMPTY_STAT, "EMPTY_STAT")); })
-           )*
-           // if the first expression contained a declaration,
-           // but we are having only one expression at all, then
-           // the first declaration is of the kind (def a=b)
-           // which is invalid. Therefore if there was no closure
-           // list we let the compiler throw an error if the
-           // the first declaration exists
-           {
-            if (firstContainsDeclaration && !hasClosureList)
-               throw new NoViableAltException(declaration, getFilename());
-           }
-        RPAREN!
-        {
-            if (hasClosureList) {
-                #parenthesizedExpression = #(create(CLOSURE_LIST,"CLOSURE_LIST",first,LT(1)), #parenthesizedExpression);
-            }
-        }
-    ;
-
-/** Things that can show up as expressions, but only in strict
- *  contexts like inside parentheses, argument lists, and list constructors.
- */
-strictContextExpression[boolean allowDeclaration]
-returns [boolean hasDeclaration=false]
-{Token first = LT(1);}
-    :
-        (   ({allowDeclaration}? declarationStart) =>
-            {hasDeclaration=true;} singleDeclaration  // used for both binding and value, as: while (String xx = nextln()) { println xx }
-        |   expression[0]
-        |   branchStatement // useful to embed inside expressions (cf. C++ throw)
-        |   annotation      // creates an annotation value
-        )
-        // For the sake of the AST walker, mark nodes like this very clearly.
-        {#strictContextExpression = #(create(EXPR,"EXPR",first,LT(1)), #strictContextExpression);}
-    ;
-
-assignmentLessExpression  {Token first = LT(1);}
-    :
-        (   conditionalExpression[0]
-        )
-        // For the sake of the AST walker, mark nodes like this very clearly.
-        {#assignmentLessExpression = #(create(EXPR,"EXPR",first,LT(1)), #assignmentLessExpression);}
-    ;
-
-closableBlockConstructorExpression
-    :   closableBlock
-    ;
-
-// Groovy syntax for "$x $y" or /$x $y/.
-stringConstructorExpression  {Token first = LT(1);}
-    :   cs:STRING_CTOR_START
-        { #cs.setType(STRING_LITERAL); }
-
-        stringConstructorValuePart
-
-        (   cm:STRING_CTOR_MIDDLE
-            { #cm.setType(STRING_LITERAL); }
-            stringConstructorValuePart
-        )*
-
-        ce:STRING_CTOR_END
-        { #ce.setType(STRING_LITERAL);
-          #stringConstructorExpression = #(create(STRING_CONSTRUCTOR,"STRING_CONSTRUCTOR",first,LT(1)), stringConstructorExpression);
-        }
-    ;
-
-stringConstructorValuePart
-    :
-    (   identifier
-    |   "this" |   "super"
-    |   openOrClosableBlock
-    )
-    ;
-
-/**
- * A list constructor is a argument list enclosed in square brackets, without labels.
- * Any argument can be decorated with a spread operator (*x), but not a label (a:x).
- * Examples:  [], [1], [1,2], [1,*l1,2], [*l1,*l2].
- * (The l1, l2 must be a sequence or null.)
- * <p>
- * A map constructor is an argument list enclosed in square brackets, with labels everywhere,
- * except on spread arguments, which stand for whole maps spliced in.
- * A colon alone between the brackets also forces the expression to be an empty map constructor.
- * Examples: [:], [a:1], [a:1,b:2], [a:1,*:m1,b:2], [*:m1,*:m2]
- * (The m1, m2 must be a map or null.)
- * Values associated with identical keys overwrite from left to right:
- * [a:1,a:2]  ===  [a:2]
- * <p>
- * Some malformed constructor expressions are not detected in the parser, but in a post-pass.
- * Bad examples: [1,b:2], [a:1,2], [:1].
- * (Note that method call arguments, by contrast, can be a mix of keyworded and non-keyworded arguments.)
- */
-// The parser allows a mix of labeled and unlabeled arguments, but there must be a semantic check that
-// the arguments are all labeled (or SPREAD_MAP_ARG) or all unlabeled (and not SPREAD_MAP_ARG).
-listOrMapConstructorExpression
-        { boolean hasLabels = false; }
-    :   lcon:LBRACK!
-        args:argList                 { hasLabels |= argListHasLabels;  }  // any argument label implies a map
-        RBRACK!
-        {   int type = hasLabels ? MAP_CONSTRUCTOR : LIST_CONSTRUCTOR;
-            #listOrMapConstructorExpression = #(create(type,"[",lcon,LT(1)), args);
-        }
-    |
-        /* Special case:  [:] is an empty map constructor. */
-        emcon:LBRACK^ COLON! RBRACK!   {#emcon.setType(MAP_CONSTRUCTOR);}
-    ;
-
-/** object instantiation.
- *  Trees are built as illustrated by the following input/tree pairs:
- *
- *  new T()
- *
- *  new
- *   |
- *   T --  ELIST
- *           |
- *          arg1 -- arg2 -- .. -- argn
- *
- *  new int[]
- *
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR
- *
- *  new int[] {1,2}
- *
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR -- ARRAY_INIT
- *                                  |
- *                                EXPR -- EXPR
- *                                  |       |
- *                                  1       2
- *
- *  new int[3]
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR
- *               |
- *             EXPR
- *               |
- *               3
- *
- *  new int[1][2]
- *
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR
- *               |
- *         ARRAY_DECLARATOR -- EXPR
- *               |               |
- *             EXPR              1
- *               |
- *               2
- *
- */
-newExpression {Token first = LT(1);}
-    :   "new"! nls! (ta:typeArguments!)? t:type!
-        (   nls!
-            mca:methodCallArgs[null]!
-
-            (
-                options { greedy=true; }:
-                cb:classBlock
-            )?
-
-            {#mca = #mca.getFirstChild();
-            #newExpression = #(create(LITERAL_new,"new",first,LT(1)), #ta, #t, #mca, #cb);}
-
-            //java 1.1
-            // Note: This will allow bad constructs like
-            //      new int[4][][3] {exp,exp}.
-            //      There needs to be a semantic check here...
-            // to make sure:
-            //   a) [ expr ] and [ ] are not mixed
-            //   b) [ expr ] and an init are not used together
-        |   ad:newArrayDeclarator! //(arrayInitializer)?
-            // Groovy does not support Java syntax for initialized new arrays.
-            // Use sequence constructors instead.
-            {#newExpression = #(create(LITERAL_new,"new",first,LT(1)), #ta, #t, #ad);}
-        )
-    ;
-
-argList
-    {
-        Token first = LT(1);
-        Token lastComma = null;
-        int hls=0, hls2=0;
-        boolean hasClosureList=false;
-        boolean trailingComma=false;
-        boolean sce=false;
-    }
-    :
-        // Note:  nls not needed, since we are inside parens,
-        // and those insignificant newlines are suppressed by the lexer.
-        (hls=argument
-        ((
-            (
-                SEMI! {hasClosureList=true;}
-                (
-                    sce=strictContextExpression[true]
-                    | { astFactory.addASTChild(currentAST,astFactory.create(EMPTY_STAT, "EMPTY_STAT")); }
-                )
-            )+
-            {#argList = #(create(CLOSURE_LIST,"CLOSURE_LIST",first,LT(1)), #argList);}
-        ) | (
-                (   {lastComma = LT(1);}
-                    COMMA!
-                    (
-                        (hls2=argument {hls |= hls2;})
-                        |
-                        (
-                         {  if (trailingComma) throw new NoViableAltException(lastComma, getFilename());
-                            trailingComma=true;
-                         }
-                        )
-                    )
-
-                )*
-                {#argList = #(create(ELIST,"ELIST",first,LT(1)), argList);}
-            )
-        ) | (
-            {#argList = create(ELIST,"ELIST",first,LT(1));}
-        )
-        )
-        {argListHasLabels = (hls&1)!=0; }
-    ;
-
-/** A single argument in (...) or [...].  Corresponds to to a method or closure parameter.
- *  May be labeled.  May be modified by the spread operator '*' ('*:' for keywords).
- */
-argument
-returns [byte hasLabelOrSpread = 0]
-{boolean sce=false;}
-    :
-        // Optional argument label.
-        // Usage:  Specifies a map key, or a keyworded argument.
-        (   (argumentLabelStart) =>
-            argumentLabel c:COLON^          {#c.setType(LABELED_ARG);}
-
-            {   hasLabelOrSpread |= 1;  }  // signal to caller the presence of a label
-
-        |   // Spread operator:  f(*[a,b,c])  ===  f(a,b,c);  f(1,*null,2)  ===  f(1,2).
-            sp:STAR^                        {#sp.setType(SPREAD_ARG);}
-            {   hasLabelOrSpread |= 2;  }  // signal to caller the presence of a spread operator
-            // spread maps are marked, as f(*:m) for f(a:x, b:y) if m==[a:x, b:y]
-            (
-                COLON!                      {#sp.setType(SPREAD_MAP_ARG);}
-                { hasLabelOrSpread |= 1; }  // signal to caller the presence of a label
-            )?
-        )?
-
-        sce=strictContextExpression[true]
-        {
-            require(LA(1) != COLON,
-                "illegal colon after argument expression",
-                "a complex label expression before a colon must be parenthesized");
-        }
-    ;
-
-/** A label for an argument is of the form a:b, 'a':b, "a":b, (a):b, etc..
- *      The labels in (a:b), ('a':b), and ("a":b) are in all ways equivalent,
- *      except that the quotes allow more spellings.
- *  Equivalent dynamically computed labels are (('a'):b) and ("${'a'}":b)
- *  but not ((a):b) or "$a":b, since the latter cases evaluate (a) as a normal identifier.
- *      Bottom line:  If you want a truly variable label, use parens and say ((a):b).
- */
-argumentLabel
-    :   (IDENT) =>
-        id:IDENT                  {#id.setType(STRING_LITERAL);}  // identifiers are self-quoting in this context
-    |   (keywordPropertyNames) =>
-        kw:keywordPropertyNames   {#kw.setType(STRING_LITERAL);}  // identifiers are self-quoting in this context
-    |   primaryExpression                                         // dynamic expression
-    ;
-
-/** For lookahead only.  Fast approximate parse of an argumentLabel followed by a colon. */
-argumentLabelStart!
-        // allow number and string literals as labels for maps
-    :   (
-            IDENT | keywordPropertyNames
-        |   constantNumber | STRING_LITERAL
-        |   (LPAREN | STRING_CTOR_START)=> balancedBrackets
-        )
-        COLON
-    ;
-
-newArrayDeclarator
-    :   (
-            // CONFLICT:
-            // newExpression is a primaryExpression which can be
-            // followed by an array index reference. This is ok,
-            // as the generated code will stay in this loop as
-            // long as it sees an LBRACK (proper behavior)
-            options {
-                warnWhenFollowAmbig = false;
-            }
-        :
-            lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);}
-                (expression[0])?
-            RBRACK!
-        )+
-    ;
-
-/** Numeric, string, regexp, boolean, or null constant. */
-constant
-    :   constantNumber
-    |   STRING_LITERAL
-    |   "true"
-    |   "false"
-    |   "null"
-    ;
-
-/** Numeric constant. */
-constantNumber
-    :   NUM_INT
-    |   NUM_FLOAT
-    |   NUM_LONG
-    |   NUM_DOUBLE
-    |   NUM_BIG_INT
-    |   NUM_BIG_DECIMAL
-    ;
-
-/** Fast lookahead across balanced brackets of all sorts. */
-balancedBrackets!
-    :   LPAREN balancedTokens RPAREN
-    |   LBRACK balancedTokens RBRACK
-    |   LCURLY balancedTokens RCURLY
-    |   STRING_CTOR_START balancedTokens STRING_CTOR_END
-    ;
-
-balancedTokens!
-    :   (   balancedBrackets
-        |   ~(LPAREN|LBRACK|LCURLY | STRING_CTOR_START
-             |RPAREN|RBRACK|RCURLY | STRING_CTOR_END)
-        )*
-    ;
-
-/** A statement separator is either a semicolon or a significant newline.
- *  Any number of additional (insignificant) newlines may accompany it.
- */
-//  (All the '!' signs simply suppress the default AST building.)
-//  Returns the type of the separator in this.sepToken, in case it matters.
-sep!
-    :   SEMI!
-        (options { greedy=true; }: NLS!)*
-        { sepToken = SEMI; }
-    |   NLS!                // this newline is significant!
-        { sepToken = NLS; }
-        (
-            options { greedy=true; }:
-            SEMI!           // this superfluous semicolon is gobbled
-            (options { greedy=true; }: NLS!)*
-            { sepToken = SEMI; }
-        )*
-    ;
-
-/** Zero or more insignificant newlines, all gobbled up and thrown away. */
-nls!
-    :
-        (options { greedy=true; }: NLS!)?
-        // Note:  Use '?' rather than '*', relying on the fact that the lexer collapses
-        // adjacent NLS tokens, always.  This lets the parser use its LL(3) lookahead
-        // to "see through" sequences of newlines.  If there were a '*' here, the lookahead
-        // would be weaker, since the parser would have to be prepared for long sequences
-        // of NLS tokens.
-    ;
-
-/** Zero or more insignificant newlines, all gobbled up and thrown away,
- *  but a warning message is left for the user, if there was a newline.
- */
-nlsWarn!
-    :
-        (   (NLS)=>
-            { addWarning(
-              "A newline at this point does not follow the Groovy Coding Conventions.",
-              "Keep this statement on one line, or use curly braces to break across multiple lines."
-            ); }
-        )?
-        nls!
-    ;
-
-//----------------------------------------------------------------------------
-// The Groovy scanner
-//----------------------------------------------------------------------------
-class GroovyLexer extends Lexer;
-
-options {
-    exportVocab=Groovy;             // call the vocabulary "Groovy"
-    testLiterals=false;             // don't automatically test for literals
-    k=4;                                    // four characters of lookahead
-    charVocabulary='\u0000'..'\uFFFF';
-    // without inlining some bitset tests, couldn't do unicode;
-    // I need to make ANTLR generate smaller bitsets; see
-    // bottom of GroovyLexer.java
-    codeGenBitsetTestThreshold=20;
-}
-
-{
-    /** flag for enabling the "assert" keyword */
-    private boolean assertEnabled = true;
-    /** flag for enabling the "enum" keyword */
-    private boolean enumEnabled = true;
-    /** flag for including whitespace tokens (for IDE preparsing) */
-    private boolean whitespaceIncluded = false;
-
-    /** Enable the "assert" keyword */
-    public void enableAssert(boolean shouldEnable) { assertEnabled = shouldEnable; }
-    /** Query the "assert" keyword state */
-    public boolean isAssertEnabled() { return assertEnabled; }
-    /** Enable the "enum" keyword */
-    public void enableEnum(boolean shouldEnable) { enumEnabled = shouldEnable; }
-    /** Query the "enum" keyword state */
-    public boolean isEnumEnabled() { return enumEnabled; }
-
-    /** Include whitespace tokens.  Note that this breaks the parser.   */
-    public void setWhitespaceIncluded(boolean z) { whitespaceIncluded = z; }
-    /** Are whitespace tokens included? */
-    public boolean isWhitespaceIncluded() { return whitespaceIncluded; }
-
-    {
-        // Initialization actions performed on construction.
-        setTabSize(1);  // get rid of special tab interpretation, for IDEs and general clarity
-    }
-
-    /** Bumped when inside '[x]' or '(x)', reset inside '{x}'.  See ONE_NL.  */
-    protected int parenLevel = 0;
-    protected int suppressNewline = 0;  // be really mean to newlines inside strings
-    protected static final int SCS_TYPE = 3, SCS_VAL = 4, SCS_LIT = 8, SCS_LIMIT = 16;
-    protected static final int SCS_SQ_TYPE = 0, SCS_TQ_TYPE = 1, SCS_RE_TYPE = 2, SCS_DRE_TYPE = 3;
-    protected int stringCtorState = 0;  // hack string and regexp constructor boundaries
-    /** Push parenLevel here and reset whenever inside '{x}'. */
-    protected ArrayList parenLevelStack = new ArrayList();
-    protected int lastSigTokenType = EOF;  // last returned non-whitespace token
-
-    public void setTokenObjectClass(String name) {/*ignore*/}
-
-    protected Token makeToken(int t) {
-        GroovySourceToken tok = new GroovySourceToken(t);
-        tok.setColumn(inputState.getTokenStartColumn());
-        tok.setLine(inputState.getTokenStartLine());
-        tok.setColumnLast(inputState.getColumn());
-        tok.setLineLast(inputState.getLine());
-        return tok;
-    }
-
-    protected void pushParenLevel() {
-        parenLevelStack.add(Integer.valueOf(parenLevel*SCS_LIMIT + stringCtorState));
-        parenLevel = 0;
-        stringCtorState = 0;
-    }
-
-    protected void popParenLevel() {
-        int npl = parenLevelStack.size();
-        if (npl == 0)  return;
-        int i = ((Integer) parenLevelStack.remove(--npl)).intValue();
-        parenLevel      = i / SCS_LIMIT;
-        stringCtorState = i % SCS_LIMIT;
-    }
-
-    protected void restartStringCtor(boolean expectLiteral) {
-        if (stringCtorState != 0) {
-            stringCtorState = (expectLiteral? SCS_LIT: SCS_VAL) + (stringCtorState & SCS_TYPE);
-        }
-    }
-
-    protected boolean allowRegexpLiteral() {
-        return !isExpressionEndingToken(lastSigTokenType);
-    }
-
-    /** Return true for an operator or punctuation which can end an expression.
-     *  Return true for keywords, identifiers, and literals.
-     *  Return true for tokens which can end expressions (right brackets, ++, --).
-     *  Return false for EOF and all other operator and punctuation tokens.
-     *  Used to suppress the recognition of /foo/ as opposed to the simple division operator '/'.
-     */
-    // Cf. 'constant' and 'balancedBrackets' rules in the grammar.)
-    protected static boolean isExpressionEndingToken(int ttype) {
-        switch (ttype) {
-        case INC:               // x++ / y
-        case DEC:               // x-- / y
-        case RPAREN:            // (x) / y
-        case RBRACK:            // f[x] / y
-        case RCURLY:            // f{x} / y
-        case STRING_LITERAL:    // "x" / y
-        case STRING_CTOR_END:   // "$x" / y
-        case NUM_INT:           // 0 / y
-        case NUM_FLOAT:         // 0f / y
-        case NUM_LONG:          // 0l / y
-        case NUM_DOUBLE:        // 0.0 / y
-        case NUM_BIG_INT:       // 0g / y
-        case NUM_BIG_DECIMAL:   // 0.0g / y
-        case IDENT:             // x / y
-        // and a bunch of keywords (all of them; no sense picking and choosing):
-        case LITERAL_as:
-        case LITERAL_assert:
-        case LITERAL_boolean:
-        case LITERAL_break:
-        case LITERAL_byte:
-        case LITERAL_case:
-        case LITERAL_catch:
-        case LITERAL_char:
-        case LITERAL_class:
-        case LITERAL_continue:
-        case LITERAL_def:
-        case LITERAL_default:
-        case LITERAL_double:
-        case LITERAL_else:
-        case LITERAL_enum:
-        case LITERAL_extends:
-        case LITERAL_false:
-        case LITERAL_finally:
-        case LITERAL_float:
-        case LITERAL_for:
-        case LITERAL_if:
-        case LITERAL_implements:
-        case LITERAL_import:
-        case LITERAL_in:
-        case LITERAL_instanceof:
-        case LITERAL_int:
-        case LITERAL_interface:
-        case LITERAL_long:
-        case LITERAL_native:
-        case LITERAL_new:
-        case LITERAL_null:
-        case LITERAL_package:
-        case LITERAL_private:
-        case LITERAL_protected:
-        case LITERAL_public:
-        case LITERAL_return:
-        case LITERAL_short:
-        case LITERAL_static:
-        case LITERAL_super:
-        case LITERAL_switch:
-        case LITERAL_synchronized:
-        case LITERAL_trait:
-        case LITERAL_this:
-        case LITERAL_threadsafe:
-        case LITERAL_throw:
-        case LITERAL_throws:
-        case LITERAL_transient:
-        case LITERAL_true:
-        case LITERAL_try:
-        case LITERAL_void:
-        case LITERAL_volatile:
-        case LITERAL_while:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    protected void newlineCheck(boolean check) throws RecognitionException {
-        if (check && suppressNewline > 0) {
-            require(suppressNewline == 0,
-                "end of line reached within a simple string 'x' or \"x\" or /x/",
-                "for multi-line literals, use triple quotes '''x''' or \"\"\"x\"\"\" or /x/ or $/x/$");
-            suppressNewline = 0;  // shut down any flood of errors
-        }
-        newline();
-    }
-
-    protected boolean atValidDollarEscape() throws CharStreamException {
-        // '$' (('{' | LETTER) =>
-        int k = 1;
-        char lc = LA(k++);
-        if (lc != '$')  return false;
-        lc = LA(k++);
-        return (lc == '{' || (lc != '$' && Character.isJavaIdentifierStart(lc)));
-    }
-
-    protected boolean atDollarDollarEscape() throws CharStreamException {
-        return LA(1) == '$' && LA(2) == '$';
-    }
-
-    protected boolean atMultiCommentStart() throws CharStreamException {
-        return LA(1) == '/' && LA(2) == '*';
-    }
-
-    protected boolean atDollarSlashEscape() throws CharStreamException {
-        return LA(1) == '$' && LA(2) == '/';
-    }
-
-    /** This is a bit of plumbing which resumes collection of string constructor bodies,
-     *  after an embedded expression has been parsed.
-     *  Usage:  new GroovyRecognizer(new GroovyLexer(in).plumb()).
-     */
-    public TokenStream plumb() {
-        return new TokenStream() {
-            public Token nextToken() throws TokenStreamException {
-                if (stringCtorState >= SCS_LIT) {
-                    // This goo is modeled upon the ANTLR code for nextToken:
-                    int quoteType = (stringCtorState & SCS_TYPE);
-                    stringCtorState = 0;  // get out of this mode, now
-                    resetText();
-                    try {
-                        switch (quoteType) {
-                        case SCS_SQ_TYPE:
-                            mSTRING_CTOR_END(true, /*fromStart:*/false, false); break;
-                        case SCS_TQ_TYPE:
-                            mSTRING_CTOR_END(true, /*fromStart:*/false, true); break;
-                        case SCS_RE_TYPE:
-                            mREGEXP_CTOR_END(true, /*fromStart:*/false); break;
-                        case SCS_DRE_TYPE:
-                            mDOLLAR_REGEXP_CTOR_END(true, /*fromStart:*/false); break;
-                        default:  throw new AssertionError(false);
-                        }
-                        lastSigTokenType = _returnToken.getType();
-                        return _returnToken;
-                    } catch (RecognitionException e) {
-                        throw new TokenStreamRecognitionException(e);
-                    } catch (CharStreamException cse) {
-                        if ( cse instanceof CharStreamIOException ) {
-                            throw new TokenStreamIOException(((CharStreamIOException)cse).io);
-                        }
-                        else {
-                            throw new TokenStreamException(cse.getMessage());
-                        }
-                    }
-                }
-                Token token = GroovyLexer.this.nextToken();
-                int lasttype = token.getType();
-                if (whitespaceIncluded) {
-                    switch (lasttype) {  // filter out insignificant types
-                    case WS:
-                    case ONE_NL:
-                    case SL_COMMENT:
-                    case ML_COMMENT:
-                        lasttype = lastSigTokenType;  // back up!
-                    }
-                }
-                lastSigTokenType = lasttype;
-                return token;
-            }
-        };
-    }
-
-    // stuff to adjust ANTLR's tracing machinery
-    public static boolean tracing = false;  // only effective if antlr.Tool is run with -traceLexer
-    public void traceIn(String rname) throws CharStreamException {
-        if (!GroovyLexer.tracing)  return;
-        super.traceIn(rname);
-    }
-    public void traceOut(String rname) throws CharStreamException {
-        if (!GroovyLexer.tracing)  return;
-        if (_returnToken != null)  rname += tokenStringOf(_returnToken);
-        super.traceOut(rname);
-    }
-    private static java.util.HashMap ttypes;
-    private static String tokenStringOf(Token t) {
-        if (ttypes == null) {
-            java.util.HashMap map = new java.util.HashMap();
-            java.lang.reflect.Field[] fields = GroovyTokenTypes.class.getDeclaredFields();
-            for (int i = 0; i < fields.length; i++) {
-                if (fields[i].getType() != int.class)  continue;
-                try {
-                    map.put(fields[i].get(null), fields[i].getName());
-                } catch (IllegalAccessException ee) {
-                }
-            }
-            ttypes = map;
-        }
-        Integer tt = Integer.valueOf(t.getType());
-        Object ttn = ttypes.get(tt);
-        if (ttn == null)  ttn = "<"+tt+">";
-        return "["+ttn+",\""+t.getText()+"\"]";
-    }
-
-    protected GroovyRecognizer parser;  // little-used link; TODO: get rid of
-    private void require(boolean z, String problem, String solution) throws SemanticException {
-        // TODO: Direct to a common error handler, rather than through the parser.
-        if (!z && parser!=null)  parser.requireFailed(problem, solution);
-        if (!z) {
-            int lineNum = inputState.getLine(), colNum = inputState.getColumn();
-            throw new SemanticException(problem + ";\n   solution: " + solution, getFilename(), lineNum, colNum);
-        }
-    }
-}
-
-// OPERATORS
-QUESTION          options {paraphrase="'?'";}           :   '?'             ;
-LPAREN            options {paraphrase="'('";}           :   '('             {++parenLevel;};
-RPAREN            options {paraphrase="')'";}           :   ')'             {--parenLevel;};
-LBRACK            options {paraphrase="'['";}           :   '['             {++parenLevel;};
-RBRACK            options {paraphrase="']'";}           :   ']'             {--parenLevel;};
-LCURLY            options {paraphrase="'{'";}           :   '{'             {pushParenLevel();};
-RCURLY            options {paraphrase="'}'";}           :   '}'             {popParenLevel(); if(stringCtorState!=0) restartStringCtor(true);};
-COLON             options {paraphrase="':'";}           :   ':'             ;
-COMMA             options {paraphrase="','";}           :   ','             ;
-DOT               options {paraphrase="'.'";}           :   '.'             ;
-ASSIGN            options {paraphrase="'='";}           :   '='             ;
-COMPARE_TO        options {paraphrase="'<=>'";}         :   "<=>"           ;
-EQUAL             options {paraphrase="'=='";}          :   "=="            ;
-IDENTICAL         options {paraphrase="'==='";}         :   "==="           ;
-LNOT              options {paraphrase="'!'";}           :   '!'             ;
-BNOT              options {paraphrase="'~'";}           :   '~'             ;
-NOT_EQUAL         options {paraphrase="'!='";}          :   "!="            ;
-NOT_IDENTICAL     options {paraphrase="'!=='";}         :   "!=="           ;
-protected  //switched from combined rule
-DIV               options {paraphrase="'/'";}           :   '/'             ;
-protected  //switched from combined rule
-DIV_ASSIGN        options {paraphrase="'/='";}          :   "/="            ;
-PLUS              options {paraphrase="'+'";}           :   '+'             ;
-PLUS_ASSIGN       options {paraphrase="'+='";}          :   "+="            ;
-INC               options {paraphrase="'++'";}          :   "++"            ;
-MINUS             options {paraphrase="'-'";}           :   '-'             ;
-MINUS_ASSIGN      options {paraphrase="'-='";}          :   "-="            ;
-DEC               options {paraphrase="'--'";}          :   "--"            ;
-STAR              options {paraphrase="'*'";}           :   '*'             ;
-STAR_ASSIGN       options {paraphrase="'*='";}          :   "*="            ;
-MOD               options {paraphrase="'%'";}           :   '%'             ;
-MOD_ASSIGN        options {paraphrase="'%='";}          :   "%="            ;
-SR                options {paraphrase="'>>'";}          :   ">>"            ;
-SR_ASSIGN         options {paraphrase="'>>='";}         :   ">>="           ;
-BSR               options {paraphrase="'>>>'";}         :   ">>>"           ;
-BSR_ASSIGN        options {paraphrase="'>>>='";}        :   ">>>="          ;
-GE                options {paraphrase="'>='";}          :   ">="            ;
-GT                options {paraphrase="'>'";}           :   ">"             ;
-SL                options {paraphrase="'<<'";}          :   "<<"            ;
-SL_ASSIGN         options {paraphrase="'<<='";}         :   "<<="           ;
-LE                options {paraphrase="'<='";}          :   "<="            ;
-LT                options {paraphrase="'<'";}           :   '<'             ;
-BXOR              options {paraphrase="'^'";}           :   '^'             ;
-BXOR_ASSIGN       options {paraphrase="'^='";}          :   "^="            ;
-BOR               options {paraphrase="'|'";}           :   '|'             ;
-BOR_ASSIGN        options {paraphrase="'|='";}          :   "|="            ;
-LOR               options {paraphrase="'||'";}          :   "||"            ;
-BAND              options {paraphrase="'&'";}           :   '&'             ;
-BAND_ASSIGN       options {paraphrase="'&='";}          :   "&="            ;
-LAND              options {paraphrase="'&&'";}          :   "&&"            ;
-SEMI              options {paraphrase="';'";}           :   ';'             ;
-protected
-DOLLAR            options {paraphrase="'$'";}           :   '$'             ;
-RANGE_INCLUSIVE   options {paraphrase="'..'";}          :   ".."            ;
-RANGE_EXCLUSIVE   options {paraphrase="'..<'";}         :   "..<"           ;
-TRIPLE_DOT        options {paraphrase="'...'";}         :   "..."           ;
-SPREAD_DOT        options {paraphrase="'*.'";}          :   "*."            ;
-OPTIONAL_DOT      options {paraphrase="'?.'";}          :   "?."            ;
-ELVIS_OPERATOR    options {paraphrase="'?:'";}          :   "?:"            ;
-MEMBER_POINTER    options {paraphrase="'.&'";}          :   ".&"            ;
-REGEX_FIND        options {paraphrase="'=~'";}          :   "=~"            ;
-REGEX_MATCH       options {paraphrase="'==~'";}         :   "==~"           ;
-STAR_STAR         options {paraphrase="'**'";}          :   "**"            ;
-STAR_STAR_ASSIGN  options {paraphrase="'**='";}         :   "**="           ;
-CLOSABLE_BLOCK_OP options {paraphrase="'->'";}          :   "->"            ;
-
-// Whitespace -- ignored
-WS
-options {
-    paraphrase="whitespace";
-}
-    :
-        (
-            options { greedy=true; }:
-            ' '
-        |   '\t'
-        |   '\f'
-        |   '\\' ONE_NL[false]
-        )+
-        { if (!whitespaceIncluded)  _ttype = Token.SKIP; }
-    ;
-
-protected
-ONE_NL![boolean check]
-options {
-    paraphrase="a newline";
-}
- :   // handle newlines, which are significant in Groovy
-        (   options {generateAmbigWarnings=false;}
-        :   "\r\n"  // Evil DOS
-        |   '\r'    // Macintosh
-        |   '\n'    // Unix (the right way)
-        )
-        {
-            // update current line number for error reporting
-            newlineCheck(check);
-        }
-    ;
-
-// Group any number of newlines (with comments and whitespace) into a single token.
-// This reduces the amount of parser lookahead required to parse around newlines.
-// It is an invariant that the parser never sees NLS tokens back-to-back.
-NLS
-options {
-    paraphrase="some newlines, whitespace or comments";
-}
-    :   ONE_NL[true]
-        (   {!whitespaceIncluded}?
-            (ONE_NL[true] | WS | SL_COMMENT | ML_COMMENT)+
-            // (gobble, gobble)*
-        )?
-        // Inside (...) and [...] but not {...}, ignore newlines.
-        {   if (whitespaceIncluded) {
-                // keep the token as-is
-            } else if (parenLevel != 0) {
-                // when directly inside parens, all newlines are ignored here
-                $setType(Token.SKIP);
-            } else {
-                // inside {...}, newlines must be explicitly matched as 'nls!'
-                $setText("<newline>");
-            }
-        }
-    ;
-
-// Single-line comments
-SL_COMMENT
-options {
-    paraphrase="a single line comment";
-}
-    :   "//"
-        (
-            options {  greedy = true;  }:
-            // '\uffff' means the EOF character.
-            // This will fix the issue GROOVY-766 (infinite loop).
-            ~('\n'|'\r'|'\uffff')
-        )*
-        {
-            if (!whitespaceIncluded) $setType(Token.SKIP);
-        }
-        //This might be significant, so don't swallow it inside the comment:
-        //ONE_NL
-    ;
-
-// Script-header comments
-SH_COMMENT
-options {
-    paraphrase="a script header";
-}
-    :   {getLine() == 1 && getColumn() == 1}?  "#!"
-        (
-            options {  greedy = true;  }:
-            // '\uffff' means the EOF character.
-            // This will fix the issue GROOVY-766 (infinite loop).
-            ~('\n'|'\r'|'\uffff')
-        )*
-        { if (!whitespaceIncluded)  $setType(Token.SKIP); }
-        //ONE_NL  //Never a significant newline, but might as well separate it.
-    ;
-
-// multiple-line comments
-ML_COMMENT
-options {
-    paraphrase="a multi-line comment";
-}
-    :   { atMultiCommentStart() }? "/*"
-        (   /*  '\r' '\n' can be matched in one alternative or by matching
-                '\r' in one iteration and '\n' in another. I am trying to
-                handle any flavor of newline that comes in, but the language
-                that allows both "\r\n" and "\r" and "\n" to all be valid
-                newline is ambiguous. Consequently, the resulting grammar
-                must be ambiguous. I'm shutting this warning off.
-             */
-            options {
-                    generateAmbigWarnings=false;
-            }
-        :
-            ( '*' ~'/' ) => '*'
-        |   ONE_NL[true]
-        |   ~('*'|'\n'|'\r'|'\uffff')
-        )*
-        "*/"
-        {
-            if (!whitespaceIncluded) $setType(Token.SKIP);
-        }
-    ;
-
-// string literals
-STRING_LITERAL
-options {
-    paraphrase="a string literal";
-}
-        {int tt=0;}
-    :   ("'''") =>  //...shut off ambiguity warning
-        "'''"!
-        (   STRING_CH | ESC | '"' | '$' | STRING_NL[true]
-        |   ('\'' (~'\'' | '\'' ~'\'')) => '\''  // allow 1 or 2 close quotes
-        )*
-        "'''"!
-    |   '\''!
-                                {++suppressNewline;}
-        (   STRING_CH | ESC | '"' | '$'  )*
-                                {--suppressNewline;}
-        '\''!
-    |   ("\"\"\"") =>  //...shut off ambiguity warning
-        "\"\"\""!
-        tt=STRING_CTOR_END[true, /*tripleQuote:*/ true]
-        {$setType(tt);}
-    |   '"'!
-                                {++suppressNewline;}
-        tt=STRING_CTOR_END[true, /*tripleQuote:*/ false]
-        {$setType(tt);}
-    ;
-
-protected
-STRING_CTOR_END[boolean fromStart, boolean tripleQuote]
-returns [int tt=STRING_CTOR_END]
-options {
-    paraphrase="a string literal end";
-}
-        { boolean dollarOK = false; }
-    :
-        (
-            options {  greedy = true;  }:
-            STRING_CH | ESC | '\'' | STRING_NL[tripleQuote]
-        |   ('"' (~'"' | '"' ~'"'))=> {tripleQuote}? '"'  // allow 1 or 2 close quotes
-        )*
-        (   (   { !tripleQuote }? "\""!
-            |   {  tripleQuote }? "\"\"\""!
-            )
-            {
-                if (fromStart)      tt = STRING_LITERAL;  // plain string literal!
-                if (!tripleQuote)   {--suppressNewline;}
-                // done with string constructor!
-                //assert(stringCtorState == 0);
-            }
-        |   {dollarOK = atValidDollarEscape();}
-            '$'!
-            {
-                require(dollarOK,
-                    "illegal string body character after dollar sign",
-                    "either escape a literal dollar sign \"\\$5\" or bracket the value expression \"${5}\"");
-                // Yes, it's a string constructor, and we've got a value part.
-                tt = (fromStart ? STRING_CTOR_START : STRING_CTOR_MIDDLE);
-                stringCtorState = SCS_VAL + (tripleQuote? SCS_TQ_TYPE: SCS_SQ_TYPE);
-            }
-        )
-        {   $setType(tt);  }
-    ;
-
-protected
-STRING_CH
-options {
-    paraphrase="a string character";
-}
-    :   ~('"'|'\''|'\\'|'$'|'\n'|'\r'|'\uffff')
-    ;
-
-REGEXP_LITERAL
-options {
-    paraphrase="a multiline regular expression literal";
-}
-        {int tt=0;}
-    :   { !atMultiCommentStart() }?
-        (   {allowRegexpLiteral()}?
-            '/'!
-            {++suppressNewline;}
-            //Do this, but require it to be non-trivial:  REGEXP_CTOR_END[true]
-            // There must be at least one symbol or $ escape, lest the regexp collapse to '//'.
-            // (This should be simpler, but I don't know how to do it w/o ANTLR warnings vs. '//' comments.)
-            (
-                REGEXP_SYMBOL
-                tt=REGEXP_CTOR_END[true]
-            |   {!atValidDollarEscape()}? '$'
-                tt=REGEXP_CTOR_END[true]
-            |   '$'!
-                {
-                    // Yes, it's a regexp constructor, and we've got a value part.
-                    tt = STRING_CTOR_START;
-                    stringCtorState = SCS_VAL + SCS_RE_TYPE;
-                }
-            )
-            {$setType(tt);}
-
-        |   ( '/' ~'=' ) => DIV {$setType(DIV);}
-        |   DIV_ASSIGN {$setType(DIV_ASSIGN);}
-        )
-    ;
-
-DOLLAR_REGEXP_LITERAL
-options {
-    paraphrase="a multiline dollar escaping regular expression literal";
-}
-        {int tt=0;}
-    :   {allowRegexpLiteral()}? "$/"!
-        // Do this, but require it to be non-trivial:  DOLLAR_REGEXP_CTOR_END[true]
-        // There must be at least one symbol or $ escape, otherwise the regexp collapses.
-        (
-            DOLLAR_REGEXP_SYMBOL
-            tt=DOLLAR_REGEXP_CTOR_END[true]
-        | {!atValidDollarEscape() && !atDollarSlashEscape() && !atDollarDollarEscape()}? '$'
-            tt=DOLLAR_REGEXP_CTOR_END[true]
-        |
-            ('$' '/') => ESCAPED_SLASH
-            tt=DOLLAR_REGEXP_CTOR_END[true]
-        |
-            ('$' '$') => ESCAPED_DOLLAR
-            tt=DOLLAR_REGEXP_CTOR_END[true]
-        |
-            '$'!
-            {
-                // Yes, it's a regexp constructor, and we've got a value part.
-                tt = STRING_CTOR_START;
-                stringCtorState = SCS_VAL + SCS_DRE_TYPE;
-            }
-        )
-        {$setType(tt);}
-    ;
-
-protected
-REGEXP_CTOR_END[boolean fromStart]
-returns [int tt=STRING_CTOR_END]
-options {
-    paraphrase="a multiline regular expression literal end";
-}
-    :
-        (
-            options {  greedy = true;  }:
-            REGEXP_SYMBOL
-        |
-            {!atValidDollarEscape()}? '$'
-        )*
-        (   '/'!
-            {
-                if (fromStart)      tt = STRING_LITERAL;  // plain regexp literal!
-                {--suppressNewline;}
-                // done with regexp constructor!
-                //assert(stringCtorState == 0);
-            }
-        |   '$'!
-            {
-                // Yes, it's a regexp constructor, and we've got a value part.
-                tt = (fromStart ? STRING_CTOR_START : STRING_CTOR_MIDDLE);
-                stringCtorState = SCS_VAL + SCS_RE_TYPE;
-            }
-        )
-        {   $setType(tt);  }
-    ;
-
-protected
-DOLLAR_REGEXP_CTOR_END[boolean fromStart]
-returns [int tt=STRING_CTOR_END]
-options {
-    paraphrase="a multiline dollar escaping regular expression literal end";
-}
-    :
-        (
-            options {  greedy = true;  }:
-            { !(LA(1) == '/' && LA(2) == '$') }? DOLLAR_REGEXP_SYMBOL
-        |
-            ('$' '/') => ESCAPED_SLASH
-        |
-            ('$' '$') => ESCAPED_DOLLAR
-        |
-            {!atValidDollarEscape() && !atDollarSlashEscape() && !atDollarDollarEscape()}? '$'
-        )*
-        (
-            "/$"!
-            {
-                if (fromStart)      tt = STRING_LITERAL;  // plain regexp literal!
-            }
-        |   '$'!
-            {
-                // Yes, it's a regexp constructor, and we've got a value part.
-                tt = (fromStart ? STRING_CTOR_START : STRING_CTOR_MIDDLE);
-                stringCtorState = SCS_VAL + SCS_DRE_TYPE;
-            }
-        )
-        {   $setType(tt);  }
-    ;
-
-protected ESCAPED_SLASH  : '$' '/' { $setText('/'); };
-
-protected ESCAPED_DOLLAR : '$' '$' { $setText('$'); };
-
-protected
-REGEXP_SYMBOL
-options {
-    paraphrase="a multiline regular expression character";
-}
-    :
-        ~('/'|'$'|'\\'|'\n'|'\r'|'\uffff')
-    |   { LA(2)!='/' && LA(2)!='\n' && LA(2)!='\r' }? '\\' // backslash only escapes '/' and EOL
-    |   '\\' '/'                   { $setText('/'); }
-    |   STRING_NL[true]
-    |!  '\\' ONE_NL[false]
-    ;
-
-protected
-DOLLAR_REGEXP_SYMBOL
-options {
-    paraphrase="a multiline dollar escaping regular expression character";
-}
-    :
-        ~('$' | '\\' | '/' | '\n' | '\r' | '\uffff')
-    |   { LA(2)!='\n' && LA(2)!='\r' }? '\\'               // backslash only escapes EOL
-    |   ('/' ~'$') => '/'                                  // allow a slash if not followed by a $
-    |   STRING_NL[true]
-    |!  '\\' ONE_NL[false]
-    ;
-
-// escape sequence -- note that this is protected; it can only be called
-// from another lexer rule -- it will not ever directly return a token to
-// the parser
-// There are various ambiguities hushed in this rule. The optional
-// '0'...'9' digit matches should be matched here rather than letting
-// them go back to STRING_LITERAL to be matched. ANTLR does the
-// right thing by matching immediately; hence, it's ok to shut off
-// the FOLLOW ambig warnings.
-protected
-ESC
-options {
-    paraphrase="an escape sequence";
-}
-    :   '\\'!
-        (   'n'     {$setText("\n");}
-        |   'r'     {$setText("\r");}
-        |   't'     {$setText("\t");}
-        |   'b'     {$setText("\b");}
-        |   'f'     {$setText("\f");}
-        |   '"'
-        |   '\''
-        |   '\\'
-        |   '$'     //escape Groovy $ operator uniformly also
-        |   ('u')+ {$setText("");}
-            HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
-            {char ch = (char)Integer.parseInt($getText,16); $setText(ch);}
-        |   '0'..'3'
-            (
-                options {
-                    warnWhenFollowAmbig = false;
-                }
-            :   '0'..'7'
-                (
-                    options {
-                        warnWhenFollowAmbig = false;
-                    }
-                :   '0'..'7'
-                )?
-            )?
-            {char ch = (char)Integer.parseInt($getText,8); $setText(ch);}
-        |   '4'..'7'
-            (
-                options {
-                    warnWhenFollowAmbig = false;
-                }
-            :   '0'..'7'
-            )?
-            {char ch = (char)Integer.parseInt($getText,8); $setText(ch);}
-        )
-    |!  '\\' ONE_NL[false]
-    ;
-
-protected
-STRING_NL[boolean allowNewline]
-options {
-    paraphrase="a newline inside a string";
-}
-    :  {if (!allowNewline) throw new MismatchedCharException('\n', '\n', true, this); }
-       ONE_NL[false] { $setText('\n'); }
-    ;
-
-// hexadecimal digit (again, note it's protected!)
-protected
-HEX_DIGIT
-options {
-    paraphrase="a hexadecimal digit";
-}
-    :   ('0'..'9'|'A'..'F'|'a'..'f')
-    ;
-
-// a dummy rule to force vocabulary to be all characters (except special
-// ones that ANTLR uses internally (0 to 2)
-protected
-VOCAB
-options {
-    paraphrase="a character";
-}
-    :   '\3'..'\377'
-    ;
-
-// an identifier. Note that testLiterals is set to true! This means
-// that after we match the rule, we look in the literals table to see
-// if it's a literal or really an identifier
-IDENT
-options {
-    paraphrase="an identifier";
-}
-    //options {testLiterals=true;}  // Actually, this is done manually in the actions below.
-    :   ( {stringCtorState == 0}? (DOLLAR|LETTER) (LETTER|DIGIT|DOLLAR)* | LETTER (LETTER|DIGIT)* )
-        {
-            if (stringCtorState != 0) {
-                if (LA(1) == '.' && LA(2) != '$' &&
-                        Character.isJavaIdentifierStart(LA(2))) {
-                    // pick up another name component before going literal again:
-                    restartStringCtor(false);
-                } else {
-                    // go back to the string
-                    restartStringCtor(true);
-                }
-            }
-            int ttype = testLiteralsTable(IDENT);
-            // Java doesn't have the keywords 'as', 'in' or 'def so we make some allowances
-            // for them in package names for better integration with existing Java packages
-            if ((ttype == LITERAL_as || ttype == LITERAL_def || ttype == LITERAL_in || ttype == LITERAL_trait) &&
-                (LA(1) == '.' || lastSigTokenType == DOT || lastSigTokenType == LITERAL_package)) {
-                ttype = IDENT;
-            }
-            // allow access to classes with the name package
-            if ((ttype == LITERAL_package) &&
-                (LA(1) == '.' || lastSigTokenType == DOT || lastSigTokenType == LITERAL_import
-                || (LA(1) == ')' && lastSigTokenType == LPAREN))) {
-                ttype = IDENT;
-            }
-            if (ttype == LITERAL_static && LA(1) == '.') {
-                ttype = IDENT;
-            }
-
-            $setType(ttype);
-
-            // check if "assert" keyword is enabled
-            if (assertEnabled && "assert".equals($getText)) {
-                $setType(LITERAL_assert); // set token type for the rule in the parser
-            }
-            // check if "enum" keyword is enabled
-            if (enumEnabled && "enum".equals($getText)) {
-                $setType(LITERAL_enum); // set token type for the rule in the parser
-            }
-        }
-    ;
-
-protected
-LETTER
-options {
-    paraphrase="a letter";
-}
-    :   'a'..'z'|'A'..'Z'|'\u00C0'..'\u00D6'|'\u00D8'..'\u00F6'|'\u00F8'..'\u00FF'|'\u0100'..'\uFFFE'|'_'
-    // TODO:  Recognize all the Java identifier starts here (except '$').
-    ;
-
-protected
-DIGIT
-options {
-    paraphrase="a digit";
-}
-    :   '0'..'9'
-    // TODO:  Recognize all the Java identifier parts here (except '$').
-    ;
-
-protected
-DIGITS_WITH_UNDERSCORE
-options {
-    paraphrase="a sequence of digits and underscores, bordered by digits";
-}
-    :   DIGIT (DIGITS_WITH_UNDERSCORE_OPT)?
-    ;
-
-protected
-DIGITS_WITH_UNDERSCORE_OPT
-options {
-    paraphrase="a sequence of digits and underscores with maybe underscore starting";
-}
-    :   (DIGIT | '_')* DIGIT
-    ;
-
-// a numeric literal
-NUM_INT
-options {
-    paraphrase="a numeric literal";
-}
-    {boolean isDecimal=false; Token t=null;}
-    :
-        // TODO:  This complex pattern seems wrong.  Verify or fix.
-        (   '0' {isDecimal = true;} // special case for just '0'
-            (   // hex digits
-                ('x'|'X')
-                {isDecimal = false;}
-                HEX_DIGIT
-                (   options { warnWhenFollowAmbig=false; }
-                    : (options { warnWhenFollowAmbig=false; } : HEX_DIGIT | '_')*
-                    HEX_DIGIT
-                )?
-
-            |   //binary literal
-                ('b'|'B') ('0'|'1') (('0'|'1'|'_')* ('0'|'1'))?
-                {isDecimal = false;}
-
-            |   //float or double with leading zero
-                (   DIGITS_WITH_UNDERSCORE
-                    ( '.' DIGITS_WITH_UNDERSCORE | EXPONENT | FLOAT_SUFFIX)
-                ) => DIGITS_WITH_UNDERSCORE
-
-            |   // octal
-                ('0'..'7') (('0'..'7'|'_')* ('0'..'7'))?
-                {isDecimal = false;}
-            )?
-        |   ('1'..'9') (DIGITS_WITH_UNDERSCORE_OPT)? {isDecimal=true;}               // non-zero decimal
-        )
-        (   ('l'|'L') { _ttype = NUM_LONG; }
-        |   ('i'|'I') { _ttype = NUM_INT; }
-        |   BIG_SUFFIX { _ttype = NUM_BIG_INT; }
-
-        // only check to see if it's a float if looks like decimal so far
-        |
-            (~'.' | '.' ('0'..'9')) =>
-            {isDecimal}?
-            (   '.' DIGITS_WITH_UNDERSCORE (e:EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;} | g2:BIG_SUFFIX {t=g2;})?
-            |   EXPONENT (f3:FLOAT_SUFFIX {t=f3;} | g3:BIG_SUFFIX {t=g3;})?
-            |   f4:FLOAT_SUFFIX {t=f4;}
-            )
-            {
-                String txt = (t == null ? "" : t.getText().toUpperCase());
-                if (txt.indexOf('F') >= 0) {
-                    _ttype = NUM_FLOAT;
-                } else if (txt.indexOf('G') >= 0) {
-                    _ttype = NUM_BIG_DECIMAL;
-                } else {
-                    _ttype = NUM_DOUBLE; // assume double
-                }
-            }
-        )?
-    ;
-
-// JDK 1.5 token for annotations and their declarations
-// also a groovy operator for actual field access e.g. 'telson.@age'
-AT
-options {
-    paraphrase="'@'";
-}
-    :   '@'
-    ;
-
-// a couple protected methods to assist in matching floating point numbers
-protected
-EXPONENT
-options {
-    paraphrase="an exponent";
-}
-    :   ('e'|'E') ('+'|'-')? ('0'..'9'|'_')* ('0'..'9')
-    ;
-
-protected
-FLOAT_SUFFIX
-options {
-    paraphrase="a float or double suffix";
-}
-    :   'f'|'F'|'d'|'D'
-    ;
-
-protected
-BIG_SUFFIX
-options {
-    paraphrase="a big decimal suffix";
-}
-    :   'g'|'G'
-    ;
-
-// Note: Please don't use physical tabs.  Logical tabs for indent are width 4.
-// Here's a little hint for you, Emacs:
-// Local Variables:
-// tab-width: 4
-// mode: antlr-mode
-// indent-tabs-mode: nil
-// End:
diff --git a/src/main/antlr2/org/codehaus/groovy/antlr/java/java.g b/src/main/antlr2/org/codehaus/groovy/antlr/java/java.g
deleted file mode 100644
index cfa2607..0000000
--- a/src/main/antlr2/org/codehaus/groovy/antlr/java/java.g
+++ /dev/null
@@ -1,2047 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-// Note: Please don't use physical tabs.  Logical tabs for indent are width 4.
-header {
-package org.codehaus.groovy.antlr.java;
-import org.codehaus.groovy.antlr.*;
-import org.codehaus.groovy.antlr.parser.*;
-import java.util.*;
-import java.io.InputStream;
-import java.io.Reader;
-import antlr.InputBuffer;
-import antlr.LexerSharedInputState;
-}
- 
-/** Java 1.5 Recognizer
- *
- * Run 'java Main [-showtree] directory-full-of-java-files'
- *
- * [The -showtree option pops up a Swing frame that shows
- *  the AST constructed from the parser.]
- *
- * Run 'java Main <directory full of java files>'
- *
- * Contributing authors:
- *      Jeremy Rayner       groovy@ross-rayner.com
- *		John Mitchell		johnm@non.net
- *		Terence Parr		parrt@magelang.com
- *		John Lilley		jlilley@empathy.com
- *		Scott Stanchfield	thetick@magelang.com
- *		Markus Mohnen		mohnen@informatik.rwth-aachen.de
- *		Peter Williams		pete.williams@sun.com
- *		Allan Jacobs		Allan.Jacobs@eng.sun.com
- *		Steve Messick		messick@redhills.com
- *		John Pybus		john@pybus.org
- *
- * Version 1.00 December 9, 1997 -- initial release
- * Version 1.01 December 10, 1997
- *		fixed bug in octal def (0..7 not 0..8)
- * Version 1.10 August 1998 (parrt)
- *		added tree construction
- *		fixed definition of WS,comments for mac,pc,unix newlines
- *		added unary plus
- * Version 1.11 (Nov 20, 1998)
- *		Added "shutup" option to turn off last ambig warning.
- *		Fixed inner class def to allow named class defs as statements
- *		synchronized requires compound not simple statement
- *		add [] after builtInType DOT class in primaryExpression
- *		"const" is reserved but not valid..removed from modifiers
- * Version 1.12 (Feb 2, 1999)
- *		Changed LITERAL_xxx to xxx in tree grammar.
- *		Updated java.g to use tokens {...} now for 2.6.0 (new feature).
- *
- * Version 1.13 (Apr 23, 1999)
- *		Didn't have (stat)? for else clause in tree parser.
- *		Didn't gen ASTs for interface extends.  Updated tree parser too.
- *		Updated to 2.6.0.
- * Version 1.14 (Jun 20, 1999)
- *		Allowed final/abstract on local classes.
- *		Removed local interfaces from methods
- *		Put instanceof precedence where it belongs...in relationalExpr
- *			It also had expr not type as arg; fixed it.
- *		Missing ! on SEMI in classBlock
- *		fixed: (expr) + "string" was parsed incorrectly (+ as unary plus).
- *		fixed: didn't like Object[].class in parser or tree parser
- * Version 1.15 (Jun 26, 1999)
- *		Screwed up rule with instanceof in it. :(  Fixed.
- *		Tree parser didn't like (expr).something; fixed.
- *		Allowed multiple inheritance in tree grammar. oops.
- * Version 1.16 (August 22, 1999)
- *		Extending an interface built a wacky tree: had extra EXTENDS.
- *		Tree grammar didn't allow multiple superinterfaces.
- *		Tree grammar didn't allow empty var initializer: {}
- * Version 1.17 (October 12, 1999)
- *		ESC lexer rule allowed 399 max not 377 max.
- *		java.tree.g didn't handle the expression of synchronized
- *		statements.
- * Version 1.18 (August 12, 2001)
- *	  	Terence updated to Java 2 Version 1.3 by
- *		observing/combining work of Allan Jacobs and Steve
- *		Messick.  Handles 1.3 src.  Summary:
- *		o  primary didn't include boolean.class kind of thing
- *	  	o  constructor calls parsed explicitly now:
- * 		   see explicitConstructorInvocation
- *		o  add strictfp modifier
- *	  	o  missing objBlock after new expression in tree grammar
- *		o  merged local class definition alternatives, moved after declaration
- *		o  fixed problem with ClassName.super.field
- *	  	o  reordered some alternatives to make things more efficient
- *		o  long and double constants were not differentiated from int/float
- *		o  whitespace rule was inefficient: matched only one char
- *		o  add an examples directory with some nasty 1.3 cases
- *		o  made Main.java use buffered IO and a Reader for Unicode support
- *		o  supports UNICODE?
- *		   Using Unicode charVocabulay makes code file big, but only
- *		   in the bitsets at the end. I need to make ANTLR generate
- *		   unicode bitsets more efficiently.
- * Version 1.19 (April 25, 2002)
- *		Terence added in nice fixes by John Pybus concerning floating
- *		constants and problems with super() calls.  John did a nice
- *		reorg of the primary/postfix expression stuff to read better
- *		and makes f.g.super() parse properly (it was METHOD_CALL not
- *		a SUPER_CTOR_CALL).  Also:
- *
- *		o  "finally" clause was a root...made it a child of "try"
- *		o  Added stuff for asserts too for Java 1.4, but *commented out*
- *		   as it is not backward compatible.
- *
- * Version 1.20 (October 27, 2002)
- *
- *	  Terence ended up reorging John Pybus' stuff to
- *	  remove some nondeterminisms and some syntactic predicates.
- *	  Note that the grammar is stricter now; e.g., this(...) must
- *	be the first statement.
- *
- *	  Ternary ?: operator wasn't working as array name:
- *		  (isBig ? bigDigits : digits)[i];
- *
- *	  Checked parser/tree parser on source for
- *		  Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4,
- *		and the 110k-line jGuru server source.
- *
- * Version 1.21 (October 17, 2003)
- *  Fixed lots of problems including:
- *  Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g
- *  He found a problem/fix with floating point that start with 0
- *  Ray also fixed problem that (int.class) was not recognized.
- *  Thorsten van Ellen noticed that \n are allowed incorrectly in strings.
- *  TJP fixed CHAR_LITERAL analogously.
- *
- * Version 1.21.2 (March, 2003)
- *	  Changes by Matt Quail to support generics (as per JDK1.5/JSR14)
- *	  Notes:
- *	  o We only allow the "extends" keyword and not the "implements"
- *		keyword, since that's what JSR14 seems to imply.
- *	  o Thanks to Monty Zukowski for his help on the antlr-interest
- *		mail list.
- *	  o Thanks to Alan Eliasen for testing the grammar over his
- *		Fink source base
- *
- * Version 1.22 (July, 2004)
- *	  Changes by Michael Studman to support Java 1.5 language extensions
- *	  Notes:
- *	  o Added support for annotations types
- *	  o Finished off Matt Quail's generics enhancements to support bound type arguments
- *	  o Added support for new for statement syntax
- *	  o Added support for static import syntax
- *	  o Added support for enum types
- *	  o Tested against JDK 1.5 source base and source base of jdigraph project
- *	  o Thanks to Matt Quail for doing the hard part by doing most of the generics work
- *
- * Version 1.22.1 (July 28, 2004)
- *	  Bug/omission fixes for Java 1.5 language support
- *	  o Fixed tree structure bug with classOrInterface - thanks to Pieter Vangorpto for
- *		spotting this
- *	  o Fixed bug where incorrect handling of SR and BSR tokens would cause type
- *		parameters to be recognised as type arguments.
- *	  o Enabled type parameters on constructors, annotations on enum constants
- *		and package definitions
- *	  o Fixed problems when parsing if ((char.class.equals(c))) {} - solution by Matt Quail at Cenqua
- *
- * Version 1.22.2 (July 28, 2004)
- *	  Slight refactoring of Java 1.5 language support
- *	  o Refactored for/"foreach" productions so that original literal "for" literal
- *	    is still used but the for sub-clauses vary by token type
- *	  o Fixed bug where type parameter was not included in generic constructor's branch of AST
- *
- * Version 1.22.3 (August 26, 2004)
- *	  Bug fixes as identified by Michael Stahl; clean up of tabs/spaces
- *        and other refactorings
- *	  o Fixed typeParameters omission in identPrimary and newStatement
- *	  o Replaced GT reconciliation code with simple semantic predicate
- *	  o Adapted enum/assert keyword checking support from Michael Stahl's java15 grammar
- *	  o Refactored typeDefinition production and field productions to reduce duplication
- *
- * Version 1.22.4 (October 21, 2004)
- *    Small bux fixes
- *    o Added typeArguments to explicitConstructorInvocation, e.g. new <String>MyParameterised()
- *    o Added typeArguments to postfixExpression productions for anonymous inner class super
- *      constructor invocation, e.g. new Outer().<String>super()
- *    o Fixed bug in array declarations identified by Geoff Roy
- *
- * Version 1.22.4.j.1
- *	  Changes by Jeremy Rayner to support java2groovy tool
- *    o I have taken java.g for Java1.5 from Michael Studman (1.22.4)
- *      and have made some changes to enable use by java2groovy tool (Jan 2007)
- *
- * Based on an original grammar released in the PUBLIC DOMAIN
- */
-
-class JavaRecognizer extends Parser;
-options {
-	k = 2;							// two token lookahead
-	exportVocab=Java;				// Call its vocabulary "Java"
-	codeGenMakeSwitchThreshold = 2;	// Some optimizations
-	codeGenBitsetTestThreshold = 3;
-	defaultErrorHandler = false;	// Don't generate parser error handlers
-	buildAST = true;
-}
-
-tokens {
-	BLOCK; MODIFIERS; OBJBLOCK; SLIST; METHOD_DEF; VARIABLE_DEF;
-	INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF;
-	PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE;
-	PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP;
-	POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT;
-	IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION;
-	FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract";
-	STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; VARIABLE_PARAMETER_DEF;
-	STATIC_IMPORT; ENUM_DEF; ENUM_CONSTANT_DEF; FOR_EACH_CLAUSE; ANNOTATION_DEF; ANNOTATIONS;
-	ANNOTATION; ANNOTATION_MEMBER_VALUE_PAIR; ANNOTATION_FIELD_DEF; ANNOTATION_ARRAY_INIT;
-	TYPE_ARGUMENTS; TYPE_ARGUMENT; TYPE_PARAMETERS; TYPE_PARAMETER; WILDCARD_TYPE;
-	TYPE_UPPER_BOUNDS; TYPE_LOWER_BOUNDS;
-}
-
-{
-    /** This factory is the correct way to wire together a Groovy parser and lexer. */
-    public static JavaRecognizer make(JavaLexer lexer) {
-        JavaRecognizer parser = new JavaRecognizer(lexer.plumb());
-        // TODO: set up a common error-handling control block, to avoid excessive tangle between these guys
-        parser.lexer = lexer;
-        lexer.parser = parser;
-        parser.setASTNodeClass("org.codehaus.groovy.antlr.GroovySourceAST");
-        return parser;
-    }
-    // Create a scanner that reads from the input stream passed to us...
-    public static JavaRecognizer make(InputStream in) { return make(new JavaLexer(in)); }
-    public static JavaRecognizer make(Reader in) { return make(new JavaLexer(in)); }
-    public static JavaRecognizer make(InputBuffer in) { return make(new JavaLexer(in)); }
-    public static JavaRecognizer make(LexerSharedInputState in) { return make(new JavaLexer(in)); }
-    
-    private static GroovySourceAST dummyVariableToforceClassLoaderToFindASTClass = new GroovySourceAST();
-    
-    JavaLexer lexer;
-    public JavaLexer getLexer() { return lexer; }
-    public void setFilename(String f) { super.setFilename(f); lexer.setFilename(f); }
-    private SourceBuffer sourceBuffer;
-    public void setSourceBuffer(SourceBuffer sourceBuffer) {
-        this.sourceBuffer = sourceBuffer;
-    }
-
-    /** Create an AST node with the token type and text passed in, but
-     *  with the same background information as another supplied Token (e.g. line numbers)
-     * to be used in place of antlr tree construction syntax,
-     * i.e. #[TOKEN,"text"]  becomes  create(TOKEN,"text",anotherToken)
-     *
-     * todo - change antlr.ASTFactory to do this instead...
-     */
-    public AST create(int type, String txt, Token first, Token last) {
-        AST t = astFactory.create(type,txt);
-        if ( t != null && first != null) {
-            // first copy details from first token
-            t.initialize(first);
-            // then ensure that type and txt are specific to this new node
-            t.initialize(type,txt);
-        }
-
-        if ((t instanceof GroovySourceAST) && last != null) {
-            GroovySourceAST node = (GroovySourceAST)t;
-            node.setLast(last);
-            // This is a good point to call node.setSnippet(),
-            // but it bulks up the AST too much for production code.
-        }
-        return t;
-    }
-
-    
-    /**
-	 * Counts the number of LT seen in the typeArguments production.
-	 * It is used in semantic predicates to ensure we have seen
-	 * enough closing '>' characters; which actually may have been
-	 * either GT, SR or BSR tokens.
-	 */
-	private int ltCounter = 0;
-}
-
-// Compilation Unit: In Java, this is a single file. This is the start
-// rule for this parser
-compilationUnit
-	:	// A compilation unit starts with an optional package definition
-		(	(annotations "package")=> packageDefinition
-		|	/* nothing */
-		)
-
-		// Next we have a series of zero or more import statements
-		( importDefinition )*
-
-		// Wrapping things up with any number of class or interface
-		// definitions
-		( typeDefinition )*
-
-		EOF!
-	;
-
-
-// Package statement: optional annotations followed by "package" then the package identifier.
-packageDefinition
-	options {defaultErrorHandler = true;} // let ANTLR handle errors
-	:	annotations p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI!
-	;
-
-
-// Import statement: import followed by a package or class name
-importDefinition
-	options {defaultErrorHandler = true;}
-	{ boolean isStatic = false; }
-	:	i:"import"^ {#i.setType(IMPORT);} ( "static"! {#i.setType(STATIC_IMPORT);} )? identifierStar SEMI!
-	;
-
-// A type definition is either a class, interface, enum or annotation with possible additional semis.
-typeDefinition
-	options {defaultErrorHandler = true;}
-	:	m:modifiers!
-		typeDefinitionInternal[#m]
-	|	SEMI!
-	;
-
-// Protected type definitions production for reuse in other productions
-protected typeDefinitionInternal[AST mods]
-	:	classDefinition[#mods]		// inner class
-	|	interfaceDefinition[#mods]	// inner interface
-	|	enumDefinition[#mods]		// inner enum
-	|	annotationDefinition[#mods]	// inner annotation
-	;
-
-// A declaration is the creation of a reference or primitive-type variable
-// Create a separate Type/Var tree for each var in the var list.
-declaration!
-	:	m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t]
-		{#declaration = #v;}
-	;
-
-// A type specification is a type name with possible brackets afterwards
-// (which would make it an array type).
-typeSpec[boolean addImagNode]
-	:	classTypeSpec[addImagNode]
-	|	builtInTypeSpec[addImagNode]
-	;
-
-// A class type specification is a class type with either:
-// - possible brackets afterwards
-//   (which would make it an array type).
-// - generic type arguments after
-classTypeSpec[boolean addImagNode]  {Token first = LT(1);}
-	:	classOrInterfaceType[false]
-		(options{greedy=true;}: // match as many as possible
-			lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!
-		)*
-		{
-			if ( addImagNode ) {
-				#classTypeSpec = #(create(TYPE,"TYPE",first,LT(1)), #classTypeSpec);
-			}
-		}
-	;
-
-// A non-built in type name, with possible type parameters
-classOrInterfaceType[boolean addImagNode]  {Token first = LT(1);}
-	:	IDENT^ (typeArgumentsOrDiamond)?
-		(options{greedy=true;}: // match as many as possible
-			DOT^
-			IDENT (typeArgumentsOrDiamond)?
-		)*
-		{
-			if ( addImagNode ) {
-				#classOrInterfaceType = #(create(TYPE,"TYPE",first,LT(1)), #classOrInterfaceType);
-			}
-		}
-	;
-
-// A specialised form of typeSpec where built in types must be arrays
-typeArgumentSpec
-	:	classTypeSpec[true]
-	|	builtInTypeArraySpec[true]
-	;
-
-// A generic type argument is a class type, a possibly bounded wildcard type or a built-in type array
-typeArgument  {Token first = LT(1);}
-	:	(	typeArgumentSpec
-		|	wildcardType
-		)
-		{#typeArgument = #(create(TYPE_ARGUMENT,"TYPE_ARGUMENT",first,LT(1)), #typeArgument);}
-	;
-
-// Wildcard type indicating all types (with possible constraint)
-wildcardType
-	:	q:QUESTION^ {#q.setType(WILDCARD_TYPE);}
-		(("extends" | "super")=> typeArgumentBounds)?
-	;
-
-typeArgumentsOrDiamond
-    :   LT! GT!
-    |   typeArguments
-    ;
-
-// Type arguments to a class or interface type
-typeArguments
-{int currentLtLevel = 0;  Token first = LT(1);}
-	:
-		{currentLtLevel = ltCounter;}
-		LT! {ltCounter++;}
-		typeArgument
-		(options{greedy=true;}: // match as many as possible
-			{inputState.guessing !=0 || ltCounter == currentLtLevel + 1}?
-			COMMA! typeArgument
-		)*
-
-		(	// turn warning off since Antlr generates the right code,
-			// plus we have our semantic predicate below
-			options{generateAmbigWarnings=false;}:
-			typeArgumentsOrParametersEnd
-		)?
-
-		// make sure we have gobbled up enough '>' characters
-		// if we are at the "top level" of nested typeArgument productions
-		{(currentLtLevel != 0) || ltCounter == currentLtLevel}?
-
-		{#typeArguments = #(create(TYPE_ARGUMENTS,"TYPE_ARGUMENTS",first,LT(1)), #typeArguments);}
-	;
-
-// this gobbles up *some* amount of '>' characters, and counts how many
-// it gobbled.
-protected typeArgumentsOrParametersEnd
-	:	GT! {ltCounter-=1;}
-	|	SR! {ltCounter-=2;}
-	|	BSR! {ltCounter-=3;}
-	;
-
-// Restriction on wildcard types based on super class or derrived class
-typeArgumentBounds
-	{boolean isUpperBounds = false;  Token first = LT(1);}
-	:
-		( "extends"! {isUpperBounds=true;} | "super"! ) classOrInterfaceType[false]
-		{
-			if (isUpperBounds)
-			{
-				#typeArgumentBounds = #(create(TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS",first,LT(1)), #typeArgumentBounds);
-			}
-			else
-			{
-				#typeArgumentBounds = #(create(TYPE_LOWER_BOUNDS,"TYPE_LOWER_BOUNDS",first,LT(1)), #typeArgumentBounds);
-			}
-		}
-	;
-
-// A builtin type array specification is a builtin type with brackets afterwards
-builtInTypeArraySpec[boolean addImagNode]  {Token first = LT(1);}
-	:	builtInType
-		(options{greedy=true;}: // match as many as possible
-			lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!
-		)+
-
-		{
-			if ( addImagNode ) {
-				#builtInTypeArraySpec = #(create(TYPE,"TYPE",first,LT(1)), #builtInTypeArraySpec);
-			}
-		}
-	;
-
-// A builtin type specification is a builtin type with possible brackets
-// afterwards (which would make it an array type).
-builtInTypeSpec[boolean addImagNode]  {Token first = LT(1);}
-	:	builtInType
-		(options{greedy=true;}: // match as many as possible
-			lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!
-		)*
-		{
-			if ( addImagNode ) {
-				#builtInTypeSpec = #(create(TYPE,"TYPE",first,LT(1)), #builtInTypeSpec);
-			}
-		}
-	;
-
-// A type name. which is either a (possibly qualified and parameterized)
-// class name or a primitive (builtin) type
-type
-	:	classOrInterfaceType[false]
-	|	builtInType
-	;
-
-// The primitive types.
-builtInType
-	:	"void"
-	|	"boolean"
-	|	"byte"
-	|	"char"
-	|	"short"
-	|	"int"
-	|	"float"
-	|	"long"
-	|	"double"
-	;
-
-// A (possibly-qualified) java identifier. We start with the first IDENT
-// and expand its name by adding dots and following IDENTS
-identifier
-	:	IDENT ( DOT^ IDENT )*
-	;
-
-identifierStar
-	:	IDENT
-		( DOT^ IDENT )*
-		( DOT^ STAR )?
-	;
-
-// A list of zero or more modifiers. We could have used (modifier)* in
-// place of a call to modifiers, but I thought it was a good idea to keep
-// this rule separate so they can easily be collected in a Vector if
-// someone so desires
-modifiers {Token first = LT(1);}
-	:
-		(
-			//hush warnings since the semantic check for "@interface" solves the non-determinism
-			options{generateAmbigWarnings=false;}:
-
-			modifier
-			|
-			//Semantic check that we aren't matching @interface as this is not an annotation
-			//A nicer way to do this would be nice
-			{LA(1)==AT && !LT(2).getText().equals("interface")}? annotation
-		)*
-
-		{#modifiers = #(create(MODIFIERS, "MODIFIERS",first,LT(1)), #modifiers);}
-	;
-
-// modifiers for Java classes, interfaces, class/instance vars and methods
-modifier
-	:	"private"
-	|	"public"
-	|	"protected"
-	|	"static"
-	|	"transient"
-	|	"final"
-	|	"abstract"
-	|	"native"
-	|	"threadsafe"
-	|	"synchronized"
-	|	"volatile"
-	|	"strictfp"
-	;
-
-annotation!  {Token first = LT(1);}
-	:	AT! i:identifier ( LPAREN! ( args:annotationArguments )? RPAREN! )?
-		{#annotation = #(create(ANNOTATION,"ANNOTATION",first,LT(1)), i, args);}
-	;
-
-annotations  {Token first = LT(1);}
-    :   (annotation)*
-		{#annotations = #([ANNOTATIONS, "ANNOTATIONS"], #annotations);}
-    ;
-
-annotationArguments
-	:	annotationMemberValueInitializer | annotationMemberValuePairs
-	;
-
-annotationMemberValuePairs
-	:	annotationMemberValuePair ( COMMA! annotationMemberValuePair )*
-	;
-
-annotationMemberValuePair!  {Token first = LT(1);}
-	:	i:IDENT ASSIGN! v:annotationMemberValueInitializer
-		{#annotationMemberValuePair = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",first,LT(1)), i, v);}
-	;
-
-annotationMemberValueInitializer
-	:
-		conditionalExpression | annotation | annotationMemberArrayInitializer
-	;
-
-// This is an initializer used to set up an annotation member array.
-annotationMemberArrayInitializer
-	:	lc:LCURLY^ {#lc.setType(ANNOTATION_ARRAY_INIT);}
-			(	annotationMemberArrayValueInitializer
-				(
-					// CONFLICT: does a COMMA after an initializer start a new
-					// initializer or start the option ',' at end?
-					// ANTLR generates proper code by matching
-					// the comma as soon as possible.
-					options {
-						warnWhenFollowAmbig = false;
-					}
-				:
-					COMMA! annotationMemberArrayValueInitializer
-				)*
-				(COMMA!)?
-			)?
-		RCURLY!
-	;
-
-// The two things that can initialize an annotation array element are a conditional expression
-// and an annotation (nested annotation array initialisers are not valid)
-annotationMemberArrayValueInitializer
-	:	conditionalExpression
-	|	annotation
-	;
-
-superClassClause!  {Token first = LT(1);}
-	:	( "extends" c:classOrInterfaceType[false] )?
-		{#superClassClause = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)),c);}
-	;
-
-// Definition of a Java class
-classDefinition![AST modifiers] {Token first = LT(1);}
-	:	"class" IDENT
-		// it _might_ have type parameters
-		(tp:typeParameters)?
-		// it _might_ have a superclass...
-		sc:superClassClause
-		// it might implement some interfaces...
-		ic:implementsClause
-		// now parse the body of the class
-		cb:classBlock
-		{#classDefinition = #(create(CLASS_DEF,"CLASS_DEF",first,LT(1)),
-								modifiers,IDENT,tp,sc,ic,cb);}
-	;
-
-// Definition of a Java Interface
-interfaceDefinition![AST modifiers]  {Token first = LT(1);}
-	:	"interface" IDENT
-		// it _might_ have type parameters
-		(tp:typeParameters)?
-		// it might extend some other interfaces
-		ie:interfaceExtends
-		// now parse the body of the interface (looks like a class...)
-		ib:interfaceBlock
-		{#interfaceDefinition = #(create(INTERFACE_DEF,"INTERFACE_DEF",first,LT(1)),
-									modifiers,IDENT,tp,ie,ib);}
-	;
-
-enumDefinition![AST modifiers]  {Token first = LT(1);}
-	:	"enum" IDENT
-		// it might implement some interfaces...
-		ic:implementsClause
-		// now parse the body of the enum
-		eb:enumBlock
-		{#enumDefinition = #(create(ENUM_DEF,"ENUM_DEF",first,LT(1)),
-								modifiers,IDENT,ic,eb);}
-	;
-
-annotationDefinition![AST modifiers]  {Token first = LT(1);}
-	:	AT "interface" IDENT
-		// now parse the body of the annotation
-		ab:annotationBlock
-		{#annotationDefinition = #(create(ANNOTATION_DEF,"ANNOTATION_DEF",first,LT(1)),
-									modifiers,IDENT,ab);}
-	;
-
-typeParameters
-{int currentLtLevel = 0; Token first = LT(1);}
-	:
-		{currentLtLevel = ltCounter;}
-		LT! {ltCounter++;}
-		typeParameter (COMMA! typeParameter)*
-		(typeArgumentsOrParametersEnd)?
-
-		// make sure we have gobbled up enough '>' characters
-		// if we are at the "top level" of nested typeArgument productions
-		{(currentLtLevel != 0) || ltCounter == currentLtLevel}?
-
-		{#typeParameters = #(create(TYPE_PARAMETERS,"TYPE_PARAMETERS",first,LT(1)), #typeParameters);}
-	;
-
-typeParameter   {Token first = LT(1);}
-	:
-		// I'm pretty sure Antlr generates the right thing here:
-		(id:IDENT) ( options{generateAmbigWarnings=false;}: typeParameterBounds )?
-		{#typeParameter = #(create(TYPE_PARAMETER,"TYPE_PARAMETER",first,LT(1)), #typeParameter);}
-	;
-
-typeParameterBounds  {Token first = LT(1);}
-	:
-		"extends"! classOrInterfaceType[false]
-		(BAND! classOrInterfaceType[false])*
-		{#typeParameterBounds = #(create(TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS",first,LT(1)), #typeParameterBounds);}
-	;
-
-// This is the body of a class. You can have classFields and extra semicolons.
-classBlock
-	:	LCURLY!
-			( classField | SEMI! )*
-		RCURLY!
-		{#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);}
-	;
-
-// This is the body of an interface. You can have interfaceField and extra semicolons.
-interfaceBlock
-	:	LCURLY!
-			( interfaceField | SEMI! )*
-		RCURLY!
-		{#interfaceBlock = #([OBJBLOCK, "OBJBLOCK"], #interfaceBlock);}
-	;
-	
-// This is the body of an annotation. You can have annotation fields and extra semicolons,
-// That's about it (until you see what an annoation field is...)
-annotationBlock
-	:	LCURLY!
-		( annotationField | SEMI! )*
-		RCURLY!
-		{#annotationBlock = #([OBJBLOCK, "OBJBLOCK"], #annotationBlock);}
-	;
-
-// This is the body of an enum. You can have zero or more enum constants
-// followed by any number of fields like a regular class
-enumBlock
-	:	LCURLY!
-			( enumConstant ( options{greedy=true;}: COMMA! enumConstant )* ( COMMA! )? )?
-			( SEMI! ( classField | SEMI! )* )?
-		RCURLY!
-		{#enumBlock = #([OBJBLOCK, "OBJBLOCK"], #enumBlock);}
-	;
-
-// An annotation field
-annotationField!  {Token first = LT(1);}
-	:	mods:modifiers
-		(	td:typeDefinitionInternal[#mods]
-			{#annotationField = #td;}
-		|	t:typeSpec[false]		// annotation field
-			(	i:IDENT				// the name of the field
-
-				LPAREN! RPAREN!
-
-				rt:declaratorBrackets[#t]
-
-				( "default" amvi:annotationMemberValueInitializer )?
-
-				SEMI
-
-				{#annotationField =
-					#(create(ANNOTATION_FIELD_DEF,"ANNOTATION_FIELD_DEF",first,LT(1)),
-						 mods,
-						 #(create(TYPE,"TYPE",first,LT(1)),rt),
-						 i,amvi
-						 );}
-			|	v:variableDefinitions[#mods,#t] SEMI	// variable
-				{#annotationField = #v;}
-			)
-		)
-	;
-
-//An enum constant may have optional parameters and may have a
-//a class body
-enumConstant!
-	:	an:annotations
-		i:IDENT
-		(	LPAREN!
-			a:argList
-			RPAREN!
-		)?
-		( b:enumConstantBlock )?
-		{#enumConstant = #([ENUM_CONSTANT_DEF, "ENUM_CONSTANT_DEF"], an, i, a, b);}
-	;
-
-//The class-like body of an enum constant
-enumConstantBlock
-	:	LCURLY!
-		( enumConstantField | SEMI! )*
-		RCURLY!
-		{#enumConstantBlock = #([OBJBLOCK, "OBJBLOCK"], #enumConstantBlock);}
-	;
-
-//An enum constant field is just like a class field but without
-//the possibility of a constructor definition or a static initializer
-enumConstantField! {Token first = LT(1);}
-	:	mods:modifiers
-		(	td:typeDefinitionInternal[#mods]
-			{#enumConstantField = #td;}
-
-		|	// A generic method has the typeParameters before the return type.
-			// This is not allowed for variable definitions, but this production
-			// allows it, a semantic check could be used if you wanted.
-			(tp:typeParameters)? t:typeSpec[false]		// method or variable declaration(s)
-			(	IDENT									// the name of the method
-
-				// parse the formal parameter declarations.
-				LPAREN! param:parameterDeclarationList RPAREN!
-
-				rt:declaratorBrackets[#t]
-
-				// get the list of exceptions that this method is
-				// declared to throw
-				(tc:throwsClause)?
-
-				( s2:compoundStatement | SEMI )
-				{#enumConstantField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)),
-							 mods,
-							 tp,
-							 #(create(TYPE,"TYPE",first,LT(1)),rt),
-							 IDENT,
-							 param,
-							 tc,
-							 s2);}
-			|	v:variableDefinitions[#mods,#t] SEMI
-				{#enumConstantField = #v;}
-			)
-		)
-
-	// "{ ... }" instance initializer
-	|	s4:compoundStatement
-		{#enumConstantField = #(create(INSTANCE_INIT,"INSTANCE_INIT",first,LT(1)), s4);}
-	;
-
-// An interface can extend several other interfaces...
-interfaceExtends  {Token first = LT(1);}
-	:	(
-		e:"extends"!
-		classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )*
-		)?
-		{#interfaceExtends = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)),
-								#interfaceExtends);}
-	;
-
-// A class can implement several interfaces...
-implementsClause  {Token first = LT(1);}
-	:	(
-			i:"implements"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )*
-		)?
-		{#implementsClause = #(create(IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE",first,LT(1)),
-								 #implementsClause);}
-	;
-
-// Now the various things that can be defined inside a class
-classField!   {Token first = LT(1);}
-	:	// method, constructor, or variable declaration
-		mods:modifiers
-		(	td:typeDefinitionInternal[#mods]
-			{#classField = #td;}
-
-		|	(tp:typeParameters)?
-			(
-				h:ctorHead s:constructorBody // constructor
-				// just treat CTOR_DEF like METHOD_DEF for java2groovy
-				{#classField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)), mods, tp, h, s);}
-
-				|	// A generic method/ctor has the typeParameters before the return type.
-					// This is not allowed for variable definitions, but this production
-					// allows it, a semantic check could be used if you wanted.
-					t:typeSpec[false]		// method or variable declaration(s)
-					(	IDENT				// the name of the method
-
-						// parse the formal parameter declarations.
-						LPAREN! param:parameterDeclarationList RPAREN!
-
-						rt:declaratorBrackets[#t]
-
-						// get the list of exceptions that this method is
-						// declared to throw
-						(tc:throwsClause)?
-
-						( s2:compoundStatement | SEMI )
-						{#classField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)),
-									 mods,
-									 tp,
-									 #(create(TYPE,"TYPE",first,LT(1)),rt),
-									 IDENT,
-									 param,
-									 tc,
-									 s2);}
-					|	v:variableDefinitions[#mods,#t] SEMI
-						{#classField = #v;}
-					)
-			)
-		)
-
-	// "static { ... }" class initializer
-	|	"static" s3:compoundStatement
-		{#classField = #(create(STATIC_INIT,"STATIC_INIT",first,LT(1)), s3);}
-
-	// "{ ... }" instance initializer
-	|	s4:compoundStatement
-		{#classField = #(create(INSTANCE_INIT,"INSTANCE_INIT",first,LT(1)), s4);}
-	;
-
-// Now the various things that can be defined inside a interface
-interfaceField!    {Token first = LT(1);}
-	:	// method, constructor, or variable declaration
-		mods:modifiers
-		(	td:typeDefinitionInternal[#mods]
-			{#interfaceField = #td;}
-
-		|	(tp:typeParameters)?
-			// A generic method has the typeParameters before the return type.
-			// This is not allowed for variable definitions, but this production
-			// allows it, a semantic check could be used if you want a more strict
-			// grammar.
-			("default"!)?          // just to keep groovydoc parsing happy
-			t:typeSpec[false]		// method or variable declaration(s)
-			(	IDENT				// the name of the method
-
-				// parse the formal parameter declarations.
-				LPAREN! param:parameterDeclarationList RPAREN!
-
-				rt:declaratorBrackets[#t]
-
-				// get the list of exceptions that this method is
-				// declared to throw
-				(tc:throwsClause)?
-
-				SEMI
-				
-				{#interfaceField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)),
-							 mods,
-							 tp,
-							 #(create(TYPE,"TYPE",first,LT(1)),rt),
-							 IDENT,
-							 param,
-							 tc);}
-			|	v:variableDefinitions[#mods,#t] SEMI
-				{#interfaceField = #v;}
-			)
-		)
-	;
-
-constructorBody
-	:	lc:LCURLY^ {#lc.setType(SLIST);}
-			( options { greedy=true; } : explicitConstructorInvocation)?
-			(statement)*
-		RCURLY!
-	;
-
-/** Catch obvious constructor calls, but not the expr.super(...) calls */
-explicitConstructorInvocation
-	:	(typeArguments)?
-		(	"this"! lp1:LPAREN^ argList RPAREN! SEMI!
-			{#lp1.setType(CTOR_CALL);}
-		|	"super"! lp2:LPAREN^ argList RPAREN! SEMI!
-			{#lp2.setType(SUPER_CTOR_CALL);}
-		)
-	;
-
-variableDefinitions[AST mods, AST t]
-	:	variableDeclarator[getASTFactory().dupTree(mods),
-							getASTFactory().dupTree(t)]
-		(	COMMA!
-			variableDeclarator[getASTFactory().dupTree(mods),
-							getASTFactory().dupTree(t)]
-		)*
-	;
-
-/** Declaration of a variable. This can be a class/instance variable,
- *  or a local variable in a method
- *  It can also include possible initialization.
- */
-variableDeclarator![AST mods, AST t] { Token first = LT(1);}
-	:	id:IDENT d:declaratorBrackets[t] v:varInitializer
-		{#variableDeclarator = #(create(VARIABLE_DEF,"VARIABLE_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)),d), id, v);}
-	;
-
-declaratorBrackets[AST typ]
-	:	{#declaratorBrackets=typ;}
-		(lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
-	;
-
-varInitializer
-	:	( ASSIGN^ initializer )?
-	;
-
-// This is an initializer used to set up an array.
-arrayInitializer
-	:	lc:LCURLY^ {#lc.setType(ARRAY_INIT);}
-			(	initializer
-				(
-					// CONFLICT: does a COMMA after an initializer start a new
-					// initializer or start the option ',' at end?
-					// ANTLR generates proper code by matching
-					// the comma as soon as possible.
-					options {
-						warnWhenFollowAmbig = false;
-					}
-				:
-					COMMA! initializer
-				)*
-				(COMMA!)?
-			)?
-		RCURLY!
-	;
-
-// The two "things" that can initialize an array element are an expression
-// and another (nested) array initializer.
-initializer
-	:	expression
-	|	arrayInitializer
-	;
-
-// This is the header of a method. It includes the name and parameters
-// for the method.
-// This also watches for a list of exception classes in a "throws" clause.
-ctorHead
-	:	IDENT // the name of the method
-
-		// parse the formal parameter declarations.
-		LPAREN! parameterDeclarationList RPAREN!
-
-		// get the list of exceptions that this method is declared to throw
-		(throwsClause)?
-	;
-
-// This is a list of exception classes that the method is declared to throw
-throwsClause
-	:	"throws"^ identifier ( COMMA! identifier )*
-	;
-
-// A list of formal parameters
-//	 Zero or more parameters
-//	 If a parameter is variable length (e.g. String... myArg) it is the right-most parameter
-parameterDeclarationList {Token first = LT(1);}
-	// The semantic check in ( .... )* block is flagged as superfluous, and seems superfluous but
-	// is the only way I could make this work. If my understanding is correct this is a known bug
-	:	(	( parameterDeclaration )=> parameterDeclaration
-			( options {warnWhenFollowAmbig=false;} : ( COMMA! parameterDeclaration ) => COMMA! parameterDeclaration )*
-			( COMMA! variableLengthParameterDeclaration )?
-		|
-			variableLengthParameterDeclaration
-		)?
-		{#parameterDeclarationList = #(create(PARAMETERS,"PARAMETERS",first,LT(1)),
-                						#parameterDeclarationList);}
-	;
-
-// A formal parameter.
-parameterDeclaration! {Token first = LT(1);}
-	:	pm:parameterModifier t:typeSpec[false] id:IDENT
-		pd:declaratorBrackets[#t]
-		{#parameterDeclaration = #(create(PARAMETER_DEF,"PARAMETER_DEF",first,LT(1)),
-									pm, #(create(TYPE,"TYPE",first,LT(1)),pd), id);}
-	;
-
-variableLengthParameterDeclaration!  {Token first = LT(1);}
-	:	pm:parameterModifier t:typeSpec[false] TRIPLE_DOT! id:IDENT
-		pd:declaratorBrackets[#t]
-		{#variableLengthParameterDeclaration = #(create(VARIABLE_PARAMETER_DEF,"VARIABLE_PARAMETER_DEF",first,LT(1)),
-												pm, #(create(TYPE,"TYPE",first,LT(1)),pd), id);}
-	;
-
-parameterModifier  {Token first = LT(1);}
-	//final can appear amongst annotations in any order - greedily consume any preceding
-	//annotations to shut non-determinism warnings off
-	:	(options{greedy=true;} : annotation)* (f:"final")? (annotation)*
-		{#parameterModifier = #(create(MODIFIERS,"MODIFIERS",first,LT(1)), #parameterModifier);}
-	;
-
-// Compound statement. This is used in many contexts:
-// Inside a class definition prefixed with "static":
-// it is a class initializer
-// Inside a class definition without "static":
-// it is an instance initializer
-// As the body of a method
-// As a completely independent braced block of code inside a method
-// it starts a new scope for variable definitions
-
-compoundStatement
-	:	lc:LCURLY^ {#lc.setType(SLIST);}
-			// include the (possibly-empty) list of statements
-			(statement)*
-		RCURLY!
-	;
-
-
-statement
-	// A list of statements in curly braces -- start a new scope!
-	:	compoundStatement
-
-	// declarations are ambiguous with "ID DOT" relative to expression
-	// statements. Must backtrack to be sure. Could use a semantic
-	// predicate to test symbol table to see what the type was coming
-	// up, but that's pretty hard without a symbol table ;)
-	|	(declaration)=> declaration SEMI!
-
-	// An expression statement. This could be a method call,
-	// assignment statement, or any other expression evaluated for
-	// side-effects.
-	|	expression SEMI!
-
-	//TODO: what about interfaces, enums and annotations
-	// class definition
-	|	m:modifiers! classDefinition[#m]
-
-	// Attach a label to the front of a statement
-	|	IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement
-
-	// If-else statement
-	|	"if"^ LPAREN! expression RPAREN! statement
-		(
-			// CONFLICT: the old "dangling-else" problem...
-			// ANTLR generates proper code matching
-			// as soon as possible. Hush warning.
-			options {
-				warnWhenFollowAmbig = false;
-			}
-		:
-			"else"! statement
-		)?
-
-	// For statement
-	|	forStatement
-
-	// While statement
-	|	"while"^ LPAREN! expression RPAREN! statement
-
-	// do-while statement
-	|	"do"^ statement "while"! LPAREN! expression RPAREN! SEMI!
-
-	// get out of a loop (or switch)
-	|	"break"^ (IDENT)? SEMI!
-
-	// do next iteration of a loop
-	|	"continue"^ (IDENT)? SEMI!
-
-	// Return an expression
-	|	"return"^ (expression)? SEMI!
-
-	// switch/case statement
-	|	"switch"^ LPAREN! expression RPAREN! LCURLY!
-			( casesGroup )*
-		RCURLY!
-
-	// exception try-catch block
-	|	tryBlock
-
-	// throw an exception
-	|	"throw"^ expression SEMI!
-
-	// synchronize a statement
-	|	"synchronized"^ LPAREN! expression RPAREN! compoundStatement
-
-	// asserts (uncomment if you want 1.4 compatibility)
-	|	"assert"^ expression ( COLON! expression )? SEMI!
-
-	// empty statement
-	|	s:SEMI {#s.setType(EMPTY_STAT);}
-	;
-
-forStatement
-	:	f:"for"^
-		LPAREN!
-			(	(forInit SEMI)=>traditionalForClause
-			|	forEachClause
-			)
-		RPAREN!
-		statement					 // statement to loop over
-	;
-
-traditionalForClause
-	:
-		forInit SEMI!	// initializer
-		forCond SEMI!	// condition test
-		forIter			// updater
-	;
-
-forEachClause  {Token first = LT(1);}
-	:
-		p:parameterDeclaration COLON! expression
-		{#forEachClause = #(create(FOR_EACH_CLAUSE,"FOR_EACH_CLAUSE",first,LT(1)), #forEachClause);}
-	;
-
-casesGroup
-	:	(	// CONFLICT: to which case group do the statements bind?
-			// ANTLR generates proper code: it groups the
-			// many "case"/"default" labels together then
-			// follows them with the statements
-			options {
-				greedy = true;
-			}
-			:
-			aCase
-		)+
-		caseSList
-		{#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);}
-	;
-
-aCase
-	:	("case"^ expression | "default") COLON!
-	;
-
-caseSList  {Token first = LT(1);}
-	:	(statement)*
-		{#caseSList = #(create(SLIST,"SLIST",first,LT(1)),#caseSList);}
-	;
-
-// The initializer for a for loop
-forInit  {Token first = LT(1);}
-		// if it looks like a declaration, it is
-	:	((declaration)=> declaration
-		// otherwise it could be an expression list...
-		|	expressionList
-		)?
-		{#forInit = #(create(FOR_INIT,"FOR_INIT",first,LT(1)),#forInit);}
-	;
-
-forCond  {Token first = LT(1);}
-	:	(expression)?
-		{#forCond = #(create(FOR_CONDITION,"FOR_CONDITION",first,LT(1)),#forCond);}
-	;
-
-forIter  {Token first = LT(1);}
-	:	(expressionList)?
-		{#forIter = #(create(FOR_ITERATOR,"FOR_ITERATOR",first,LT(1)),#forIter);}
-	;
-
-// an exception handler try/catch block
-// TODO currently handles try-with-resources only enough for groovydoc, not java2groovy
-// plan is to switch java2groovy over to using parrot parser (or some other alternative)
-tryBlock
-	:	"try"^ ((LPAREN) => resources!)? compoundStatement
-		(handler)*
-		( finallyClause )?
-	;
-
-resources
-    :   LPAREN! resourceList (SEMI!)? RPAREN!
-    ;
-
-resourceList
-    :   resource (SEMI! resource)*
-    ;
-
-resource
-    : (declaration) => declaration
-	| expression
-    ;
-
-finallyClause
-	:	"finally"^ compoundStatement
-	;
-
-// an exception handler borrowed from groovy.g to handle Java7+ multi-catch
-handler {Token first = LT(1);}
-    :   "catch"! LPAREN! pd:multicatch! RPAREN! handlerCs:compoundStatement!
-        {#handler = #(create(LITERAL_catch,"catch",first,LT(1)),pd,handlerCs);}
-    ;
-
-multicatch_types
-{Token first = LT(1);}
-    :
-        classOrInterfaceType[false]
-        (
-            BOR! classOrInterfaceType[false]
-        )*
-    ;
-
-multicatch
-{Token first = LT(1);}
-    :   (FINAL)? (m:multicatch_types) id:IDENT!
-    ;
-
-
-// expressions
-// Note that most of these expressions follow the pattern
-//   thisLevelExpression :
-//	   nextHigherPrecedenceExpression
-//		   (OPERATOR nextHigherPrecedenceExpression)*
-// which is a standard recursive definition for a parsing an expression.
-// The operators in java have the following precedences:
-//	lowest  (13)  = *= /= %= += -= <<= >>= >>>= &= ^= |=
-//			(12)  ?:
-//			(11)  ||
-//			(10)  &&
-//			( 9)  |
-//			( 8)  ^
-//			( 7)  &
-//			( 6)  == !=
-//			( 5)  < <= > >=
-//			( 4)  << >>
-//			( 3)  +(binary) -(binary)
-//			( 2)  * / %
-//			( 1)  ++ -- +(unary) -(unary)  ~  !  (type)
-//				  []   () (method call)  . (dot -- identifier qualification)
-//				  new   ()  (explicit parenthesis)
-//
-// the last two are not usually on a precedence chart; I put them in
-// to point out that new has a higher precedence than '.', so you
-// can validly use
-//	 new Frame().show()
-//
-// Note that the above precedence levels map to the rules below...
-// Once you have a precedence chart, writing the appropriate rules as below
-//   is usually very straightforward
-
-
-
-// the mother of all expressions
-expression  {Token first = LT(1);}
-	:	assignmentExpression
-		{#expression = #(create(EXPR,"EXPR",first,LT(1)),#expression);}
-	;
-
-
-// This is a list of expressions.
-expressionList  {Token first = LT(1);}
-	:	expression (COMMA! expression)*
-		{#expressionList = #(create(ELIST,"ELIST",first,LT(1)), #expressionList);}
-	;
-
-
-// assignment expression (level 13)
-assignmentExpression
-	:	conditionalExpression
-		(	(	ASSIGN^
-			|	PLUS_ASSIGN^
-			|	MINUS_ASSIGN^
-			|	STAR_ASSIGN^
-			|	DIV_ASSIGN^
-			|	MOD_ASSIGN^
-			|	SR_ASSIGN^
-			|	BSR_ASSIGN^
-			|	SL_ASSIGN^
-			|	BAND_ASSIGN^
-			|	BXOR_ASSIGN^
-			|	BOR_ASSIGN^
-			)
-			assignmentExpression
-		)?
-	;
-
-
-// conditional test (level 12)
-conditionalExpression
-	:	logicalOrExpression
-		( QUESTION^ assignmentExpression COLON! conditionalExpression )?
-	;
-
-
-// logical or (||) (level 11)
-logicalOrExpression
-	:	logicalAndExpression (LOR^ logicalAndExpression)*
-	;
-
-
-// logical and (&&) (level 10)
-logicalAndExpression
-	:	inclusiveOrExpression (LAND^ inclusiveOrExpression)*
-	;
-
-
-// bitwise or non-short-circuiting or (|) (level 9)
-inclusiveOrExpression
-	:	exclusiveOrExpression (BOR^ exclusiveOrExpression)*
-	;
-
-
-// exclusive or (^) (level 8)
-exclusiveOrExpression
-	:	andExpression (BXOR^ andExpression)*
-	;
-
-
-// bitwise or non-short-circuiting and (&) (level 7)
-andExpression
-	:	equalityExpression (BAND^ equalityExpression)*
-	;
-
-
-// equality/inequality (==/!=) (level 6)
-equalityExpression
-	:	relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)*
-	;
-
-
-// boolean relational expressions (level 5)
-relationalExpression
-	:	shiftExpression
-		(	(	(	LT^
-				|	GT^
-				|	LE^
-				|	GE^
-				)
-				shiftExpression
-			)*
-		|	"instanceof"^ typeSpec[true]
-		)
-	;
-
-
-// bit shift expressions (level 4)
-shiftExpression
-	:	additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)*
-	;
-
-
-// binary addition/subtraction (level 3)
-additiveExpression
-	:	multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)*
-	;
-
-
-// multiplication/division/modulo (level 2)
-multiplicativeExpression
-	:	unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)*
-	;
-
-unaryExpression
-	:	INC^ unaryExpression
-	|	DEC^ unaryExpression
-	|	MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression
-	|	PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression
-	|	unaryExpressionNotPlusMinus
-	;
-
-unaryExpressionNotPlusMinus
-	:	BNOT^ unaryExpression
-	|	LNOT^ unaryExpression
-	|	(	// sub-rule allows option to shut off warnings
-			options {
-				// "(int" ambig with postfixExpr due to lack of sequence
-				// info in linear approximate LL(k). It's ok. Shut up.
-				generateAmbigWarnings=false;
-			}
-		:	// If typecast is built in type, must be numeric operand
-			// Have to backtrack to see if operator follows
-		(LPAREN builtInTypeSpec[true] RPAREN unaryExpression)=>
-		lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN!
-		unaryExpression
-
-		// Have to backtrack to see if operator follows. If no operator
-		// follows, it's a typecast. No semantic checking needed to parse.
-		// if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)"
-	|	(LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=>
-		lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN!
-		unaryExpressionNotPlusMinus
-
-	|	postfixExpression
-	)
-	;
-
-// qualified names, array expressions, method invocation, post inc/dec
-postfixExpression
-	:
-		primaryExpression
-
-		(
-			/*
-			options {
-				// the use of postfixExpression in SUPER_CTOR_CALL adds DOT
-				// to the lookahead set, and gives loads of false non-det
-				// warnings.
-				// shut them off.
-				generateAmbigWarnings=false;
-			}
-		:	*/
-			//type arguments are only appropriate for a parameterized method/ctor invocations
-			//semantic check may be needed here to ensure that this is the case
-			DOT^ (typeArguments)?
-				(	IDENT
-					(	lp:LPAREN^ {#lp.setType(METHOD_CALL);}
-						argList
-						RPAREN!
-					)?
-				|	"super"
-					(	// (new Outer()).super() (create enclosing instance)
-						lp3:LPAREN^ argList RPAREN!
-						{#lp3.setType(SUPER_CTOR_CALL);}
-					|	DOT^ (typeArguments)? IDENT
-						(	lps:LPAREN^ {#lps.setType(METHOD_CALL);}
-							argList
-							RPAREN!
-						)?
-					)
-				)
-		|	DOT^ "this"
-		|	DOT^ newExpression
-		|	lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK!
-		)*
-
-		(	// possibly add on a post-increment or post-decrement.
-			// allows INC/DEC on too much, but semantics can check
-			in:INC^ {#in.setType(POST_INC);}
-	 	|	de:DEC^ {#de.setType(POST_DEC);}
-		)?
- 	;
-
-// the basic element of an expression
-primaryExpression
-	:	identPrimary ( options {greedy=true;} : DOT^ "class" )?
-	|	constant
-	|	"true"
-	|	"false"
-	|	"null"
-	|	newExpression
-	|	"this"
-	|	"super"
-	|	LPAREN! assignmentExpression RPAREN!
-		// look for int.class and int[].class
-	|	builtInType
-		( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )*
-		DOT^ "class"
-	;
-
-/** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class,
- *  and a.b.c.class refs. Also this(...) and super(...). Match
- *  this or super.
- */
-identPrimary
-	:	(ta1:typeArguments!)?
-		IDENT
-		// Syntax for method invocation with type arguments is
-		// <String>foo("blah")
-		(
-			options {
-				// .ident could match here or in postfixExpression.
-				// We do want to match here. Turn off warning.
-				greedy=true;
-				// This turns the ambiguity warning of the second alternative
-				// off. See below. (The "false" predicate makes it non-issue)
-				warnWhenFollowAmbig=false;
-			}
-			// we have a new non-determinism because of
-			// typeArguments... only a syntactic predicate will help...
-			// The problem is that this loop here conflicts with
-			// DOT typeArguments "super" in postfixExpression (k=2)
-			// A proper solution would require a lot of refactoring...
-		:	(DOT (typeArguments)? IDENT) =>
-				DOT^ (ta2:typeArguments!)? IDENT
-		|	{false}?	// FIXME: this is very ugly but it seems to work...
-						// this will also produce an ANTLR warning!
-				// Unfortunately a syntactic predicate can only select one of
-				// multiple alternatives on the same level, not break out of
-				// an enclosing loop, which is why this ugly hack (a fake
-				// empty alternative with always-false semantic predicate)
-				// is necessary.
-		)*
-		(
-			options {
-				// ARRAY_DECLARATOR here conflicts with INDEX_OP in
-				// postfixExpression on LBRACK RBRACK.
-				// We want to match [] here, so greedy. This overcomes
-				// limitation of linear approximate lookahead.
-				greedy=true;
-			}
-		:	(	lp:LPAREN^ {#lp.setType(METHOD_CALL);}
-				// if the input is valid, only the last IDENT may
-				// have preceding typeArguments... rather hacky, this is...
-				{if (#ta2 != null) astFactory.addASTChild(currentAST, #ta2);}
-				{if (#ta2 == null) astFactory.addASTChild(currentAST, #ta1);}
-				argList RPAREN!
-			)
-		|	( options {greedy=true;} :
-				lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK!
-			)+
-		)?
-	;
-
-/** object instantiation.
- *  Trees are built as illustrated by the following input/tree pairs:
- *
- *  new T()
- *
- *  new
- *   |
- *   T --  ELIST
- *		   |
- *		  arg1 -- arg2 -- .. -- argn
- *
- *  new int[]
- *
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR
- *
- *  new int[] {1,2}
- *
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR -- ARRAY_INIT
- *								  |
- *								EXPR -- EXPR
- *								  |	  |
- *								  1	  2
- *
- *  new int[3]
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR
- *				|
- *			  EXPR
- *				|
- *				3
- *
- *  new int[1][2]
- *
- *  new
- *   |
- *  int -- ARRAY_DECLARATOR
- *			   |
- *		 ARRAY_DECLARATOR -- EXPR
- *			   |			  |
- *			 EXPR			 1
- *			   |
- *			   2
- *
- */
-newExpression
-	:	"new"^ (typeArguments)? type
-		(	LPAREN! argList RPAREN! (classBlock)?
-
-			//java 1.1
-			// Note: This will allow bad constructs like
-			//	new int[4][][3] {exp,exp}.
-			//	There needs to be a semantic check here...
-			// to make sure:
-			//   a) [ expr ] and [ ] are not mixed
-			//   b) [ expr ] and an init are not used together
-
-		|	newArrayDeclarator (arrayInitializer)?
-		)
-	;
-
-argList {Token first = LT(1);}
-	:	(	expressionList
-		|	/*nothing*/
-			{#argList = create(ELIST,"ELIST",first,LT(1));}
-		)
-	;
-
-newArrayDeclarator
-	:	(
-			// CONFLICT:
-			// newExpression is a primaryExpression which can be
-			// followed by an array index reference. This is ok,
-			// as the generated code will stay in this loop as
-			// long as it sees an LBRACK (proper behavior)
-			options {
-				warnWhenFollowAmbig = false;
-			}
-		:
-			lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);}
-				(expression)?
-			RBRACK!
-		)+
-	;
-
-constant
-	:	NUM_INT
-	|	CHAR_LITERAL
-	|	STRING_LITERAL
-	|	NUM_FLOAT
-	|	NUM_LONG
-	|	NUM_DOUBLE
-	;
-
-
-//----------------------------------------------------------------------------
-// The Java scanner
-//----------------------------------------------------------------------------
-class JavaLexer extends Lexer;
-
-options {
-	exportVocab=Java;		// call the vocabulary "Java"
-	testLiterals=false;		// don't automatically test for literals
-	k=4;					// four characters of lookahead
-	charVocabulary='\u0003'..'\uFFFF';
-	// without inlining some bitset tests, couldn't do unicode;
-	// I need to make ANTLR generate smaller bitsets; see
-	// bottom of JavaLexer.java
-	codeGenBitsetTestThreshold=20;
-}
-
-{
-    protected static final int SCS_TYPE = 3, SCS_VAL = 4, SCS_LIT = 8, SCS_LIMIT = 16;
-    protected static final int SCS_SQ_TYPE = 0, SCS_TQ_TYPE = 1, SCS_RE_TYPE = 2;
-    protected int stringCtorState = 0;  // hack string and regexp constructor boundaries
-    protected int lastSigTokenType = EOF;  // last returned non-whitespace token
-
-    /** flag for enabling the "assert" keyword */
-	private boolean assertEnabled = true;
-	/** flag for enabling the "enum" keyword */
-	private boolean enumEnabled = true;
-    /** flag for including whitespace tokens (for IDE preparsing) */
-    private boolean whitespaceIncluded = false;
-
-	/** Enable the "assert" keyword */
-	public void enableAssert(boolean shouldEnable) { assertEnabled = shouldEnable; }
-	/** Query the "assert" keyword state */
-	public boolean isAssertEnabled() { return assertEnabled; }
-	/** Enable the "enum" keyword */
-	public void enableEnum(boolean shouldEnable) { enumEnabled = shouldEnable; }
-	/** Query the "enum" keyword state */
-	public boolean isEnumEnabled() { return enumEnabled; }
-
-    /** This is a bit of plumbing which resumes collection of string constructor bodies,
-     *  after an embedded expression has been parsed.
-     *  Usage:  new JavaRecognizer(new JavaLexer(in).plumb()).
-     */
-    public TokenStream plumb() {
-        return new TokenStream() {
-            public Token nextToken() throws TokenStreamException {
-                if (stringCtorState >= SCS_LIT) {
-                    // This goo is modeled upon the ANTLR code for nextToken:
-                    int quoteType = (stringCtorState & SCS_TYPE);
-                    stringCtorState = 0;  // get out of this mode, now
-                    resetText();
-/*                    try {
-                        switch (quoteType) {
-                        case SCS_SQ_TYPE:
-//todo: suitable replacement???     mSTRING_CTOR_END(true, false, false); 
-                        	break;
-                        case SCS_TQ_TYPE:
-//                            mSTRING_CTOR_END(true, false, true); 
-                        	break;
-                        case SCS_RE_TYPE:
-//                            mREGEXP_CTOR_END(true, false); 
-                        	break;
-                        default:  throw new AssertionError(false);
-                        }
-                        lastSigTokenType = _returnToken.getType();
-                        return _returnToken;
-                    }*//* catch (RecognitionException e) {
-                        throw new TokenStreamRecognitionException(e);
-                    }*/ /*catch (CharStreamException cse) {
-                        if ( cse instanceof CharStreamIOException ) {
-                            throw new TokenStreamIOException(((CharStreamIOException)cse).io);
-                        }
-                        else {
-                            throw new TokenStreamException(cse.getMessage());
-                        }
-                    }*/
-                }
-                Token token = JavaLexer.this.nextToken();
-                int lasttype = token.getType();
-                if (whitespaceIncluded) {
-                    switch (lasttype) {  // filter out insignificant types
-                    case WS:
-                    case SL_COMMENT:
-                    case ML_COMMENT:
-                        lasttype = lastSigTokenType;  // back up!
-                    }
-                }
-                lastSigTokenType = lasttype;
-                return token;
-            }
-        };
-    }
-    
-    protected JavaRecognizer parser;  // little-used link; TODO: get rid of
-}
-
-// OPERATORS
-QUESTION		:	'?'		;
-LPAREN			:	'('		;
-RPAREN			:	')'		;
-LBRACK			:	'['		;
-RBRACK			:	']'		;
-LCURLY			:	'{'		;
-RCURLY			:	'}'		;
-COLON			:	':'		;
-COMMA			:	','		;
-//DOT			:	'.'		;
-ASSIGN			:	'='		;
-EQUAL			:	"=="	;
-LNOT			:	'!'		;
-BNOT			:	'~'		;
-NOT_EQUAL		:	"!="	;
-DIV				:	'/'		;
-DIV_ASSIGN		:	"/="	;
-PLUS			:	'+'		;
-PLUS_ASSIGN		:	"+="	;
-INC				:	"++"	;
-MINUS			:	'-'		;
-MINUS_ASSIGN	:	"-="	;
-DEC				:	"--"	;
-STAR			:	'*'		;
-STAR_ASSIGN		:	"*="	;
-MOD				:	'%'		;
-MOD_ASSIGN		:	"%="	;
-SR				:	">>"	;
-SR_ASSIGN		:	">>="	;
-BSR				:	">>>"	;
-BSR_ASSIGN		:	">>>="	;
-GE				:	">="	;
-GT				:	">"		;
-SL				:	"<<"	;
-SL_ASSIGN		:	"<<="	;
-LE				:	"<="	;
-LT				:	'<'		;
-BXOR			:	'^'		;
-BXOR_ASSIGN		:	"^="	;
-BOR				:	'|'		;
-BOR_ASSIGN		:	"|="	;
-LOR				:	"||"	;
-BAND			:	'&'		;
-BAND_ASSIGN		:	"&="	;
-LAND			:	"&&"	;
-SEMI			:	';'		;
-
-
-// Whitespace -- ignored
-WS	:	(	' '
-		|	'\t'
-		|	'\f'
-			// handle newlines
-		|	(	options {generateAmbigWarnings=false;}
-			:	"\r\n"	// Evil DOS
-			|	'\r'	// Macintosh
-			|	'\n'	// Unix (the right way)
-			)
-			{ newline(); }
-		)+
-		{ _ttype = Token.SKIP; }
-	;
-
-// Single-line comments
-SL_COMMENT
-	:	"//"
-        (
-            options {  greedy = true;  }:
-            // '\uffff' means the EOF character.
-            ~('\n'|'\r'|'\uffff')
-        )*
-		{$setType(Token.SKIP);}
-	;
-
-// multiple-line comments
-ML_COMMENT
-	:	"/*"
-		(	/*	'\r' '\n' can be matched in one alternative or by matching
-				'\r' in one iteration and '\n' in another. I am trying to
-				handle any flavor of newline that comes in, but the language
-				that allows both "\r\n" and "\r" and "\n" to all be valid
-				newline is ambiguous. Consequently, the resulting grammar
-				must be ambiguous. I'm shutting this warning off.
-			 */
-			options {
-				generateAmbigWarnings=false;
-			}
-		:
-			{ LA(2)!='/' }? '*'
-		|	'\r' '\n'		{newline();}
-		|	'\r'			{newline();}
-		|	'\n'			{newline();}
-		|	~('*'|'\n'|'\r')
-		)*
-		"*/"
-		{$setType(Token.SKIP);}
-	;
-
-
-//	 character literals
-	CHAR_LITERAL
-		:	'\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\''
-		;
-
-//	 string literals
-	STRING_LITERAL
-		:	'"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"'
-		;
-
-
-// escape sequence -- note that this is protected; it can only be called
-// from another lexer rule -- it will not ever directly return a token to
-// the parser
-// There are various ambiguities hushed in this rule. The optional
-// '0'...'9' digit matches should be matched here rather than letting
-// them go back to STRING_LITERAL to be matched. ANTLR does the
-// right thing by matching immediately; hence, it's ok to shut off
-// the FOLLOW ambig warnings.
-protected
-ESC
-	:	'\\'
-		(	'n'
-		|	'r'
-		|	't'
-		|	'b'
-		|	'f'
-		|	'"'
-		|	'\''
-		|	'\\'
-		|	('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
-		|	'0'..'3'
-			(
-				options {
-					warnWhenFollowAmbig = false;
-				}
-			:	'0'..'7'
-				(
-					options {
-						warnWhenFollowAmbig = false;
-					}
-				:	'0'..'7'
-				)?
-			)?
-		|	'4'..'7'
-			(
-				options {
-					warnWhenFollowAmbig = false;
-				}
-			:	'0'..'7'
-			)?
-		)
-	;
-
-
-// hexadecimal digit (again, note it's protected!)
-protected
-HEX_DIGIT
-	:	('0'..'9'|'A'..'F'|'a'..'f')
-	;
-
-
-// a dummy rule to force vocabulary to be all characters (except special
-// ones that ANTLR uses internally (0 to 2)
-protected
-VOCAB
-	:	'\3'..'\377'
-	;
-
-
-// an identifier. Note that testLiterals is set to true! This means
-// that after we match the rule, we look in the literals table to see
-// if it's a literal or really an identifer
-IDENT
-	options {testLiterals=true;}
-	:	('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')*
-		{
-			// check if "assert" keyword is enabled
-			if (assertEnabled && "assert".equals($getText)) {
-				$setType(LITERAL_assert); // set token type for the rule in the parser
-			}
-			// check if "enum" keyword is enabled
-			if (enumEnabled && "enum".equals($getText)) {
-				$setType(LITERAL_enum); // set token type for the rule in the parser
-			}
-		}
-	;
-
-protected
-DIGIT
-options {
-    paraphrase="a digit";
-}
-    :   '0'..'9'
-    // TODO:  Recognize all the Java identifier parts here (except '$').
-    ;
-
-protected
-DIGITS_WITH_UNDERSCORE
-options {
-    paraphrase="a sequence of digits and underscores, bordered by digits";
-}
-    :   DIGIT (DIGITS_WITH_UNDERSCORE_OPT)?
-    ;
-
-protected
-DIGITS_WITH_UNDERSCORE_OPT
-options {
-    paraphrase="a sequence of digits and underscores with maybe underscore starting";
-}
-    :   (DIGIT | '_')* DIGIT
-    ;
-
-// a numeric literal
-NUM_INT
-	{boolean isDecimal=false; Token t=null;}
-	:	'.' {_ttype = DOT;}
-			(
-				(('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
-				{
-				if (t != null && t.getText().toUpperCase().indexOf('F')>=0) {
-					_ttype = NUM_FLOAT;
-				}
-				else {
-					_ttype = NUM_DOUBLE; // assume double
-				}
-				})
-				|
-				// JDK 1.5 token for variable length arguments
-				(".." {_ttype = TRIPLE_DOT;})
-			)?
-
-	|	(	'0' {isDecimal = true;} // special case for just '0'
-			(	('x'|'X')
-				(											// hex
-					// the 'e'|'E' and float suffix stuff look
-					// like hex digits, hence the (...)+ doesn't
-					// know when to stop: ambig. ANTLR resolves
-					// it correctly by matching immediately. It
-					// is therefor ok to hush warning.
-					options {
-						warnWhenFollowAmbig=false;
-					}
-				:	HEX_DIGIT
-				)+
-
-			|	//float or double with leading zero
-                (   DIGITS_WITH_UNDERSCORE
-                    ( '.' DIGITS_WITH_UNDERSCORE | EXPONENT | FLOAT_SUFFIX)
-                ) => DIGITS_WITH_UNDERSCORE
-
-			|	('0'..'7')+									// octal
-			)?
-		|	('1'..'9') (DIGITS_WITH_UNDERSCORE_OPT)?  {isDecimal=true;}		// non-zero decimal
-		)
-		(	('l'|'L') { _ttype = NUM_LONG; }
-
-		// only check to see if it's a float if looks like decimal so far
-		|	{isDecimal}?
-			(	'.' DIGITS_WITH_UNDERSCORE (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
-			|	EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
-			|	f4:FLOAT_SUFFIX {t=f4;}
-			)
-			{
-			if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) {
-				_ttype = NUM_FLOAT;
-			}
-			else {
-				_ttype = NUM_DOUBLE; // assume double
-			}
-			}
-		)?
-	;
-
-// JDK 1.5 token for annotations and their declarations
-AT
-	:	'@'
-	;
-
-// a couple protected methods to assist in matching floating point numbers
-protected
-EXPONENT
-	:	('e'|'E') ('+'|'-')? ('0'..'9')+
-	;
-
-
-protected
-FLOAT_SUFFIX
-	:	'f'|'F'|'d'|'D'
-	;
-			
-
-//			 Note: Please don't use physical tabs.  Logical tabs for indent are width 4.
-//			 Here's a little hint for you, Emacs:
-//			 Local Variables:
-//			 tab-width: 4
-//			 mode: antlr-mode
-//			 indent-tabs-mode: nil
-//			 End:
diff --git a/src/main/java/org/codehaus/groovy/antlr/ASTParserException.java b/src/main/java/org/codehaus/groovy/antlr/ASTParserException.java
deleted file mode 100644
index a74ed93..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/ASTParserException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import antlr.collections.AST;
-import org.codehaus.groovy.syntax.ParserException;
-
-/**
- * Thrown when trying to parse the AST
- */
-public class ASTParserException extends ParserException {
-    private static final long serialVersionUID = 7307319325760515017L;
-    private final AST ast;
-
-    public ASTParserException(ASTRuntimeException e) {
-        super(e.getMessage(), e, e.getLine(), e.getColumn(), getLineLast(e), getColumnLast(e));
-        this.ast = e.getAst();
-    }
-
-    public ASTParserException(String message, ASTRuntimeException e) {
-        super(message, e, e.getLine(), e.getColumn(), getLineLast(e), getColumnLast(e));
-        this.ast = e.getAst();
-    }
-
-    public AST getAst() {
-        return ast;
-    }
-    
-    private static int getLineLast(ASTRuntimeException e) {
-        final AST ast = e.getAst();
-        return (ast instanceof SourceInfo) ? ((SourceInfo)ast).getLineLast() : ast.getLine();
-    }
-
-    private static int getColumnLast(ASTRuntimeException e) {
-        final AST ast = e.getAst();
-        return (ast instanceof SourceInfo) ? ((SourceInfo)ast).getColumnLast() : ast.getColumn()+1;
-    }
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/ASTRuntimeException.java b/src/main/java/org/codehaus/groovy/antlr/ASTRuntimeException.java
deleted file mode 100644
index 11f082b..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/ASTRuntimeException.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import antlr.collections.AST;
-
-/**
- * Used within the Groovy's AntlrParserPlugin
- */
-public class ASTRuntimeException extends RuntimeException {
-    private static final long serialVersionUID = 238104771184624613L;
-    private final AST ast;
-
-    public ASTRuntimeException(AST ast, String message) {
-        super(message + description(ast));
-        this.ast = ast;
-    }
-
-    public ASTRuntimeException(AST ast, String message, Throwable throwable) {
-        super(message + description(ast), throwable);
-        this.ast = null;
-    }
-
-    protected static String description(AST node) {
-        return (node != null) ? " at line: " + node.getLine() + " column: " + node.getColumn() : "";
-    }
-
-    public AST getAst() {
-        return ast;
-    }
-
-    public int getLine() {
-        return ast != null ? ast.getLine() : -1;
-    }
-
-    public int getColumn() {
-        return ast != null ? ast.getColumn() : -1;
-    }
-
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrASTProcessSnippets.java b/src/main/java/org/codehaus/groovy/antlr/AntlrASTProcessSnippets.java
deleted file mode 100644
index 1373649..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrASTProcessSnippets.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-/**
- * Process to decorate antlr AST with ending line/col info, and if
- * possible the snippet of source from the start/end line/col for each node.
- */
-
-import antlr.collections.AST;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-public class AntlrASTProcessSnippets implements AntlrASTProcessor{
-
-    public AntlrASTProcessSnippets() {
-    }
-
-    /**
-     * decorate antlr AST with ending line/col info, and if
-     * possible the snippet of source from the start/end line/col for each node.
-     * @param t the AST to decorate
-     * @return the decorated AST
-     */
-    public AST process(AST t) {
-        // first visit
-        List l = new ArrayList();
-        traverse((GroovySourceAST)t,l,null);
-
-        //System.out.println("l:" + l);
-        // second visit
-        Iterator itr = l.iterator();
-        if (itr.hasNext()) { itr.next(); /* discard first */ }
-        traverse((GroovySourceAST)t,null,itr);
-        return t;
-    }
-
-    /**
-     * traverse an AST node
-     * @param t the AST node to traverse
-     * @param l A list to add line/col info to
-     * @param itr An iterator over a list of line/col
-     */
-    private void traverse(GroovySourceAST t,List l,Iterator itr) {
-         while (t != null) {
-             // first visit of node
-             if (l != null) {
-                 l.add(new LineColumn(t.getLine(),t.getColumn()));
-             }
-
-             // second visit of node
-             if (itr != null && itr.hasNext()) {
-                 LineColumn lc = (LineColumn)itr.next();
-                 if (t.getLineLast() == 0) {
-                     int nextLine = lc.getLine();
-                     int nextColumn = lc.getColumn();
-                     if (nextLine < t.getLine() || (nextLine == t.getLine() && nextColumn < t.getColumn())) {
-                         nextLine = t.getLine();
-                         nextColumn = t.getColumn();
-                     }
-                     t.setLineLast(nextLine);
-                     t.setColumnLast(nextColumn);
-                     // This is a good point to call t.setSnippet(),
-                     // but it bulks up the AST too much for production code.
-                 }
-             }
-
-             GroovySourceAST child = (GroovySourceAST)t.getFirstChild();
-             if (child != null) {
-                 traverse(child,l,itr);
-             }
-
-             t = (GroovySourceAST)t.getNextSibling();
-         }
-    }
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrASTProcessor.java b/src/main/java/org/codehaus/groovy/antlr/AntlrASTProcessor.java
deleted file mode 100644
index 4eea485..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrASTProcessor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import antlr.collections.AST;
-
-/**
- * An interface for processing antlr AST objects
- */
-public interface AntlrASTProcessor {
-    /**
-     * performs some processing on the supplied AST node.
-     * @param t the AST node to process.
-     * @return possibly returns the AST modified or null, depends on the implementation.
-     */
-    AST process(AST t);
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
deleted file mode 100644
index c7c095f..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
+++ /dev/null
@@ -1,3175 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-import antlr.TokenStreamRecognitionException;
-import antlr.collections.AST;
-import groovy.transform.Trait;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.antlr.parser.GroovyLexer;
-import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
-import org.codehaus.groovy.antlr.parser.GroovyTokenTypes;
-import org.codehaus.groovy.antlr.treewalker.CompositeVisitor;
-import org.codehaus.groovy.antlr.treewalker.MindMapPrinter;
-import org.codehaus.groovy.antlr.treewalker.NodeAsHTMLPrinter;
-import org.codehaus.groovy.antlr.treewalker.PreOrderTraversal;
-import org.codehaus.groovy.antlr.treewalker.SourceCodeTraversal;
-import org.codehaus.groovy.antlr.treewalker.SourcePrinter;
-import org.codehaus.groovy.antlr.treewalker.Visitor;
-import org.codehaus.groovy.antlr.treewalker.VisitorAdapter;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ConstructorNode;
-import org.codehaus.groovy.ast.EnumConstantClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.GenericsType;
-import org.codehaus.groovy.ast.ImportNode;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.MixinNode;
-import org.codehaus.groovy.ast.ModuleNode;
-import org.codehaus.groovy.ast.PackageNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
-import org.codehaus.groovy.ast.expr.ArrayExpression;
-import org.codehaus.groovy.ast.expr.AttributeExpression;
-import org.codehaus.groovy.ast.expr.BinaryExpression;
-import org.codehaus.groovy.ast.expr.BitwiseNegationExpression;
-import org.codehaus.groovy.ast.expr.BooleanExpression;
-import org.codehaus.groovy.ast.expr.CastExpression;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ClosureExpression;
-import org.codehaus.groovy.ast.expr.ClosureListExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
-import org.codehaus.groovy.ast.expr.DeclarationExpression;
-import org.codehaus.groovy.ast.expr.ElvisOperatorExpression;
-import org.codehaus.groovy.ast.expr.EmptyExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.ExpressionTransformer;
-import org.codehaus.groovy.ast.expr.FieldExpression;
-import org.codehaus.groovy.ast.expr.GStringExpression;
-import org.codehaus.groovy.ast.expr.ListExpression;
-import org.codehaus.groovy.ast.expr.MapEntryExpression;
-import org.codehaus.groovy.ast.expr.MapExpression;
-import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.MethodPointerExpression;
-import org.codehaus.groovy.ast.expr.NamedArgumentListExpression;
-import org.codehaus.groovy.ast.expr.NotExpression;
-import org.codehaus.groovy.ast.expr.PostfixExpression;
-import org.codehaus.groovy.ast.expr.PrefixExpression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
-import org.codehaus.groovy.ast.expr.RangeExpression;
-import org.codehaus.groovy.ast.expr.SpreadExpression;
-import org.codehaus.groovy.ast.expr.SpreadMapExpression;
-import org.codehaus.groovy.ast.expr.TernaryExpression;
-import org.codehaus.groovy.ast.expr.TupleExpression;
-import org.codehaus.groovy.ast.expr.UnaryMinusExpression;
-import org.codehaus.groovy.ast.expr.UnaryPlusExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.AssertStatement;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.BreakStatement;
-import org.codehaus.groovy.ast.stmt.CaseStatement;
-import org.codehaus.groovy.ast.stmt.CatchStatement;
-import org.codehaus.groovy.ast.stmt.ContinueStatement;
-import org.codehaus.groovy.ast.stmt.EmptyStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.ForStatement;
-import org.codehaus.groovy.ast.stmt.IfStatement;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.stmt.SwitchStatement;
-import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
-import org.codehaus.groovy.ast.stmt.ThrowStatement;
-import org.codehaus.groovy.ast.stmt.TryCatchStatement;
-import org.codehaus.groovy.ast.stmt.WhileStatement;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.ParserPlugin;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.XStreamUtils;
-import org.codehaus.groovy.syntax.ASTHelper;
-import org.codehaus.groovy.syntax.Numbers;
-import org.codehaus.groovy.syntax.ParserException;
-import org.codehaus.groovy.syntax.Reduction;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.codehaus.groovy.syntax.Token;
-import org.codehaus.groovy.syntax.Types;
-import org.objectweb.asm.Opcodes;
-
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
-import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;
-
-/**
- * A parser plugin which adapts the JSR Antlr Parser to the Groovy runtime.
- */
-@Deprecated
-public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, GroovyTokenTypes {
-
-    private static class AnonymousInnerClassCarrier extends Expression {
-        ClassNode innerClass;
-
-        @Override
-        public Expression transformExpression(ExpressionTransformer transformer) {
-            return null;
-        }
-
-        @Override
-        public void setSourcePosition(final ASTNode node) {
-            super.setSourcePosition(node);
-            innerClass.setSourcePosition(node);
-        }
-
-        @Override
-        public void setColumnNumber(final int columnNumber) {
-            super.setColumnNumber(columnNumber);
-            innerClass.setColumnNumber(columnNumber);
-        }
-
-        @Override
-        public void setLineNumber(final int lineNumber) {
-            super.setLineNumber(lineNumber);
-            innerClass.setLineNumber(lineNumber);
-        }
-
-        @Override
-        public void setLastColumnNumber(final int columnNumber) {
-            super.setLastColumnNumber(columnNumber);
-            innerClass.setLastColumnNumber(columnNumber);
-        }
-
-        @Override
-        public void setLastLineNumber(final int lineNumber) {
-            super.setLastLineNumber(lineNumber);
-            innerClass.setLastLineNumber(lineNumber);
-        }
-    }
-
-    protected AST ast;
-    private ClassNode classNode;
-    private MethodNode methodNode;
-    protected String[] tokenNames;
-    private boolean enumConstantBeingDef;
-    private boolean forStatementBeingDef;
-    private boolean annotationBeingDef;
-    private boolean firstParamIsVarArg;
-    private boolean firstParam;
-
-    public Reduction parseCST(SourceUnit sourceUnit, Reader reader) throws CompilationFailedException {
-        SourceBuffer sourceBuffer = new SourceBuffer();
-        transformCSTIntoAST(sourceUnit, reader, sourceBuffer);
-        processAST();
-        return outputAST(sourceUnit, sourceBuffer);
-    }
-
-    protected void transformCSTIntoAST(SourceUnit sourceUnit, Reader reader, SourceBuffer sourceBuffer) throws CompilationFailedException {
-        ast = null;
-
-        setController(sourceUnit);
-
-        UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(reader, sourceBuffer);
-        UnicodeLexerSharedInputState inputState = new UnicodeLexerSharedInputState(unicodeReader);
-        GroovyLexer lexer = new GroovyLexer(inputState);
-        unicodeReader.setLexer(lexer);
-        GroovyRecognizer parser = GroovyRecognizer.make(lexer);
-        parser.setSourceBuffer(sourceBuffer);
-        tokenNames = parser.getTokenNames();
-        parser.setFilename(sourceUnit.getName());
-
-        // start parsing at the compilationUnit rule
-        try {
-            parser.compilationUnit();
-        }
-        catch (TokenStreamRecognitionException tsre) {
-            RecognitionException e = tsre.recog;
-            SyntaxException se = new SyntaxException(e.getMessage(), e, e.getLine(), e.getColumn());
-            se.setFatal(true);
-            sourceUnit.addError(se);
-        }
-        catch (RecognitionException e) {
-            SyntaxException se = new SyntaxException(e.getMessage(), e, e.getLine(), e.getColumn());
-            se.setFatal(true);
-            sourceUnit.addError(se);
-        }
-        catch (TokenStreamException e) {
-            sourceUnit.addException(e);
-        }
-
-        ast = parser.getAST();
-    }
-
-    protected void processAST() {
-        AntlrASTProcessor snippets = new AntlrASTProcessSnippets();
-        ast = snippets.process(ast);
-    }
-
-    public Reduction outputAST(final SourceUnit sourceUnit, final SourceBuffer sourceBuffer) {
-        return AccessController.doPrivileged((PrivilegedAction<Reduction>) () -> {
-            outputASTInVariousFormsIfNeeded(sourceUnit, sourceBuffer);
-            return null;
-        });
-    }
-
-    private void outputASTInVariousFormsIfNeeded(SourceUnit sourceUnit, SourceBuffer sourceBuffer) {
-        // straight xstream output of AST
-        String formatProp = System.getProperty("ANTLR.AST".toLowerCase()); // uppercase to hide from jarjar
-
-        if ("xml".equals(formatProp)) {
-            XStreamUtils.serialize(sourceUnit.getName() + ".antlr", ast);
-        }
-
-        // 'pretty printer' output of AST
-        if ("groovy".equals(formatProp)) {
-            try {
-                PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".pretty.groovy"));
-                Visitor visitor = new SourcePrinter(out, tokenNames);
-                AntlrASTProcessor treewalker = new SourceCodeTraversal(visitor);
-                treewalker.process(ast);
-            } catch (FileNotFoundException e) {
-                System.out.println("Cannot create " + sourceUnit.getName() + ".pretty.groovy");
-            }
-        }
-
-        // output AST in format suitable for opening in http://freemind.sourceforge.net
-        // which is a really nice way of seeing the AST, folding nodes etc
-        if ("mindmap".equals(formatProp)) {
-            try {
-                PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".mm"));
-                Visitor visitor = new MindMapPrinter(out, tokenNames);
-                AntlrASTProcessor treewalker = new PreOrderTraversal(visitor);
-                treewalker.process(ast);
-            } catch (FileNotFoundException e) {
-                System.out.println("Cannot create " + sourceUnit.getName() + ".mm");
-            }
-        }
-
-        // include original line/col info and source code on the mindmap output
-        if ("extendedMindmap".equals(formatProp)) {
-            try {
-                PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".mm"));
-                Visitor visitor = new MindMapPrinter(out, tokenNames, sourceBuffer);
-                AntlrASTProcessor treewalker = new PreOrderTraversal(visitor);
-                treewalker.process(ast);
-            } catch (FileNotFoundException e) {
-                System.out.println("Cannot create " + sourceUnit.getName() + ".mm");
-            }
-        }
-
-        // html output of AST
-        if ("html".equals(formatProp)) {
-            try {
-                PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".html"));
-                List<VisitorAdapter> v = new ArrayList<>();
-                v.add(new NodeAsHTMLPrinter(out, tokenNames));
-                v.add(new SourcePrinter(out, tokenNames));
-                Visitor visitors = new CompositeVisitor(v);
-                AntlrASTProcessor treewalker = new SourceCodeTraversal(visitors);
-                treewalker.process(ast);
-            } catch (FileNotFoundException e) {
-                System.out.println("Cannot create " + sourceUnit.getName() + ".html");
-            }
-        }
-    }
-
-    public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException {
-        setClassLoader(classLoader);
-        makeModule();
-        try {
-            convertGroovy(ast);
-            if (output.getStatementBlock().isEmpty() && output.getMethods().isEmpty() && output.getClasses().isEmpty()) {
-                output.addStatement(ReturnStatement.RETURN_NULL_OR_VOID);
-            }
-
-            // set the script source position
-            ClassNode scriptClassNode = output.getScriptClassDummy();
-            if (scriptClassNode != null) {
-                List<Statement> statements = output.getStatementBlock().getStatements();
-                if (!statements.isEmpty()) {
-                    Statement firstStatement = statements.get(0);
-                    Statement lastStatement = statements.get(statements.size() - 1);
-
-                    scriptClassNode.setSourcePosition(firstStatement);
-                    scriptClassNode.setLastColumnNumber(lastStatement.getLastColumnNumber());
-                    scriptClassNode.setLastLineNumber(lastStatement.getLastLineNumber());
-                }
-            }
-        } catch (ASTRuntimeException e) {
-            throw new ASTParserException(e.getMessage() + ". File: " + sourceUnit.getName(), e);
-        }
-        ast = null;
-        return output;
-    }
-
-    /**
-     * Converts the Antlr AST to the Groovy AST.
-     */
-    protected void convertGroovy(AST node) {
-        while (node != null) {
-            int type = node.getType();
-            switch (type) {
-                case PACKAGE_DEF:
-                    packageDef(node);
-                    break;
-
-                case STATIC_IMPORT:
-                case IMPORT:
-                    importDef(node);
-                    break;
-
-                case TRAIT_DEF:
-                case CLASS_DEF:
-                    classDef(node);
-                    break;
-
-                case INTERFACE_DEF:
-                    interfaceDef(node);
-                    break;
-
-                case METHOD_DEF:
-                    methodDef(node);
-                    break;
-
-                case ENUM_DEF:
-                    enumDef(node);
-                    break;
-
-                case ANNOTATION_DEF:
-                    annotationDef(node);
-                    break;
-
-                default:
-                    output.addStatement(statement(node));
-            }
-            node = node.getNextSibling();
-        }
-    }
-
-    // Top level control structures
-    //-------------------------------------------------------------------------
-
-    protected void packageDef(AST packageDef) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST node = packageDef.getFirstChild();
-        if (isType(ANNOTATIONS, node)) {
-            processAnnotations(annotations, node);
-            node = node.getNextSibling();
-        }
-        PackageNode packageNode = setPackage(qualifiedName(node), annotations);
-        configureAST(packageNode, packageDef);
-    }
-
-    protected void importDef(AST importNode) {
-        try {
-            // GROOVY-6094
-            output.putNodeMetaData(ImportNode.class, ImportNode.class);
-
-            boolean isStatic = importNode.getType() == STATIC_IMPORT;
-            List<AnnotationNode> annotations = new ArrayList<>();
-
-            AST node = importNode.getFirstChild();
-            if (isType(ANNOTATIONS, node)) {
-                processAnnotations(annotations, node);
-                node = node.getNextSibling();
-            }
-
-            ImportNode imp;
-            String alias = null;
-            AST aliasNode = null;
-            if (isType(LITERAL_as, node)) {
-                //import is like "import Foo as Bar"
-                node = node.getFirstChild();
-                aliasNode = node.getNextSibling();
-                alias = identifier(aliasNode);
-            }
-
-            if (node.getNumberOfChildren() == 0) {
-                String name = identifier(node);
-                // import is like  "import Foo"
-                ClassNode type = ClassHelper.make(name);
-                configureAST(type, importNode);
-                addImport(type, name, alias, annotations);
-                imp = last(output.getImports());
-                configureAST(imp, importNode);
-                return;
-            }
-
-            AST packageNode = node.getFirstChild();
-            String packageName = qualifiedName(packageNode);
-            AST nameNode = packageNode.getNextSibling();
-            if (isType(STAR, nameNode)) {
-                if (isStatic) {
-                    // import is like "import static foo.Bar.*"
-                    // packageName is actually a className in this case
-                    ClassNode type = ClassHelper.make(packageName);
-                    configureAST(type, importNode);
-                    addStaticStarImport(type, packageName, annotations);
-                    imp = output.getStaticStarImports().get(packageName);
-                    configureAST(imp, importNode);
-                } else {
-                    // import is like "import foo.*"
-                    addStarImport(packageName, annotations);
-                    imp = last(output.getStarImports());
-                    configureAST(imp, importNode);
-                }
-
-                if (alias != null)
-                    throw new GroovyBugError("imports like 'import foo.* as Bar' are not supported and should be caught by the grammar");
-            } else {
-                String name = identifier(nameNode);
-                if (isStatic) {
-                    // import is like "import static foo.Bar.method"
-                    // packageName is really class name in this case
-                    ClassNode type = ClassHelper.make(packageName);
-                    configureAST(type, importNode);
-                    addStaticImport(type, name, alias, annotations);
-                    imp = output.getStaticImports().get(alias == null ? name : alias);
-                    configureAST(imp, importNode);
-                } else {
-                    // import is like "import foo.Bar"
-                    ClassNode type = ClassHelper.make(packageName + "." + name);
-                    configureAST(type, importNode);
-                    addImport(type, name, alias, annotations);
-                    imp = last(output.getImports());
-                    configureAST(imp, importNode);
-                }
-            }
-        } finally {
-            // we're using node metadata here in order to fix GROOVY-6094
-            // without breaking external APIs
-            Object node = output.getNodeMetaData(ImportNode.class);
-            if (node != null && node != ImportNode.class) {
-                configureAST((ImportNode)node, importNode);
-            }
-            output.removeNodeMetaData(ImportNode.class);
-        }
-    }
-
-    private void processAnnotations(List<AnnotationNode> annotations, AST node) {
-        AST child = node.getFirstChild();
-        while (child != null) {
-            if (isType(ANNOTATION, child))
-                annotations.add(annotation(child));
-            child = child.getNextSibling();
-        }
-    }
-
-    protected void annotationDef(AST classDef) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST node = classDef.getFirstChild();
-        int modifiers = Opcodes.ACC_PUBLIC;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            checkNoInvalidModifier(classDef, "Annotation Definition", modifiers, Opcodes.ACC_SYNCHRONIZED, "synchronized");
-            node = node.getNextSibling();
-        }
-        modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE | Opcodes.ACC_ANNOTATION;
-
-        String name = identifier(node);
-        node = node.getNextSibling();
-        ClassNode superClass = ClassHelper.OBJECT_TYPE;
-
-        GenericsType[] genericsType = null;
-        if (isType(TYPE_PARAMETERS, node)) {
-            genericsType = makeGenericsType(node);
-            node = node.getNextSibling();
-        }
-
-        ClassNode[] interfaces = ClassNode.EMPTY_ARRAY;
-        if (isType(EXTENDS_CLAUSE, node)) {
-            interfaces = interfaces(node);
-            node = node.getNextSibling();
-        }
-
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-        classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, null);
-        classNode.setSyntheticPublic(syntheticPublic);
-        classNode.addAnnotations(annotations);
-        classNode.setGenericsTypes(genericsType);
-        classNode.addInterface(ClassHelper.Annotation_TYPE);
-        configureAST(classNode, classDef);
-
-        assertNodeType(OBJBLOCK, node);
-        objectBlock(node);
-        output.addClass(classNode);
-        classNode = null;
-    }
-
-    protected void interfaceDef(AST classDef) {
-        innerInterfaceDef(classDef);
-        classNode = null;
-    }
-
-    protected void innerInterfaceDef(AST classDef) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST node = classDef.getFirstChild();
-        int modifiers = Opcodes.ACC_PUBLIC;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            checkNoInvalidModifier(classDef, "Interface", modifiers, Opcodes.ACC_SYNCHRONIZED, "synchronized");
-            node = node.getNextSibling();
-        }
-        modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE;
-
-        String name = identifier(node);
-        node = node.getNextSibling();
-        ClassNode superClass = ClassHelper.OBJECT_TYPE;
-
-        GenericsType[] genericsType = null;
-        if (isType(TYPE_PARAMETERS, node)) {
-            genericsType = makeGenericsType(node);
-            node = node.getNextSibling();
-        }
-
-        ClassNode[] interfaces = ClassNode.EMPTY_ARRAY;
-        if (isType(EXTENDS_CLAUSE, node)) {
-            interfaces = interfaces(node);
-            node = node.getNextSibling();
-        }
-
-        ClassNode outerClass = classNode;
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-        if (classNode != null) {
-            name = classNode.getNameWithoutPackage() + "$" + name;
-            String fullName = dot(classNode.getPackageName(), name);
-            classNode = new InnerClassNode(classNode, fullName, modifiers, superClass, interfaces, null);
-        } else {
-            classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, null);
-        }
-        classNode.setSyntheticPublic(syntheticPublic);
-        classNode.addAnnotations(annotations);
-        classNode.setGenericsTypes(genericsType);
-        configureAST(classNode, classDef);
-
-        assertNodeType(OBJBLOCK, node);
-        objectBlock(node);
-        output.addClass(classNode);
-
-        classNode = outerClass;
-    }
-
-    protected void classDef(AST classDef) {
-        innerClassDef(classDef);
-        classNode = null;
-    }
-
-    private ClassNode getClassOrScript(ClassNode node) {
-        if (node != null) return node;
-        return output.getScriptClassDummy();
-    }
-
-    private static int anonymousClassCount(ClassNode node) {
-        int count = 0;
-        for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext();) {
-            InnerClassNode innerClass = it.next();
-            if (innerClass.isAnonymous()) {
-                count += 1;
-            }
-        }
-        return count;
-    }
-
-    protected Expression anonymousInnerClassDef(AST node) {
-        ClassNode oldNode = classNode;
-        ClassNode outerClass = getClassOrScript(oldNode);
-        String innerClassName = outerClass.getName() + "$" + (anonymousClassCount(outerClass) + 1);
-        if (enumConstantBeingDef) {
-            classNode = new EnumConstantClassNode(outerClass, innerClassName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
-        } else {
-            classNode = new InnerClassNode(outerClass, innerClassName, 0, ClassHelper.OBJECT_TYPE);
-        }
-        ((InnerClassNode) classNode).setAnonymous(true);
-        classNode.setEnclosingMethod(methodNode);
-        configureAST(classNode, node);
-
-        assertNodeType(OBJBLOCK, node);
-        objectBlock(node);
-
-        AnonymousInnerClassCarrier ret = new AnonymousInnerClassCarrier();
-        ret.innerClass = classNode;
-        output.addClass(classNode);
-        classNode = oldNode;
-        return ret;
-    }
-
-    protected void innerClassDef(AST classDef) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-
-        if (isType(TRAIT_DEF, classDef)) {
-            annotations.add(new AnnotationNode(ClassHelper.makeCached(Trait.class)));
-        }
-
-        AST node = classDef.getFirstChild();
-        int modifiers = Opcodes.ACC_PUBLIC;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            checkNoInvalidModifier(classDef, "Class", modifiers, Opcodes.ACC_SYNCHRONIZED, "synchronized");
-            node = node.getNextSibling();
-        }
-
-        String name = identifier(node);
-        node = node.getNextSibling();
-
-        GenericsType[] genericsType = null;
-        if (isType(TYPE_PARAMETERS, node)) {
-            genericsType = makeGenericsType(node);
-            node = node.getNextSibling();
-        }
-
-        ClassNode superClass = null;
-        if (isType(EXTENDS_CLAUSE, node)) {
-            superClass = makeTypeWithArguments(node);
-            node = node.getNextSibling();
-        }
-
-        ClassNode[] interfaces = ClassNode.EMPTY_ARRAY;
-        if (isType(IMPLEMENTS_CLAUSE, node)) {
-            interfaces = interfaces(node);
-            node = node.getNextSibling();
-        }
-
-        // TODO read mixins
-        MixinNode[] mixins = {};
-        ClassNode outerClass = classNode;
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-        if (classNode != null) {
-            name = classNode.getNameWithoutPackage() + "$" + name;
-            String fullName = dot(classNode.getPackageName(), name);
-            if (classNode.isInterface()) {
-                modifiers |= Opcodes.ACC_STATIC;
-            }
-            classNode = new InnerClassNode(classNode, fullName, modifiers, superClass, interfaces, mixins);
-        } else {
-            classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, mixins);
-        }
-        classNode.addAnnotations(annotations);
-        classNode.setGenericsTypes(genericsType);
-        classNode.setSyntheticPublic(syntheticPublic);
-        configureAST(classNode, classDef);
-
-        // we put the class already in output to avoid the most inner classes
-        // will be used as first class later in the loader. The first class
-        // there determines what GCL#parseClass for example will return, so we
-        // have here to ensure it won't be the inner class
-        output.addClass(classNode);
-
-        assertNodeType(OBJBLOCK, node);
-        objectBlock(node);
-
-        classNode = outerClass;
-    }
-
-    protected void objectBlock(AST objectBlock) {
-        for (AST node = objectBlock.getFirstChild(); node != null; node = node.getNextSibling()) {
-            int type = node.getType();
-            switch (type) {
-                case OBJBLOCK:
-                    objectBlock(node);
-                    break;
-
-                case ANNOTATION_FIELD_DEF:
-                case METHOD_DEF:
-                    methodDef(node);
-                    break;
-
-                case CTOR_IDENT:
-                    constructorDef(node);
-                    break;
-
-                case VARIABLE_DEF:
-                    fieldDef(node);
-                    break;
-
-                case STATIC_INIT:
-                    staticInit(node);
-                    break;
-
-                case INSTANCE_INIT:
-                    objectInit(node);
-                    break;
-
-                case ENUM_DEF:
-                    enumDef(node);
-                    break;
-
-                case ENUM_CONSTANT_DEF:
-                    enumConstantDef(node);
-                    break;
-
-                case TRAIT_DEF:
-                case CLASS_DEF:
-                    innerClassDef(node);
-                    break;
-
-                case INTERFACE_DEF:
-                    innerInterfaceDef(node);
-                    break;
-
-                default:
-                    unknownAST(node);
-            }
-        }
-    }
-
-    protected void enumDef(AST enumNode) {
-        assertNodeType(ENUM_DEF, enumNode);
-        List<AnnotationNode> annotations = new ArrayList<>();
-
-        AST node = enumNode.getFirstChild();
-        int modifiers = Opcodes.ACC_PUBLIC;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            node = node.getNextSibling();
-        }
-
-        String name = identifier(node);
-        node = node.getNextSibling();
-
-        ClassNode[] interfaces = interfaces(node);
-        node = node.getNextSibling();
-
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-        String enumName = (classNode != null ? name : dot(getPackageName(), name));
-        ClassNode enumClass = EnumHelper.makeEnumNode(enumName, modifiers, interfaces, classNode);
-        enumClass.setSyntheticPublic(syntheticPublic);
-        enumClass.addAnnotations(annotations);
-        configureAST(enumClass, enumNode);
-
-        ClassNode oldNode = classNode;
-        classNode = enumClass;
-        assertNodeType(OBJBLOCK, node);
-        objectBlock(node);
-        classNode = oldNode;
-
-        output.addClass(enumClass);
-    }
-
-    protected void enumConstantDef(AST node) {
-        enumConstantBeingDef = true;
-        assertNodeType(ENUM_CONSTANT_DEF, node);
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST element = node.getFirstChild();
-        if (isType(ANNOTATIONS, element)) {
-            processAnnotations(annotations, element);
-            element = element.getNextSibling();
-        }
-        String identifier = identifier(element);
-        Expression init = null;
-        element = element.getNextSibling();
-
-        if (element != null) {
-            init = expression(element);
-            ClassNode innerClass;
-            if (element.getNextSibling() == null) {
-                innerClass = getAnonymousInnerClassNode(init);
-                if (innerClass != null) {
-                    init = null;
-                }
-            } else {
-                element = element.getNextSibling();
-                Expression next = expression(element);
-                innerClass = getAnonymousInnerClassNode(next);
-            }
-
-            if (innerClass != null) {
-                // we have to handle an enum constant with a class overriding
-                // a method in which case we need to configure the inner class
-                innerClass.setSuperClass(classNode.getPlainNodeReference());
-                innerClass.setModifiers(classNode.getModifiers() | Opcodes.ACC_FINAL);
-                // we use a ClassExpression for transportation to EnumVisitor
-                Expression inner = new ClassExpression(innerClass);
-                if (init == null) {
-                    ListExpression le = new ListExpression();
-                    le.addExpression(inner);
-                    init = le;
-                } else {
-                    if (init instanceof ListExpression) {
-                        ((ListExpression) init).addExpression(inner);
-                    } else {
-                        ListExpression le = new ListExpression();
-                        le.addExpression(init);
-                        le.addExpression(inner);
-                        init = le;
-                    }
-                }
-                // and remove the final modifier from classNode to allow the sub class
-                classNode.setModifiers(classNode.getModifiers() & ~Opcodes.ACC_FINAL);
-            } else if (isType(ELIST, element)) {
-                if (init instanceof ListExpression && !((ListExpression) init).isWrapped()) {
-                    ListExpression le = new ListExpression();
-                    le.addExpression(init);
-                    init = le;
-                }
-            }
-        }
-        FieldNode enumField = EnumHelper.addEnumConstant(classNode, identifier, init);
-        enumField.addAnnotations(annotations);
-        configureAST(enumField, node);
-        enumConstantBeingDef = false;
-    }
-
-    protected void throwsList(AST node, List<ClassNode> list) {
-        String name;
-        if (isType(DOT, node)) {
-            name = qualifiedName(node);
-        } else {
-            name = identifier(node);
-        }
-        ClassNode exception = ClassHelper.make(name);
-        configureAST(exception, node);
-        list.add(exception);
-        AST next = node.getNextSibling();
-        if (next != null) throwsList(next, list);
-    }
-
-    protected void methodDef(AST methodDef) {
-        MethodNode oldNode = methodNode;
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST node = methodDef.getFirstChild();
-
-        GenericsType[] generics = null;
-        if (isType(TYPE_PARAMETERS, node)) {
-            generics = makeGenericsType(node);
-            node = node.getNextSibling();
-        }
-
-        int modifiers = Opcodes.ACC_PUBLIC;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            checkNoInvalidModifier(methodDef, "Method", modifiers, Opcodes.ACC_VOLATILE, "volatile");
-            node = node.getNextSibling();
-        }
-
-        if (isAnInterface()) {
-            modifiers |= Opcodes.ACC_ABSTRACT;
-        }
-
-        ClassNode returnType = null;
-        if (isType(TYPE, node)) {
-            returnType = makeTypeWithArguments(node);
-            node = node.getNextSibling();
-        }
-
-        String name = identifier(node);
-        if (classNode != null && !classNode.isAnnotationDefinition()) {
-            if (classNode.getNameWithoutPackage().equals(name)) {
-                if (isAnInterface()) {
-                    throw new ASTRuntimeException(methodDef, "Constructor not permitted within an interface.");
-                }
-                throw new ASTRuntimeException(methodDef, "Invalid constructor format. Remove '" + returnType.getName() +
-                        "' as the return type if you want a constructor, or use a different name if you want a method.");
-            }
-        }
-        node = node.getNextSibling();
-
-        Parameter[] parameters = Parameter.EMPTY_ARRAY;
-        ClassNode[] exceptions = ClassNode.EMPTY_ARRAY;
-
-        if (classNode == null || !classNode.isAnnotationDefinition()) {
-            assertNodeType(PARAMETERS, node);
-            parameters = parameters(node);
-            if (parameters == null) parameters = Parameter.EMPTY_ARRAY;
-            node = node.getNextSibling();
-
-            if (isType(LITERAL_throws, node)) {
-                AST throwsNode = node.getFirstChild();
-                List<ClassNode> exceptionList = new ArrayList<>();
-                throwsList(throwsNode, exceptionList);
-                exceptions = exceptionList.toArray(exceptions);
-                node = node.getNextSibling();
-            }
-        }
-
-        boolean hasAnnotationDefault = false;
-        Statement code = null;
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-        methodNode = new MethodNode(name, modifiers, returnType, parameters, exceptions, code);
-        if ((modifiers & Opcodes.ACC_ABSTRACT) == 0) {
-            if (node == null) {
-                throw new ASTRuntimeException(methodDef, "You defined a method without a body. Try adding a body, or declare it abstract.");
-            } else {
-                assertNodeType(SLIST, node);
-                code = statementList(node);
-            }
-        } else if (node != null) {
-            if (classNode != null && classNode.isAnnotationDefinition()) {
-                code = statement(node);
-                hasAnnotationDefault = true;
-            } else {
-                throw new ASTRuntimeException(methodDef, "Abstract methods do not define a body.");
-            }
-        }
-        methodNode.setCode(code);
-        methodNode.addAnnotations(annotations);
-        methodNode.setGenericsTypes(generics);
-        methodNode.setAnnotationDefault(hasAnnotationDefault);
-        methodNode.setSyntheticPublic(syntheticPublic);
-        configureAST(methodNode, methodDef);
-
-        if (classNode != null) {
-            classNode.addMethod(methodNode);
-        } else {
-            output.addMethod(methodNode);
-        }
-        methodNode = oldNode;
-    }
-
-    private static void checkNoInvalidModifier(AST node, String nodeType, int modifiers, int modifier, String modifierText) {
-        if ((modifiers & modifier) != 0) {
-            throw new ASTRuntimeException(node, nodeType + " has an incorrect modifier '" + modifierText + "'.");
-        }
-    }
-
-    private boolean isAnInterface() {
-        return classNode != null && (classNode.getModifiers() & Opcodes.ACC_INTERFACE) > 0;
-    }
-
-    protected void staticInit(AST staticInit) {
-        BlockStatement code = (BlockStatement) statementList(staticInit);
-        classNode.addStaticInitializerStatements(code.getStatements(), false);
-    }
-
-    protected void objectInit(AST init) {
-        BlockStatement code = (BlockStatement) statementList(init);
-        classNode.addObjectInitializerStatements(code);
-    }
-
-    protected void constructorDef(AST constructorDef) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST node = constructorDef.getFirstChild();
-        int modifiers = Opcodes.ACC_PUBLIC;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            checkNoInvalidModifier(constructorDef, "Constructor", modifiers, Opcodes.ACC_STATIC, "static");
-            checkNoInvalidModifier(constructorDef, "Constructor", modifiers, Opcodes.ACC_FINAL, "final");
-            checkNoInvalidModifier(constructorDef, "Constructor", modifiers, Opcodes.ACC_ABSTRACT, "abstract");
-            checkNoInvalidModifier(constructorDef, "Constructor", modifiers, Opcodes.ACC_NATIVE, "native");
-            node = node.getNextSibling();
-        }
-
-        assertNodeType(PARAMETERS, node);
-        Parameter[] parameters = parameters(node);
-        if (parameters == null) parameters = Parameter.EMPTY_ARRAY;
-        node = node.getNextSibling();
-
-        ClassNode[] exceptions = ClassNode.EMPTY_ARRAY;
-        if (isType(LITERAL_throws, node)) {
-            AST throwsNode = node.getFirstChild();
-            List<ClassNode> exceptionList = new ArrayList<>();
-            throwsList(throwsNode, exceptionList);
-            exceptions = exceptionList.toArray(exceptions);
-            node = node.getNextSibling();
-        }
-
-        assertNodeType(SLIST, node);
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-        ConstructorNode constructorNode = classNode.addConstructor(modifiers, parameters, exceptions, null);
-        MethodNode oldMethod = methodNode;
-        methodNode = constructorNode;
-        Statement code = statementList(node);
-        methodNode = oldMethod;
-        constructorNode.setCode(code);
-        constructorNode.setSyntheticPublic(syntheticPublic);
-        constructorNode.addAnnotations(annotations);
-        configureAST(constructorNode, constructorDef);
-    }
-
-    protected void fieldDef(AST fieldDef) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-        AST node = fieldDef.getFirstChild();
-
-        int modifiers = 0;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            node = node.getNextSibling();
-        }
-
-        if (classNode.isInterface()) {
-            modifiers |= Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
-            if ((modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) == 0) {
-                modifiers |= Opcodes.ACC_PUBLIC;
-            }
-        }
-
-        ClassNode type = null;
-        if (isType(TYPE, node)) {
-            type = makeTypeWithArguments(node);
-            node = node.getNextSibling();
-        }
-
-        String name = identifier(node);
-        node = node.getNextSibling();
-
-        Expression initialValue = null;
-        if (node != null) {
-            assertNodeType(ASSIGN, node);
-            initialValue = expression(node.getFirstChild());
-        }
-
-        if (classNode.isInterface() && initialValue == null && type != null) {
-            initialValue = getDefaultValueForPrimitive(type);
-        }
-
-        FieldNode fieldNode = new FieldNode(name, modifiers, type, classNode, initialValue);
-        fieldNode.addAnnotations(annotations);
-        configureAST(fieldNode, fieldDef);
-
-        if (!hasVisibility(modifiers)) {
-            // let's set the modifiers on the field
-            int fieldModifiers = 0;
-            int flags = Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_VOLATILE | Opcodes.ACC_FINAL;
-
-            if (!hasVisibility(modifiers)) {
-                modifiers |= Opcodes.ACC_PUBLIC;
-                fieldModifiers |= Opcodes.ACC_PRIVATE;
-            }
-
-            // let's pass along any other modifiers we need
-            fieldModifiers |= (modifiers & flags);
-            fieldNode.setModifiers(fieldModifiers);
-            fieldNode.setSynthetic(true);
-
-            // in the case that there is already a field, we would
-            // like to use that field, instead of the default field
-            // for the property
-            FieldNode storedNode = classNode.getDeclaredField(fieldNode.getName());
-            if (storedNode != null && !classNode.hasProperty(name)) {
-                fieldNode = storedNode;
-                // we remove it here, because addProperty will add it
-                // again and we want to avoid it showing up multiple
-                // times in the fields list.
-                classNode.getFields().remove(storedNode);
-            }
-
-            PropertyNode propertyNode = new PropertyNode(fieldNode, modifiers, null, null);
-            configureAST(propertyNode, fieldDef);
-            classNode.addProperty(propertyNode);
-        } else {
-            fieldNode.setModifiers(modifiers);
-            // if there is a property of that name, then a field of that
-            // name already exists, which means this new field here should
-            // be used instead of the field the property originally has.
-            PropertyNode pn = classNode.getProperty(name);
-            if (pn != null && pn.getField().isSynthetic()) {
-                classNode.getFields().remove(pn.getField());
-                pn.setField(fieldNode);
-            }
-            classNode.addField(fieldNode);
-        }
-    }
-
-    @Deprecated
-    public static Expression getDefaultValueForPrimitive(ClassNode type) {
-        return PrimitiveHelper.getDefaultValueForPrimitive(type);
-    }
-
-    protected ClassNode[] interfaces(AST node) {
-        List<ClassNode> interfaceList = new ArrayList<>();
-        for (AST implementNode = node.getFirstChild(); implementNode != null; implementNode = implementNode.getNextSibling()) {
-            interfaceList.add(makeTypeWithArguments(implementNode));
-        }
-        ClassNode[] interfaces = ClassNode.EMPTY_ARRAY;
-        if (!interfaceList.isEmpty()) {
-            interfaces = new ClassNode[interfaceList.size()];
-            interfaceList.toArray(interfaces);
-        }
-        return interfaces;
-    }
-
-    protected Parameter[] parameters(AST parametersNode) {
-        AST node = parametersNode.getFirstChild();
-        firstParam = false;
-        firstParamIsVarArg = false;
-        if (node == null) {
-            if (isType(IMPLICIT_PARAMETERS, parametersNode)) return Parameter.EMPTY_ARRAY;
-            return null;
-        } else {
-            List<Parameter> parameters = new ArrayList<>();
-            AST firstParameterNode = null;
-            do {
-                firstParam = (firstParameterNode == null);
-                if (firstParameterNode == null) firstParameterNode = node;
-                parameters.add(parameter(node));
-                node = node.getNextSibling();
-            }
-            while (node != null);
-
-            verifyParameters(parameters, firstParameterNode);
-
-            Parameter[] answer = new Parameter[parameters.size()];
-            parameters.toArray(answer);
-            return answer;
-        }
-    }
-
-    private void verifyParameters(List<Parameter> parameters, AST firstParameterNode) {
-        if (parameters.size() <= 1) return;
-
-        Parameter first = parameters.get(0);
-        if (firstParamIsVarArg) {
-            throw new ASTRuntimeException(firstParameterNode, "The var-arg parameter " + first.getName() + " must be the last parameter.");
-        }
-    }
-
-    protected Parameter parameter(AST paramNode) {
-        List<AnnotationNode> annotations = new ArrayList<>();
-        boolean variableParameterDef = isType(VARIABLE_PARAMETER_DEF, paramNode);
-        AST node = paramNode.getFirstChild();
-
-        int modifiers = 0;
-        if (isType(MODIFIERS, node)) {
-            modifiers = modifiers(node, annotations, modifiers);
-            node = node.getNextSibling();
-        }
-
-        ClassNode type = ClassHelper.DYNAMIC_TYPE;
-        if (isType(TYPE, node)) {
-            type = makeTypeWithArguments(node);
-            if (variableParameterDef)
-                type = makeArray(type, node);
-            node = node.getNextSibling();
-        }
-
-        String name = identifier(node);
-        node = node.getNextSibling();
-
-        VariableExpression leftExpression = new VariableExpression(name, type);
-        leftExpression.setModifiers(modifiers);
-        configureAST(leftExpression, paramNode);
-
-        Parameter parameter = null;
-        if (node != null) {
-            assertNodeType(ASSIGN, node);
-            Expression rightExpression = expression(node.getFirstChild());
-            if (isAnInterface()) {
-                throw new ASTRuntimeException(node, "Cannot specify default value for method parameter '" + name + " = " + rightExpression.getText() + "' inside an interface");
-            }
-            parameter = new Parameter(type, name, rightExpression);
-        } else
-            parameter = new Parameter(type, name);
-
-        if (firstParam) firstParamIsVarArg = variableParameterDef;
-
-        configureAST(parameter, paramNode);
-        parameter.addAnnotations(annotations);
-        parameter.setModifiers(modifiers);
-        return parameter;
-    }
-
-    protected int modifiers(AST modifierNode, List<AnnotationNode> annotations, int defaultModifiers) {
-        assertNodeType(MODIFIERS, modifierNode);
-
-        boolean access = false;
-        int answer = 0;
-
-        for (AST node = modifierNode.getFirstChild(); node != null; node = node.getNextSibling()) {
-            int type = node.getType();
-            switch (type) {
-                case STATIC_IMPORT:
-                    // ignore
-                    break;
-
-                // annotations
-                case ANNOTATION:
-                    annotations.add(annotation(node));
-                    break;
-
-                // core access scope modifiers
-                case LITERAL_private:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_PRIVATE);
-                    access = setAccessTrue(node, access);
-                    break;
-
-                case LITERAL_protected:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_PROTECTED);
-                    access = setAccessTrue(node, access);
-                    break;
-
-                case LITERAL_public:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_PUBLIC);
-                    access = setAccessTrue(node, access);
-                    break;
-
-                // other modifiers
-                case ABSTRACT:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_ABSTRACT);
-                    break;
-
-                case FINAL:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_FINAL);
-                    break;
-
-                case LITERAL_native:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_NATIVE);
-                    break;
-
-                case LITERAL_static:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_STATIC);
-                    break;
-
-                case STRICTFP:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_STRICT);
-                    break;
-
-                case LITERAL_synchronized:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_SYNCHRONIZED);
-                    break;
-
-                case LITERAL_transient:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_TRANSIENT);
-                    break;
-
-                case LITERAL_volatile:
-                    answer = setModifierBit(node, answer, Opcodes.ACC_VOLATILE);
-                    break;
-
-                default:
-                    unknownAST(node);
-            }
-        }
-        if (!access) {
-            answer |= defaultModifiers;
-            // ACC_SYNTHETIC isn't used here, use it as a special flag
-            if (defaultModifiers == Opcodes.ACC_PUBLIC) answer |= Opcodes.ACC_SYNTHETIC;
-        }
-        return answer;
-    }
-
-    protected boolean setAccessTrue(AST node, boolean access) {
-        if (!access) {
-            return true;
-        } else {
-            throw new ASTRuntimeException(node, "Cannot specify modifier: " + node.getText() + " when access scope has already been defined");
-        }
-    }
-
-    protected int setModifierBit(AST node, int answer, int bit) {
-        if ((answer & bit) != 0) {
-            throw new ASTRuntimeException(node, "Cannot repeat modifier: " + node.getText());
-        }
-        return answer | bit;
-    }
-
-    protected AnnotationNode annotation(AST annotationNode) {
-        annotationBeingDef = true;
-        AST node = annotationNode.getFirstChild();
-        AnnotationNode annotatedNode = new AnnotationNode(ClassHelper.make(qualifiedName(node)));
-        configureAST(annotatedNode, annotationNode);
-        while (true) {
-            node = node.getNextSibling();
-            if (isType(ANNOTATION_MEMBER_VALUE_PAIR, node)) {
-                AST memberNode = node.getFirstChild();
-                String param = identifier(memberNode);
-                Expression expression = expression(memberNode.getNextSibling());
-                if (annotatedNode.getMember(param) != null) {
-                    throw new ASTRuntimeException(memberNode, "Annotation member '" + param + "' has already been associated with a value");
-                }
-                annotatedNode.setMember(param, expression);
-            } else {
-                break;
-            }
-        }
-        annotationBeingDef = false;
-        return annotatedNode;
-    }
-
-    // Statements
-    //-------------------------------------------------------------------------
-
-    protected Statement statement(AST node) {
-        Statement statement = null;
-        int type = node.getType();
-        switch (type) {
-            case SLIST:
-            case LITERAL_finally:
-                statement = statementList(node);
-                break;
-
-            case METHOD_CALL:
-                statement = methodCall(node);
-                break;
-
-            case VARIABLE_DEF:
-                statement = variableDef(node);
-                break;
-
-            case LABELED_STAT:
-                return labelledStatement(node);
-
-            case LITERAL_assert:
-                statement = assertStatement(node);
-                break;
-
-            case LITERAL_break:
-                statement = breakStatement(node);
-                break;
-
-            case LITERAL_continue:
-                statement = continueStatement(node);
-                break;
-
-            case LITERAL_if:
-                statement = ifStatement(node);
-                break;
-
-            case LITERAL_for:
-                statement = forStatement(node);
-                break;
-
-            case LITERAL_return:
-                statement = returnStatement(node);
-                break;
-
-            case LITERAL_synchronized:
-                statement = synchronizedStatement(node);
-                break;
-
-            case LITERAL_switch:
-                statement = switchStatement(node);
-                break;
-
-            case LITERAL_try:
-                statement = tryStatement(node);
-                break;
-
-            case LITERAL_throw:
-                statement = throwStatement(node);
-                break;
-
-            case LITERAL_while:
-                statement = whileStatement(node);
-                break;
-
-            default:
-                statement = new ExpressionStatement(expression(node));
-        }
-        if (statement != null) {
-            configureAST(statement, node);
-        }
-        return statement;
-    }
-
-    protected Statement statementList(AST code) {
-        BlockStatement block = siblingsToBlockStatement(code.getFirstChild());
-        configureAST(block, code);
-        return block;
-    }
-
-    protected Statement statementListNoChild(AST node, AST alternativeConfigureNode) {
-        BlockStatement block = siblingsToBlockStatement(node);
-        // alternativeConfigureNode is used only to set the source position
-        if (alternativeConfigureNode != null) {
-            configureAST(block, alternativeConfigureNode);
-        } else if (node != null) {
-            configureAST(block, node);
-        }
-        return block;
-    }
-
-    private BlockStatement siblingsToBlockStatement(AST firstSiblingNode) {
-        BlockStatement block = new BlockStatement();
-        for (AST node = firstSiblingNode; node != null; node = node.getNextSibling()) {
-            block.addStatement(statement(node));
-        }
-        return block;
-    }
-
-    protected Statement assertStatement(AST assertNode) {
-        AST node = assertNode.getFirstChild();
-        BooleanExpression booleanExpression = booleanExpression(node);
-        Expression messageExpression = null;
-
-        node = node.getNextSibling();
-        if (node != null) {
-            messageExpression = expression(node);
-        } else {
-            messageExpression = nullX();
-        }
-        AssertStatement assertStatement = new AssertStatement(booleanExpression, messageExpression);
-        configureAST(assertStatement, assertNode);
-        return assertStatement;
-    }
-
-    protected Statement breakStatement(AST node) {
-        BreakStatement breakStatement = new BreakStatement(label(node));
-        configureAST(breakStatement, node);
-        return breakStatement;
-    }
-
-    protected Statement continueStatement(AST node) {
-        ContinueStatement continueStatement = new ContinueStatement(label(node));
-        configureAST(continueStatement, node);
-        return continueStatement;
-    }
-
-    protected Statement forStatement(AST forNode) {
-        AST inNode = forNode.getFirstChild();
-        Expression collectionExpression;
-        Parameter forParameter;
-        if (isType(CLOSURE_LIST, inNode)) {
-            forStatementBeingDef = true;
-            ClosureListExpression clist = closureListExpression(inNode);
-            forStatementBeingDef = false;
-            int size = clist.getExpressions().size();
-            if (size != 3) {
-                throw new ASTRuntimeException(inNode, "3 expressions are required for the classic for loop, you gave " + size);
-            }
-            collectionExpression = clist;
-            forParameter = ForStatement.FOR_LOOP_DUMMY;
-        } else {
-            AST variableNode = inNode.getFirstChild();
-            AST collectionNode = variableNode.getNextSibling();
-
-            ClassNode type = ClassHelper.OBJECT_TYPE;
-            if (isType(VARIABLE_DEF, variableNode)) {
-                AST node = variableNode.getFirstChild();
-                // skip the final modifier if it's present
-                if (isType(MODIFIERS, node)) {
-                    int modifiersMask = modifiers(node, new ArrayList<>(), 0);
-                    // only final modifier allowed
-                    if ((modifiersMask & ~Opcodes.ACC_FINAL) != 0) {
-                        throw new ASTRuntimeException(node, "Only the 'final' modifier is allowed in front of the for loop variable.");
-                    }
-                    node = node.getNextSibling();
-                }
-                type = makeTypeWithArguments(node);
-
-                variableNode = node.getNextSibling();
-            }
-            String variable = identifier(variableNode);
-
-            collectionExpression = expression(collectionNode);
-            forParameter = new Parameter(type, variable);
-            configureAST(forParameter, variableNode);
-        }
-
-        final AST node = inNode.getNextSibling();
-        Statement block;
-        if (isType(SEMI, node)) {
-            block = EmptyStatement.INSTANCE;
-        } else {
-            block = statement(node);
-        }
-        ForStatement forStatement = new ForStatement(forParameter, collectionExpression, block);
-        configureAST(forStatement, forNode);
-        return forStatement;
-    }
-
-    protected Statement ifStatement(AST ifNode) {
-        AST node = ifNode.getFirstChild();
-        assertNodeType(EXPR, node);
-        BooleanExpression booleanExpression = booleanExpression(node);
-
-        node = node.getNextSibling();
-        Statement ifBlock = statement(node);
-
-        Statement elseBlock = EmptyStatement.INSTANCE;
-        node = node.getNextSibling();
-        if (node != null) {
-            elseBlock = statement(node);
-        }
-        IfStatement ifStatement = new IfStatement(booleanExpression, ifBlock, elseBlock);
-        configureAST(ifStatement, ifNode);
-        return ifStatement;
-    }
-
-    protected Statement labelledStatement(AST labelNode) {
-        AST node = labelNode.getFirstChild();
-        String label = identifier(node);
-        Statement statement = statement(node.getNextSibling());
-        statement.addStatementLabel(label);
-        return statement;
-    }
-
-    protected Statement methodCall(AST code) {
-        Expression expression = methodCallExpression(code);
-        ExpressionStatement expressionStatement = new ExpressionStatement(expression);
-        configureAST(expressionStatement, code);
-        return expressionStatement;
-    }
-
-    protected Expression declarationExpression(AST variableDef) {
-        AST node = variableDef.getFirstChild();
-        ClassNode type = null;
-        List<AnnotationNode> annotations = new ArrayList<>();
-        int modifiers = 0;
-        if (isType(MODIFIERS, node)) {
-            // force check of modifier conflicts
-            modifiers = modifiers(node, annotations, 0);
-            node = node.getNextSibling();
-        }
-        if (isType(TYPE, node)) {
-            type = makeTypeWithArguments(node);
-            node = node.getNextSibling();
-        }
-
-        Expression leftExpression;
-        Expression rightExpression = EmptyExpression.INSTANCE;
-        AST right;
-
-        if (isType(ASSIGN, node)) {
-            node = node.getFirstChild();
-            AST left = node.getFirstChild();
-            ArgumentListExpression alist = new ArgumentListExpression();
-            for (AST varDef = left; varDef != null; varDef = varDef.getNextSibling()) {
-                assertNodeType(VARIABLE_DEF, varDef);
-                DeclarationExpression de = (DeclarationExpression) declarationExpression(varDef);
-                alist.addExpression(de.getVariableExpression());
-            }
-            leftExpression = alist;
-            right = node.getNextSibling();
-            if (right != null) rightExpression = expression(right);
-        } else {
-            String name = identifier(node);
-            VariableExpression ve = new VariableExpression(name, type);
-            ve.setModifiers(modifiers);
-            leftExpression = ve;
-
-            right = node.getNextSibling();
-            if (right != null) {
-                assertNodeType(ASSIGN, right);
-                rightExpression = expression(right.getFirstChild());
-            }
-        }
-
-        configureAST(leftExpression, node);
-
-        Token token = makeToken(Types.ASSIGN, variableDef);
-        DeclarationExpression expression = new DeclarationExpression(leftExpression, token, rightExpression);
-        expression.addAnnotations(annotations);
-        configureAST(expression, variableDef);
-        ExpressionStatement expressionStatement = new ExpressionStatement(expression);
-        configureAST(expressionStatement, variableDef);
-        return expression;
-    }
-
-    protected Statement variableDef(AST variableDef) {
-        ExpressionStatement expressionStatement = new ExpressionStatement(declarationExpression(variableDef));
-        configureAST(expressionStatement, variableDef);
-        return expressionStatement;
-    }
-
-    protected Statement returnStatement(AST node) {
-        AST exprNode = node.getFirstChild();
-
-        // This will pick up incorrect sibling node if 'node' is a plain 'return'
-        //
-        //if (exprNode == null) {
-        //    exprNode = node.getNextSibling();
-        //}
-        Expression expression = exprNode == null ? nullX() : expression(exprNode);
-        ReturnStatement returnStatement = new ReturnStatement(expression);
-        configureAST(returnStatement, node);
-        return returnStatement;
-    }
-
-    protected Statement switchStatement(AST switchNode) {
-        AST node = switchNode.getFirstChild();
-        Expression expression = expression(node);
-        Statement defaultStatement = EmptyStatement.INSTANCE;
-
-        List<CaseStatement> caseStatements = new ArrayList<>();
-        for (node = node.getNextSibling(); isType(CASE_GROUP, node); node = node.getNextSibling()) {
-            Statement tmpDefaultStatement;
-            AST child = node.getFirstChild();
-            if (isType(LITERAL_case, child)) {
-                // default statement can be grouped with previous case
-                tmpDefaultStatement = caseStatements(child, caseStatements);
-            } else {
-                tmpDefaultStatement = statement(child.getNextSibling());
-            }
-            if (!(tmpDefaultStatement instanceof EmptyStatement)) {
-                if (defaultStatement instanceof EmptyStatement) {
-                    defaultStatement = tmpDefaultStatement;
-                } else {
-                    throw new ASTRuntimeException(switchNode, "The default case is already defined.");
-                }
-            }
-        }
-        if (node != null) {
-            unknownAST(node);
-        }
-        SwitchStatement switchStatement = new SwitchStatement(expression, caseStatements, defaultStatement);
-        configureAST(switchStatement, switchNode);
-        return switchStatement;
-    }
-
-    protected Statement caseStatements(AST node, List<CaseStatement> cases) {
-        List<Expression> expressions = new ArrayList<>();
-        Statement statement = EmptyStatement.INSTANCE;
-        Statement defaultStatement = EmptyStatement.INSTANCE;
-        AST nextSibling = node;
-        do {
-            Expression expression = expression(nextSibling.getFirstChild());
-            expressions.add(expression);
-            nextSibling = nextSibling.getNextSibling();
-        } while (isType(LITERAL_case, nextSibling));
-        if (nextSibling != null) {
-            if (isType(LITERAL_default, nextSibling)) {
-                defaultStatement = statement(nextSibling.getNextSibling());
-                statement = EmptyStatement.INSTANCE;
-            } else {
-                statement = statement(nextSibling);
-            }
-        }
-        for (Iterator<Expression> iterator = expressions.iterator(); iterator.hasNext(); ) {
-            Expression expr = iterator.next();
-            CaseStatement stmt;
-            if (iterator.hasNext()) {
-                stmt = new CaseStatement(expr, EmptyStatement.INSTANCE);
-            } else {
-                stmt = new CaseStatement(expr, statement);
-            }
-            configureAST(stmt, node);
-            cases.add(stmt);
-        }
-        return defaultStatement;
-    }
-
-    protected Statement synchronizedStatement(AST syncNode) {
-        AST node = syncNode.getFirstChild();
-        Expression expression = expression(node);
-        Statement code = statement(node.getNextSibling());
-        SynchronizedStatement synchronizedStatement = new SynchronizedStatement(expression, code);
-        configureAST(synchronizedStatement, syncNode);
-        return synchronizedStatement;
-    }
-
-    protected Statement throwStatement(AST node) {
-        AST expressionNode = node.getFirstChild();
-        if (expressionNode == null) {
-            expressionNode = node.getNextSibling();
-        }
-        if (expressionNode == null) {
-            throw new ASTRuntimeException(node, "No expression available");
-        }
-        ThrowStatement throwStatement = new ThrowStatement(expression(expressionNode));
-        configureAST(throwStatement, node);
-        return throwStatement;
-    }
-
-    protected Statement tryStatement(AST tryStatementNode) {
-        AST tryNode = tryStatementNode.getFirstChild();
-        Statement tryStatement = statement(tryNode);
-        Statement finallyStatement = EmptyStatement.INSTANCE;
-        AST node = tryNode.getNextSibling();
-
-        // let's do the catch nodes
-        List<CatchStatement> catches = new ArrayList<>();
-        for (; isType(LITERAL_catch, node); node = node.getNextSibling()) {
-            final List<CatchStatement> catchStatements = catchStatement(node);
-            catches.addAll(catchStatements);
-        }
-
-        if (isType(LITERAL_finally, node)) {
-            finallyStatement = statement(node);
-            node = node.getNextSibling();
-        }
-
-        if (finallyStatement instanceof EmptyStatement && catches.isEmpty()) {
-            throw new ASTRuntimeException(tryStatementNode, "A try statement must have at least one catch or finally block.");
-        }
-
-        TryCatchStatement tryCatchStatement = new TryCatchStatement(tryStatement, finallyStatement);
-        configureAST(tryCatchStatement, tryStatementNode);
-        for (CatchStatement statement : catches) {
-            tryCatchStatement.addCatch(statement);
-        }
-        return tryCatchStatement;
-    }
-
-    protected List<CatchStatement> catchStatement(AST catchNode) {
-        AST node = catchNode.getFirstChild();
-        List<CatchStatement> catches = new ArrayList<>();
-        if (MULTICATCH == node.getType()) {
-            AST multicatches = node.getFirstChild();
-            if (multicatches.getType() != MULTICATCH_TYPES) {
-                // catch (e)
-                // catch (def e)
-                String variable = identifier(multicatches);
-                Parameter catchParameter = new Parameter(ClassHelper.DYNAMIC_TYPE, variable);
-                CatchStatement answer = new CatchStatement(catchParameter, statement(node.getNextSibling()));
-                configureAST(answer, catchNode);
-                catches.add(answer);
-            } else {
-                // catch (Exception e)
-                // catch (java.lang.Exception e)
-                // catch (Exception1 | foo.bar.Exception2 e)
-                AST exceptionNodes = multicatches.getFirstChild();
-                String variable = identifier(multicatches.getNextSibling());
-                while (exceptionNodes != null) {
-                    ClassNode exceptionType = buildName(exceptionNodes);
-                    Parameter catchParameter = new Parameter(exceptionType, variable);
-                    CatchStatement answer = new CatchStatement(catchParameter, statement(node.getNextSibling()));
-                    configureAST(answer, catchNode);
-                    catches.add(answer);
-                    exceptionNodes = exceptionNodes.getNextSibling();
-                }
-            }
-        }
-        return catches;
-    }
-
-    protected Statement whileStatement(AST whileNode) {
-        AST node = whileNode.getFirstChild();
-        assertNodeType(EXPR, node);
-        // TODO remove this once we support declarations in the while condition
-        if (isType(VARIABLE_DEF, node.getFirstChild())) {
-            throw new ASTRuntimeException(whileNode,
-                    "While loop condition contains a declaration; this is currently unsupported.");
-        }
-        BooleanExpression booleanExpression = booleanExpression(node);
-
-        node = node.getNextSibling();
-        Statement block;
-        if (isType(SEMI, node)) {
-            block = EmptyStatement.INSTANCE;
-        } else {
-            block = statement(node);
-        }
-        WhileStatement whileStatement = new WhileStatement(booleanExpression, block);
-        configureAST(whileStatement, whileNode);
-        return whileStatement;
-    }
-
-    // Expressions
-    //-------------------------------------------------------------------------
-
-    protected Expression expression(AST node) {
-        return expression(node, false);
-    }
-
-    protected Expression expression(AST node, boolean convertToConstant) {
-        Expression expression = expressionSwitch(node);
-        if (convertToConstant && expression instanceof VariableExpression) {
-            // a method name can never be a VariableExpression, so it must converted
-            // to a ConstantExpression then. This is needed as the expression
-            // method doesn't know we want a ConstantExpression instead of a
-            // VariableExpression
-            VariableExpression ve = (VariableExpression) expression;
-            if (!ve.isThisExpression() && !ve.isSuperExpression()) {
-                expression = new ConstantExpression(ve.getName());
-            }
-        }
-        configureAST(expression, node);
-        return expression;
-    }
-
-    protected Expression expressionSwitch(AST node) {
-        int type = node.getType();
-        switch (type) {
-            case EXPR:
-                Expression expression = expression(node.getFirstChild());
-                return expression;
-
-            case ELIST:
-                return expressionList(node);
-
-            case SLIST:
-                return blockExpression(node);
-
-            case CLOSABLE_BLOCK:
-                return closureExpression(node);
-
-            case SUPER_CTOR_CALL:
-                return specialConstructorCallExpression(node, ClassNode.SUPER);
-
-            case METHOD_CALL:
-                return methodCallExpression(node);
-
-            case LITERAL_new:
-                return constructorCallExpression(node);
-
-            case CTOR_CALL:
-                return specialConstructorCallExpression(node, ClassNode.THIS);
-
-            case QUESTION:
-            case ELVIS_OPERATOR:
-                return ternaryExpression(node);
-
-            case OPTIONAL_DOT:
-            case SPREAD_DOT:
-            case DOT:
-                return dotExpression(node);
-
-            case IDENT:
-            case LITERAL_boolean:
-            case LITERAL_byte:
-            case LITERAL_char:
-            case LITERAL_double:
-            case LITERAL_float:
-            case LITERAL_int:
-            case LITERAL_long:
-            case LITERAL_short:
-            case LITERAL_void:
-            case LITERAL_this:
-            case LITERAL_super:
-                return variableExpression(node);
-
-            case LIST_CONSTRUCTOR:
-                return listExpression(node);
-
-            case MAP_CONSTRUCTOR:
-                return mapExpression(node);
-
-            case LABELED_ARG:
-                return mapEntryExpression(node);
-
-            case SPREAD_ARG:
-                return spreadExpression(node);
-
-            case SPREAD_MAP_ARG:
-                return spreadMapExpression(node);
-
-            case MEMBER_POINTER:
-                return methodPointerExpression(node);
-
-            case INDEX_OP:
-                return indexExpression(node);
-
-            case LITERAL_instanceof:
-                return instanceofExpression(node);
-
-            case LITERAL_as:
-                return asExpression(node);
-
-            case TYPECAST:
-                return castExpression(node);
-
-            case LITERAL_true:
-                return literalExpression(node, Boolean.TRUE);
-
-            case LITERAL_false:
-                return literalExpression(node, Boolean.FALSE);
-
-            case LITERAL_null:
-                return literalExpression(node, null);
-
-            case STRING_LITERAL:
-                return literalExpression(node, node.getText());
-
-            case STRING_CONSTRUCTOR:
-                return gstring(node);
-
-            case NUM_DOUBLE:
-            case NUM_FLOAT:
-            case NUM_BIG_DECIMAL:
-                return decimalExpression(node);
-
-            case NUM_BIG_INT:
-            case NUM_INT:
-            case NUM_LONG:
-                return integerExpression(node);
-
-            // Unary expressions
-            case LNOT:
-                NotExpression notExpression = new NotExpression(expression(node.getFirstChild()));
-                configureAST(notExpression, node);
-                return notExpression;
-
-            case UNARY_MINUS:
-                return unaryMinusExpression(node);
-
-            case BNOT:
-                BitwiseNegationExpression bitwiseNegationExpression = new BitwiseNegationExpression(expression(node.getFirstChild()));
-                configureAST(bitwiseNegationExpression, node);
-                return bitwiseNegationExpression;
-
-            case UNARY_PLUS:
-                return unaryPlusExpression(node);
-
-            case INC:
-                return prefixExpression(node, Types.PLUS_PLUS);
-
-            case DEC:
-                return prefixExpression(node, Types.MINUS_MINUS);
-
-            case POST_INC:
-                return postfixExpression(node, Types.PLUS_PLUS);
-
-            case POST_DEC:
-                return postfixExpression(node, Types.MINUS_MINUS);
-
-            // Binary expressions
-            case ASSIGN:
-                return binaryExpression(Types.ASSIGN, node);
-
-            case EQUAL:
-                return binaryExpression(Types.COMPARE_EQUAL, node);
-
-            case IDENTICAL:
-                return binaryExpression(Types.COMPARE_IDENTICAL, node);
-
-            case NOT_EQUAL:
-                return binaryExpression(Types.COMPARE_NOT_EQUAL, node);
-
-            case NOT_IDENTICAL:
-                return binaryExpression(Types.COMPARE_NOT_IDENTICAL, node);
-
-            case COMPARE_TO:
-                return binaryExpression(Types.COMPARE_TO, node);
-
-            case LE:
-                return binaryExpression(Types.COMPARE_LESS_THAN_EQUAL, node);
-
-            case LT:
-                return binaryExpression(Types.COMPARE_LESS_THAN, node);
-
-            case GT:
-                return binaryExpression(Types.COMPARE_GREATER_THAN, node);
-
-            case GE:
-                return binaryExpression(Types.COMPARE_GREATER_THAN_EQUAL, node);
-
-            case LAND:
-                return binaryExpression(Types.LOGICAL_AND, node);
-
-            case LOR:
-                return binaryExpression(Types.LOGICAL_OR, node);
-
-            case BAND:
-                return binaryExpression(Types.BITWISE_AND, node);
-
-            case BAND_ASSIGN:
-                return binaryExpression(Types.BITWISE_AND_EQUAL, node);
-
-            case BOR:
-                return binaryExpression(Types.BITWISE_OR, node);
-
-            case BOR_ASSIGN:
-                return binaryExpression(Types.BITWISE_OR_EQUAL, node);
-
-            case BXOR:
-                return binaryExpression(Types.BITWISE_XOR, node);
-
-            case BXOR_ASSIGN:
-                return binaryExpression(Types.BITWISE_XOR_EQUAL, node);
-
-            case PLUS:
-                return binaryExpression(Types.PLUS, node);
-
-            case PLUS_ASSIGN:
-                return binaryExpression(Types.PLUS_EQUAL, node);
-
-            case MINUS:
-                return binaryExpression(Types.MINUS, node);
-
-            case MINUS_ASSIGN:
-                return binaryExpression(Types.MINUS_EQUAL, node);
-
-            case STAR:
-                return binaryExpression(Types.MULTIPLY, node);
-
-            case STAR_ASSIGN:
-                return binaryExpression(Types.MULTIPLY_EQUAL, node);
-
-            case STAR_STAR:
-                return binaryExpression(Types.POWER, node);
-
-            case STAR_STAR_ASSIGN:
-                return binaryExpression(Types.POWER_EQUAL, node);
-
-            case DIV:
-                return binaryExpression(Types.DIVIDE, node);
-
-            case DIV_ASSIGN:
-                return binaryExpression(Types.DIVIDE_EQUAL, node);
-
-            case MOD:
-                return binaryExpression(Types.MOD, node);
-
-            case MOD_ASSIGN:
-                return binaryExpression(Types.MOD_EQUAL, node);
-
-            case SL:
-                return binaryExpression(Types.LEFT_SHIFT, node);
-
-            case SL_ASSIGN:
-                return binaryExpression(Types.LEFT_SHIFT_EQUAL, node);
-
-            case SR:
-                return binaryExpression(Types.RIGHT_SHIFT, node);
-
-            case SR_ASSIGN:
-                return binaryExpression(Types.RIGHT_SHIFT_EQUAL, node);
-
-            case BSR:
-                return binaryExpression(Types.RIGHT_SHIFT_UNSIGNED, node);
-
-            case BSR_ASSIGN:
-                return binaryExpression(Types.RIGHT_SHIFT_UNSIGNED_EQUAL, node);
-
-            case VARIABLE_DEF:
-                return declarationExpression(node);
-
-            // Regex
-            case REGEX_FIND:
-                return binaryExpression(Types.FIND_REGEX, node);
-
-            case REGEX_MATCH:
-                return binaryExpression(Types.MATCH_REGEX, node);
-
-            // Ranges
-            case RANGE_INCLUSIVE:
-                return rangeExpression(node, true);
-
-            case RANGE_EXCLUSIVE:
-                return rangeExpression(node, false);
-
-            case DYNAMIC_MEMBER:
-                return dynamicMemberExpression(node);
-
-            case LITERAL_in:
-                return binaryExpression(Types.KEYWORD_IN, node);
-
-            case ANNOTATION:
-                expression = new AnnotationConstantExpression(annotation(node));
-                configureAST(expression, node);
-                return expression;
-
-            case CLOSURE_LIST:
-                return closureListExpression(node);
-
-            case LBRACK:
-            case LPAREN:
-                return tupleExpression(node);
-
-            case OBJBLOCK:
-                return anonymousInnerClassDef(node);
-
-            default:
-                unknownAST(node);
-        }
-        return null;
-    }
-
-    private TupleExpression tupleExpression(AST node) {
-        TupleExpression exp = new TupleExpression();
-        configureAST(exp, node);
-        node = node.getFirstChild();
-        while (node != null) {
-            assertNodeType(VARIABLE_DEF, node);
-            AST nameNode = node.getFirstChild().getNextSibling();
-            VariableExpression varExp = new VariableExpression(nameNode.getText());
-            configureAST(varExp, nameNode);
-            exp.addExpression(varExp);
-            node = node.getNextSibling();
-        }
-        return exp;
-    }
-
-    private ClosureListExpression closureListExpression(AST node) {
-        isClosureListExpressionAllowedHere(node);
-        AST exprNode = node.getFirstChild();
-        List<Expression> list = new ArrayList<>();
-        while (exprNode != null) {
-            if (isType(EXPR, exprNode)) {
-                Expression expr = expression(exprNode);
-                configureAST(expr, exprNode);
-                list.add(expr);
-            } else {
-                assertNodeType(EMPTY_STAT, exprNode);
-                list.add(EmptyExpression.INSTANCE);
-            }
-
-            exprNode = exprNode.getNextSibling();
-        }
-        ClosureListExpression cle = new ClosureListExpression(list);
-        configureAST(cle, node);
-        return cle;
-    }
-
-    private void isClosureListExpressionAllowedHere(AST node) {
-        if (!forStatementBeingDef) {
-            throw new ASTRuntimeException(node,
-                    "Expression list of the form (a; b; c) is not supported in this context.");
-        }
-    }
-
-    protected Expression dynamicMemberExpression(AST dynamicMemberNode) {
-        AST node = dynamicMemberNode.getFirstChild();
-        return expression(node);
-    }
-
-    protected Expression ternaryExpression(AST ternaryNode) {
-        AST node = ternaryNode.getFirstChild();
-        Expression base = expression(node);
-        node = node.getNextSibling();
-        Expression left = expression(node);
-        node = node.getNextSibling();
-        Expression ret;
-        if (node == null) {
-            ret = new ElvisOperatorExpression(base, left);
-        } else {
-            Expression right = expression(node);
-            BooleanExpression booleanExpression = new BooleanExpression(base);
-            booleanExpression.setSourcePosition(base);
-            ret = new TernaryExpression(booleanExpression, left, right);
-        }
-        configureAST(ret, ternaryNode);
-        return ret;
-    }
-
-    protected Expression variableExpression(AST node) {
-        String text = node.getText();
-
-        // TODO we might wanna only try to resolve the name if we are
-        // on the left hand side of an expression or before a dot?
-        VariableExpression variableExpression = new VariableExpression(text);
-        configureAST(variableExpression, node);
-        return variableExpression;
-    }
-
-    protected ConstantExpression literalExpression(AST node, Object value) {
-        ConstantExpression constantExpression = new ConstantExpression(value, value instanceof Boolean);
-        configureAST(constantExpression, node);
-        return constantExpression;
-    }
-
-    protected Expression rangeExpression(AST rangeNode, boolean inclusive) {
-        AST node = rangeNode.getFirstChild();
-        Expression left = expression(node);
-        Expression right = expression(node.getNextSibling());
-        RangeExpression rangeExpression = new RangeExpression(left, right, inclusive);
-        configureAST(rangeExpression, rangeNode);
-        return rangeExpression;
-    }
-
-    protected Expression spreadExpression(AST node) {
-        AST exprNode = node.getFirstChild();
-        AST listNode = exprNode.getFirstChild();
-        Expression right = expression(listNode);
-        SpreadExpression spreadExpression = new SpreadExpression(right);
-        configureAST(spreadExpression, node);
-        return spreadExpression;
-    }
-
-    protected Expression spreadMapExpression(AST node) {
-        AST exprNode = node.getFirstChild();
-        Expression expr = expression(exprNode);
-        SpreadMapExpression spreadMapExpression = new SpreadMapExpression(expr);
-        configureAST(spreadMapExpression, node);
-        return spreadMapExpression;
-    }
-
-    protected Expression methodPointerExpression(AST node) {
-        AST exprNode = node.getFirstChild();
-        Expression objectExpression = expression(exprNode);
-        AST mNode = exprNode.getNextSibling();
-        Expression methodName;
-        if (isType(DYNAMIC_MEMBER, mNode)) {
-            methodName = expression(mNode);
-        } else {
-            methodName = new ConstantExpression(identifier(mNode));
-        }
-        configureAST(methodName, mNode);
-        MethodPointerExpression methodPointerExpression = new MethodPointerExpression(objectExpression, methodName);
-        configureAST(methodPointerExpression, node);
-        return methodPointerExpression;
-    }
-
-    protected Expression listExpression(AST listNode) {
-        List<Expression> expressions = new ArrayList<>();
-        AST elist = listNode.getFirstChild();
-        assertNodeType(ELIST, elist);
-
-        for (AST node = elist.getFirstChild(); node != null; node = node.getNextSibling()) {
-            // check for stray labeled arguments:
-            switch (node.getType()) {
-                case LABELED_ARG:
-                    assertNodeType(COMMA, node);
-                    break;  // helpful error?
-                case SPREAD_MAP_ARG:
-                    assertNodeType(SPREAD_ARG, node);
-                    break;  // helpful error
-            }
-            expressions.add(expression(node));
-        }
-        ListExpression listExpression = new ListExpression(expressions);
-        configureAST(listExpression, listNode);
-        return listExpression;
-    }
-
-    protected Expression mapExpression(AST mapNode) {
-        List<MapEntryExpression> entryExpressions = new ArrayList<>();
-        AST elist = mapNode.getFirstChild();
-        if (elist != null) {  // totally empty in the case of [:]
-            assertNodeType(ELIST, elist);
-            for (AST node = elist.getFirstChild(); node != null; node = node.getNextSibling()) {
-                switch (node.getType()) {
-                    case LABELED_ARG:
-                    case SPREAD_MAP_ARG:
-                        break;  // legal cases
-                    case SPREAD_ARG:
-                        assertNodeType(SPREAD_MAP_ARG, node);
-                        break;
-                    default:
-                        assertNodeType(LABELED_ARG, node);
-                        break;
-                }
-                entryExpressions.add(mapEntryExpression(node));
-            }
-        }
-        MapExpression mapExpression = new MapExpression(entryExpressions);
-        configureAST(mapExpression, mapNode);
-        return mapExpression;
-    }
-
-    protected MapEntryExpression mapEntryExpression(AST node) {
-        if (node.getType() == SPREAD_MAP_ARG) {
-            AST rightNode = node.getFirstChild();
-            Expression keyExpression = spreadMapExpression(node);
-            Expression rightExpression = expression(rightNode);
-            MapEntryExpression mapEntryExpression = new MapEntryExpression(keyExpression, rightExpression);
-            configureAST(mapEntryExpression, node);
-            return mapEntryExpression;
-        } else {
-            AST keyNode = node.getFirstChild();
-            Expression keyExpression = expression(keyNode);
-            AST valueNode = keyNode.getNextSibling();
-            Expression valueExpression = expression(valueNode);
-            MapEntryExpression mapEntryExpression = new MapEntryExpression(keyExpression, valueExpression);
-            configureAST(mapEntryExpression, node);
-            return mapEntryExpression;
-        }
-    }
-
-    protected Expression instanceofExpression(AST node) {
-        AST leftNode = node.getFirstChild();
-        Expression leftExpression = expression(leftNode);
-
-        AST rightNode = leftNode.getNextSibling();
-        ClassNode type = buildName(rightNode);
-        assertTypeNotNull(type, rightNode);
-
-        Expression rightExpression = new ClassExpression(type);
-        configureAST(rightExpression, rightNode);
-        BinaryExpression binaryExpression = new BinaryExpression(leftExpression, makeToken(Types.KEYWORD_INSTANCEOF, node), rightExpression);
-        configureAST(binaryExpression, node);
-        return binaryExpression;
-    }
-
-    protected void assertTypeNotNull(ClassNode type, AST rightNode) {
-        if (type == null) {
-            throw new ASTRuntimeException(rightNode, "No type available for: " + qualifiedName(rightNode));
-        }
-    }
-
-    protected Expression asExpression(AST node) {
-        AST leftNode = node.getFirstChild();
-        Expression leftExpression = expression(leftNode);
-
-        AST rightNode = leftNode.getNextSibling();
-        ClassNode type = makeTypeWithArguments(rightNode);
-
-        CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
-        configureAST(asExpression, node);
-        return asExpression;
-    }
-
-    protected Expression castExpression(AST castNode) {
-        AST node = castNode.getFirstChild();
-        ClassNode type = makeTypeWithArguments(node);
-        assertTypeNotNull(type, node);
-
-        AST expressionNode = node.getNextSibling();
-        Expression expression = expression(expressionNode);
-
-        CastExpression castExpression = new CastExpression(type, expression);
-        configureAST(castExpression, castNode);
-        return castExpression;
-    }
-
-    protected Expression indexExpression(AST indexNode) {
-        AST bracket = indexNode.getFirstChild();
-        AST leftNode = bracket.getNextSibling();
-        Expression leftExpression = expression(leftNode);
-
-        AST rightNode = leftNode.getNextSibling();
-        Expression rightExpression = expression(rightNode);
-        // easier to massage here than in the grammar
-        if (rightExpression instanceof SpreadExpression) {
-            ListExpression wrapped = new ListExpression();
-            wrapped.addExpression(rightExpression);
-            rightExpression = wrapped;
-        }
-
-        BinaryExpression binaryExpression = new BinaryExpression(leftExpression, makeToken(Types.LEFT_SQUARE_BRACKET, bracket), rightExpression);
-        configureAST(binaryExpression, indexNode);
-        return binaryExpression;
-    }
-
-    protected Expression binaryExpression(int type, AST node) {
-        Token token = makeToken(type, node);
-
-        AST leftNode = node.getFirstChild();
-        Expression leftExpression = expression(leftNode);
-
-        AST rightNode = leftNode.getNextSibling();
-        if (rightNode == null) {
-            return leftExpression;
-        }
-
-        if (Types.ofType(type, Types.ASSIGNMENT_OPERATOR)) {
-            if (leftExpression instanceof VariableExpression ||
-                    leftExpression.getClass() == PropertyExpression.class ||
-                    leftExpression instanceof FieldExpression ||
-                    leftExpression instanceof AttributeExpression ||
-                    leftExpression instanceof DeclarationExpression ||
-                    leftExpression instanceof TupleExpression) {
-                // Do nothing.
-            } else if (leftExpression instanceof ConstantExpression) {
-                throw new ASTRuntimeException(node, "\n[" + ((ConstantExpression) leftExpression).getValue() + "] is a constant expression, but it should be a variable expression");
-            } else if (leftExpression instanceof BinaryExpression) {
-                int lefttype = ((BinaryExpression) leftExpression).getOperation().getType();
-                if (!Types.ofType(lefttype, Types.ASSIGNMENT_OPERATOR) && lefttype != Types.LEFT_SQUARE_BRACKET) {
-                    throw new ASTRuntimeException(node, "\n" + leftExpression.getText() + " is a binary expression, but it should be a variable expression");
-                }
-            } else if (leftExpression instanceof GStringExpression) {
-                throw new ASTRuntimeException(node, "\n\"" + leftExpression.getText() + "\" is a GString expression, but it should be a variable expression");
-            } else if (leftExpression instanceof MethodCallExpression) {
-                throw new ASTRuntimeException(node, "\n\"" + leftExpression.getText() + "\" is a method call expression, but it should be a variable expression");
-            } else if (leftExpression instanceof MapExpression) {
-                throw new ASTRuntimeException(node, "\n'" + leftExpression.getText() + "' is a map expression, but it should be a variable expression");
-            } else {
-                throw new ASTRuntimeException(node, "\n" + leftExpression.getClass() + ", with its value '" + leftExpression.getText() + "', is a bad expression as the left hand side of an assignment operator");
-            }
-        }
-        /*if (rightNode == null) {
-            throw new NullPointerException("No rightNode associated with binary expression");
-        }*/
-        Expression rightExpression = expression(rightNode);
-        BinaryExpression binaryExpression = new BinaryExpression(leftExpression, token, rightExpression);
-        configureAST(binaryExpression, node);
-        return binaryExpression;
-    }
-
-    protected Expression prefixExpression(AST node, int token) {
-        Expression expression = expression(node.getFirstChild());
-        PrefixExpression prefixExpression = new PrefixExpression(makeToken(token, node), expression);
-        configureAST(prefixExpression, node);
-        return prefixExpression;
-    }
-
-    protected Expression postfixExpression(AST node, int token) {
-        Expression expression = expression(node.getFirstChild());
-        PostfixExpression postfixExpression = new PostfixExpression(expression, makeToken(token, node));
-        configureAST(postfixExpression, node);
-        return postfixExpression;
-    }
-
-    protected BooleanExpression booleanExpression(AST node) {
-        BooleanExpression booleanExpression = new BooleanExpression(expression(node));
-        configureAST(booleanExpression, node);
-        return booleanExpression;
-    }
-
-    protected Expression dotExpression(AST node) {
-        // let's decide if this is a property invocation or a method call
-        AST leftNode = node.getFirstChild();
-        if (leftNode != null) {
-            AST identifierNode = leftNode.getNextSibling();
-            if (identifierNode != null) {
-                Expression leftExpression = expression(leftNode);
-                if (isType(SELECT_SLOT, identifierNode)) {
-                    Expression field = expression(identifierNode.getFirstChild(), true);
-                    AttributeExpression attributeExpression = new AttributeExpression(leftExpression, field, node.getType() != DOT);
-                    if (node.getType() == SPREAD_DOT) {
-                        attributeExpression.setSpreadSafe(true);
-                    }
-                    configureAST(attributeExpression, node);
-                    return attributeExpression;
-                }
-                if (isType(SLIST, identifierNode)) {
-                    Statement code = statementList(identifierNode);
-                    ClosureExpression closureExpression = new ClosureExpression(Parameter.EMPTY_ARRAY, code);
-                    configureAST(closureExpression, identifierNode);
-                    final PropertyExpression propertyExpression = new PropertyExpression(leftExpression, closureExpression);
-                    if (node.getType() == SPREAD_DOT) {
-                        propertyExpression.setSpreadSafe(true);
-                    }
-                    configureAST(propertyExpression, node);
-                    return propertyExpression;
-                }
-                Expression property = expression(identifierNode, true);
-
-
-                // A."this" assumes a VariableExpression can be used for "this"
-                // we correct that here into a ConstantExpression
-                if (property instanceof VariableExpression) {
-                    VariableExpression ve = (VariableExpression) property;
-                    property = new ConstantExpression(ve.getName());
-                    property.setSourcePosition(ve);
-                }
-
-                PropertyExpression propertyExpression = new PropertyExpression(leftExpression, property, node.getType() != DOT);
-                if (node.getType() == SPREAD_DOT) {
-                    propertyExpression.setSpreadSafe(true);
-                }
-                configureAST(propertyExpression, node);
-                return propertyExpression;
-            }
-        }
-        return methodCallExpression(node);
-    }
-
-    protected Expression specialConstructorCallExpression(AST methodCallNode, ClassNode special) {
-        AST node = methodCallNode.getFirstChild();
-        Expression arguments = arguments(node);
-
-        ConstructorCallExpression expression = new ConstructorCallExpression(special, arguments);
-        configureAST(expression, methodCallNode);
-        return expression;
-    }
-
-    protected Expression methodCallExpression(AST methodCallNode) {
-        AST node = methodCallNode.getFirstChild();
-        Expression objectExpression;
-        AST selector;
-        AST elist = node.getNextSibling();
-        List<GenericsType> typeArgumentList = null;
-
-        boolean implicitThis = false;
-        boolean safe = isType(OPTIONAL_DOT, node);
-        boolean spreadSafe = isType(SPREAD_DOT, node);
-        if (isType(DOT, node) || safe || spreadSafe) {
-            AST objectNode = node.getFirstChild();
-            objectExpression = expression(objectNode);
-            selector = objectNode.getNextSibling();
-        } else {
-            implicitThis = true;
-            objectExpression = VariableExpression.THIS_EXPRESSION;
-            selector = node;
-        }
-
-        if (isType(TYPE_ARGUMENTS, selector)) {
-            typeArgumentList = getTypeArgumentsList(selector);
-            selector = selector.getNextSibling();
-        }
-
-        Expression name = null;
-        if (isType(LITERAL_super, selector)) {
-            implicitThis = true;
-            name = new ConstantExpression("super");
-            if (objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).isThisExpression()) {
-                objectExpression = VariableExpression.SUPER_EXPRESSION;
-            }
-        } else if (isPrimitiveTypeLiteral(selector)) {
-            throw new ASTRuntimeException(selector, "Primitive type literal: " + selector.getText() + " cannot be used as a method name");
-        } else if (isType(SELECT_SLOT, selector)) {
-            Expression field = expression(selector.getFirstChild(), true);
-            AttributeExpression attributeExpression = new AttributeExpression(objectExpression, field, node.getType() != DOT);
-            configureAST(attributeExpression, node);
-            Expression arguments = arguments(elist);
-            MethodCallExpression expression = new MethodCallExpression(attributeExpression, "call", arguments);
-            setTypeArgumentsOnMethodCallExpression(expression, typeArgumentList);
-            configureAST(expression, methodCallNode);
-            return expression;
-        } else if (!implicitThis || isType(DYNAMIC_MEMBER, selector) || isType(IDENT, selector) ||
-                isType(STRING_CONSTRUCTOR, selector) || isType(STRING_LITERAL, selector)) {
-            name = expression(selector, true);
-        } else {
-            implicitThis = false;
-            name = new ConstantExpression("call");
-            objectExpression = expression(selector, true);
-        }
-
-        // if node text is found to be "super"/"this" when a method call is being processed, it is a
-        // call like this(..)/super(..) after the first statement, which shouldn't be allowed. GROOVY-2836
-        if (selector.getText().equals("this") || selector.getText().equals("super")) {
-            if (!(annotationBeingDef && selector.getText().equals("super"))) {
-                throw new ASTRuntimeException(elist, "Constructor call must be the first statement in a constructor.");
-            }
-        }
-
-        Expression arguments = arguments(elist);
-        MethodCallExpression expression = new MethodCallExpression(objectExpression, name, arguments);
-        expression.setSafe(safe);
-        expression.setSpreadSafe(spreadSafe);
-        expression.setImplicitThis(implicitThis);
-        setTypeArgumentsOnMethodCallExpression(expression, typeArgumentList);
-        Expression ret = expression;
-        //FIXME: do we really want this() to create a new object regardless
-        // the position.. for example not as first statement in a constructor
-        // this=first statement in constructor is handled by specialConstructorCallExpression
-        // we may have to add a check and remove this part of the code
-        if (implicitThis && "this".equals(expression.getMethodAsString())) {
-            ret = new ConstructorCallExpression(this.classNode, arguments);
-        }
-        configureAST(ret, methodCallNode);
-        return ret;
-    }
-
-    private static void setTypeArgumentsOnMethodCallExpression(MethodCallExpression expression,
-                                                        List<GenericsType> typeArgumentList) {
-        if (typeArgumentList != null && !typeArgumentList.isEmpty()) {
-            expression.setGenericsTypes(typeArgumentList.toArray(GenericsType.EMPTY_ARRAY));
-        }
-    }
-
-    protected Expression constructorCallExpression(AST node) {
-        AST constructorCallNode = node;
-        ClassNode type = makeTypeWithArguments(constructorCallNode);
-
-        if (isType(CTOR_CALL, node) || isType(LITERAL_new, node)) {
-            node = node.getFirstChild();
-        }
-
-        AST elist = node.getNextSibling();
-
-        if (elist == null && isType(ELIST, node)) {
-            elist = node;
-            if ("(".equals(type.getName())) {
-                type = classNode;
-            }
-        }
-
-        if (isType(ARRAY_DECLARATOR, elist)) {
-            AST expressionNode = elist.getFirstChild();
-            if (expressionNode == null) {
-                throw new ASTRuntimeException(elist, "No expression for the array constructor call");
-            }
-            List<Expression> size = arraySizeExpression(expressionNode);
-            ArrayExpression arrayExpression = new ArrayExpression(type, null, size);
-            configureAST(arrayExpression, constructorCallNode);
-            return arrayExpression;
-        }
-        Expression arguments = arguments(elist);
-        ClassNode innerClass = getAnonymousInnerClassNode(arguments);
-        ConstructorCallExpression ret = new ConstructorCallExpression(type, arguments);
-        if (innerClass != null) {
-            ret.setType(innerClass);
-            ret.setUsingAnonymousInnerClass(true);
-            innerClass.setUnresolvedSuperClass(type);
-        }
-
-        configureAST(ret, constructorCallNode);
-        return ret;
-    }
-
-    private static ClassNode getAnonymousInnerClassNode(Expression arguments) {
-        if (arguments instanceof TupleExpression) {
-            TupleExpression te = (TupleExpression) arguments;
-            List<Expression> expressions = te.getExpressions();
-            if (expressions.isEmpty()) return null;
-            Expression last = expressions.remove(expressions.size() - 1);
-            if (last instanceof AnonymousInnerClassCarrier) {
-                AnonymousInnerClassCarrier carrier = (AnonymousInnerClassCarrier) last;
-                return carrier.innerClass;
-            } else {
-                expressions.add(last);
-            }
-        } else if (arguments instanceof AnonymousInnerClassCarrier) {
-            AnonymousInnerClassCarrier carrier = (AnonymousInnerClassCarrier) arguments;
-            return carrier.innerClass;
-        }
-        return null;
-    }
-
-    protected List<Expression> arraySizeExpression(AST node) {
-        List<Expression> list;
-        Expression size = null;
-        if (isType(ARRAY_DECLARATOR, node)) {
-            AST right = node.getNextSibling();
-            if (right != null) {
-                size = expression(right);
-            } else {
-                size = ConstantExpression.EMPTY_EXPRESSION;
-            }
-            AST child = node.getFirstChild();
-            if (child == null) {
-                throw new ASTRuntimeException(node, "No expression for the array constructor call");
-            }
-            list = arraySizeExpression(child);
-        } else {
-            size = expression(node);
-            list = new ArrayList<>();
-        }
-        list.add(size);
-        return list;
-    }
-
-    protected Expression enumArguments(AST elist) {
-        List<Expression> expressionList = new ArrayList<>();
-        for (AST node = elist; node != null; node = node.getNextSibling()) {
-            Expression expression = expression(node);
-            expressionList.add(expression);
-        }
-        ArgumentListExpression argumentListExpression = new ArgumentListExpression(expressionList);
-        configureAST(argumentListExpression, elist);
-        return argumentListExpression;
-    }
-
-    protected Expression arguments(AST elist) {
-        List expressionList = new ArrayList<>();
-        // FIXME: all labeled arguments should follow any unlabeled arguments
-        boolean namedArguments = false;
-        for (AST node = elist; node != null; node = node.getNextSibling()) {
-            if (isType(ELIST, node)) {
-                for (AST child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
-                    namedArguments |= addArgumentExpression(child, expressionList);
-                }
-            } else {
-                namedArguments |= addArgumentExpression(node, expressionList);
-            }
-        }
-        if (namedArguments) {
-            if (!expressionList.isEmpty()) {
-                // let's remove any non-MapEntryExpression instances
-                // such as if the last expression is a ClosureExpression
-                // so let's wrap the named method calls in a Map expression
-                List<Expression> argumentList = new ArrayList<>();
-                for (Object next : expressionList) {
-                    Expression expression = (Expression) next;
-                    if (!(expression instanceof MapEntryExpression)) {
-                        argumentList.add(expression);
-                    }
-                }
-                if (!argumentList.isEmpty()) {
-                    expressionList.removeAll(argumentList);
-                    checkDuplicateNamedParams(elist, expressionList);
-                    MapExpression mapExpression = new MapExpression(expressionList);
-                    configureAST(mapExpression, elist);
-                    argumentList.add(0, mapExpression);
-                    ArgumentListExpression argumentListExpression = new ArgumentListExpression(argumentList);
-                    configureAST(argumentListExpression, elist);
-                    return argumentListExpression;
-                }
-            }
-            checkDuplicateNamedParams(elist, expressionList);
-            NamedArgumentListExpression namedArgumentListExpression = new NamedArgumentListExpression(expressionList);
-            configureAST(namedArgumentListExpression, elist);
-            return namedArgumentListExpression;
-        } else {
-            ArgumentListExpression argumentListExpression = new ArgumentListExpression(expressionList);
-            configureAST(argumentListExpression, elist);
-            return argumentListExpression;
-        }
-    }
-
-    private static void checkDuplicateNamedParams(AST elist, List<MapEntryExpression> expressionList) {
-        if (expressionList.isEmpty()) return;
-
-        Set<String> namedArgumentNames = new HashSet<>();
-        for (MapEntryExpression meExp : expressionList) {
-            if (meExp.getKeyExpression() instanceof ConstantExpression) {
-                String argName = meExp.getKeyExpression().getText();
-                if (!namedArgumentNames.contains(argName)) {
-                    namedArgumentNames.add(argName);
-                } else {
-                    throw new ASTRuntimeException(elist, "Duplicate named parameter '" + argName + "' found.");
-                }
-            }
-        }
-    }
-
-    protected boolean addArgumentExpression(AST node, List<Expression> expressionList) {
-        if (node.getType() == SPREAD_MAP_ARG) {
-            AST rightNode = node.getFirstChild();
-            Expression keyExpression = spreadMapExpression(node);
-            Expression rightExpression = expression(rightNode);
-            MapEntryExpression mapEntryExpression = new MapEntryExpression(keyExpression, rightExpression);
-            expressionList.add(mapEntryExpression);
-            return true;
-        } else {
-            Expression expression = expression(node);
-            expressionList.add(expression);
-            return expression instanceof MapEntryExpression;
-        }
-    }
-
-    protected Expression expressionList(AST node) {
-        List<Expression> expressionList = new ArrayList<>();
-        for (AST child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
-            expressionList.add(expression(child));
-        }
-        if (expressionList.size() == 1) {
-            return expressionList.get(0);
-        } else {
-            ListExpression listExpression = new ListExpression(expressionList);
-            listExpression.setWrapped(true);
-            configureAST(listExpression, node);
-            return listExpression;
-        }
-    }
-
-    protected ClosureExpression closureExpression(AST node) {
-        AST paramNode = node.getFirstChild();
-        Parameter[] parameters = null;
-        AST codeNode = paramNode;
-        if (isType(PARAMETERS, paramNode) || isType(IMPLICIT_PARAMETERS, paramNode)) {
-            parameters = parameters(paramNode);
-            codeNode = paramNode.getNextSibling();
-        }
-        Statement code = statementListNoChild(codeNode, node);
-        ClosureExpression closureExpression = new ClosureExpression(parameters, code);
-        configureAST(closureExpression, node);
-        return closureExpression;
-    }
-
-    protected Expression blockExpression(AST node) {
-        AST codeNode = node.getFirstChild();
-        if (codeNode == null) return nullX();
-        if (codeNode.getType() == EXPR && codeNode.getNextSibling() == null) {
-            // Simplify common case of {expr} to expr.
-            return expression(codeNode);
-        }
-        Parameter[] parameters = Parameter.EMPTY_ARRAY;
-        Statement code = statementListNoChild(codeNode, node);
-        ClosureExpression closureExpression = new ClosureExpression(parameters, code);
-        configureAST(closureExpression, node);
-        // Call it immediately.
-        String callName = "call";
-        Expression noArguments = new ArgumentListExpression();
-        MethodCallExpression call = new MethodCallExpression(closureExpression, callName, noArguments);
-        configureAST(call, node);
-        return call;
-    }
-
-    protected Expression unaryMinusExpression(AST unaryMinusExpr) {
-        AST node = unaryMinusExpr.getFirstChild();
-
-        // if we are a number literal then let's just parse it
-        // as the negation operator on MIN_INT causes rounding to a long
-        String text = node.getText();
-        switch (node.getType()) {
-            case NUM_DOUBLE:
-            case NUM_FLOAT:
-            case NUM_BIG_DECIMAL:
-                ConstantExpression constantExpression = new ConstantExpression(Numbers.parseDecimal("-" + text));
-                configureAST(constantExpression, unaryMinusExpr);
-                return constantExpression;
-
-            case NUM_BIG_INT:
-            case NUM_INT:
-            case NUM_LONG:
-                ConstantExpression constantLongExpression = new ConstantExpression(Numbers.parseInteger("-" + text));
-                configureAST(constantLongExpression, unaryMinusExpr);
-                return constantLongExpression;
-
-            default:
-                UnaryMinusExpression unaryMinusExpression = new UnaryMinusExpression(expression(node));
-                configureAST(unaryMinusExpression, unaryMinusExpr);
-                return unaryMinusExpression;
-        }
-    }
-
-    protected Expression unaryPlusExpression(AST unaryPlusExpr) {
-        AST node = unaryPlusExpr.getFirstChild();
-        UnaryPlusExpression unaryPlusExpression = new UnaryPlusExpression(expression(node));
-        configureAST(unaryPlusExpression, unaryPlusExpr);
-        switch (node.getType()) {
-            case NUM_DOUBLE:
-            case NUM_FLOAT:
-            case NUM_BIG_DECIMAL:
-            case NUM_BIG_INT:
-            case NUM_INT:
-            case NUM_LONG:
-                return unaryPlusExpression.getExpression();
-
-            default:
-                return unaryPlusExpression;
-        }
-    }
-
-    protected ConstantExpression decimalExpression(AST node) {
-        String text = node.getText();
-        Object number = Numbers.parseDecimal(text);
-        ConstantExpression constantExpression = new ConstantExpression(number,
-                number instanceof Double || number instanceof Float);
-        configureAST(constantExpression, node);
-        return constantExpression;
-    }
-
-    protected ConstantExpression integerExpression(AST node) {
-        String text = node.getText();
-        Object number = Numbers.parseInteger(text);
-        boolean keepPrimitive = number instanceof Integer || number instanceof Long;
-        ConstantExpression constantExpression = new ConstantExpression(number, keepPrimitive);
-        configureAST(constantExpression, node);
-        return constantExpression;
-    }
-
-    protected Expression gstring(AST gstringNode) {
-        List<ConstantExpression> strings = new ArrayList<>();
-        List<Expression> values = new ArrayList<>();
-
-        StringBuilder buffer = new StringBuilder();
-
-        boolean isPrevString = false;
-
-        for (AST node = gstringNode.getFirstChild(); node != null; node = node.getNextSibling()) {
-            int type = node.getType();
-            String text = null;
-            switch (type) {
-
-                case STRING_LITERAL:
-                    if (isPrevString) assertNodeType(IDENT, node);  // parser bug
-                    isPrevString = true;
-                    text = node.getText();
-                    ConstantExpression constantExpression = new ConstantExpression(text);
-                    configureAST(constantExpression, node);
-                    strings.add(constantExpression);
-                    buffer.append(text);
-                    break;
-
-                default: {
-                    if (!isPrevString) assertNodeType(IDENT, node);  // parser bug
-                    isPrevString = false;
-                    Expression expression = expression(node);
-                    values.add(expression);
-                    buffer.append("$");
-                    buffer.append(expression.getText());
-                }
-                break;
-            }
-        }
-        GStringExpression gStringExpression = new GStringExpression(buffer.toString(), strings, values);
-        configureAST(gStringExpression, gstringNode);
-        return gStringExpression;
-    }
-
-    public static String qualifiedName(AST qualifiedNameNode) {
-        if (isType(IDENT, qualifiedNameNode)) {
-            return qualifiedNameNode.getText();
-        }
-        if (isType(DOT, qualifiedNameNode)) {
-            AST node = qualifiedNameNode.getFirstChild();
-            StringBuilder buffer = new StringBuilder();
-            boolean first = true;
-
-            while (node != null && !isType(TYPE_ARGUMENTS, node)) {
-                if (first) {
-                    first = false;
-                } else {
-                    buffer.append(".");
-                }
-                buffer.append(qualifiedName(node));
-                node = node.getNextSibling();
-            }
-            return buffer.toString();
-        } else {
-            return qualifiedNameNode.getText();
-        }
-    }
-
-    private int getBoundType(AST node) {
-        if (node == null) return -1;
-        if (isType(TYPE_UPPER_BOUNDS, node)) return TYPE_UPPER_BOUNDS;
-        if (isType(TYPE_LOWER_BOUNDS, node)) return TYPE_LOWER_BOUNDS;
-        throw new ASTRuntimeException(node,
-                "Unexpected node type: " + getTokenName(node) +
-                        " found when expecting type: " + getTokenName(TYPE_UPPER_BOUNDS) +
-                        " or type: " + getTokenName(TYPE_LOWER_BOUNDS));
-    }
-
-    private GenericsType makeGenericsArgumentType(AST typeArgument) {
-        GenericsType gt;
-        AST rootNode = typeArgument.getFirstChild();
-        if (isType(WILDCARD_TYPE, rootNode)) {
-            ClassNode base = ClassHelper.makeWithoutCaching("?");
-            if (rootNode.getNextSibling() != null) {
-                int boundType = getBoundType(rootNode.getNextSibling());
-                ClassNode[] gts = makeGenericsBounds(rootNode, boundType);
-                if (boundType == TYPE_UPPER_BOUNDS) {
-                    gt = new GenericsType(base, gts, null);
-                } else {
-                    gt = new GenericsType(base, null, gts[0]);
-                }
-            } else {
-                gt = new GenericsType(base, null, null);
-            }
-            gt.setWildcard(true);
-        } else {
-            ClassNode argument = makeTypeWithArguments(rootNode);
-            gt = new GenericsType(argument);
-        }
-        configureAST(gt, typeArgument);
-        return gt;
-    }
-
-    protected ClassNode makeTypeWithArguments(AST rootNode) {
-        ClassNode basicType = makeType(rootNode);
-        AST node = rootNode.getFirstChild();
-        if (node == null || isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) return basicType;
-
-        if (!isType(DOT, node)) {
-            node = node.getFirstChild();
-            if (node == null) return basicType;
-            return addTypeArguments(basicType, node);
-        } else {
-            node = node.getFirstChild();
-            while (node != null && !isType(TYPE_ARGUMENTS, node))
-                node = node.getNextSibling();
-            return node == null ? basicType : addTypeArguments(basicType, node);
-        }
-    }
-
-    private ClassNode addTypeArguments(ClassNode basicType, AST node) {
-        List<GenericsType> typeArgumentList = getTypeArgumentsList(node);
-        // a 0-length type argument list means we face the diamond operator
-        basicType.setGenericsTypes(typeArgumentList.toArray(GenericsType.EMPTY_ARRAY));
-        return basicType;
-    }
-
-    private List<GenericsType> getTypeArgumentsList(AST node) {
-        assertNodeType(TYPE_ARGUMENTS, node);
-        List<GenericsType> typeArgumentList = new ArrayList<>();
-        AST typeArgument = node.getFirstChild();
-
-        while (typeArgument != null) {
-            assertNodeType(TYPE_ARGUMENT, typeArgument);
-            GenericsType gt = makeGenericsArgumentType(typeArgument);
-            typeArgumentList.add(gt);
-            typeArgument = typeArgument.getNextSibling();
-        }
-        return typeArgumentList;
-    }
-
-    private ClassNode[] makeGenericsBounds(AST rn, int boundType) {
-        AST boundsRoot = rn.getNextSibling();
-        if (boundsRoot == null) return null;
-        assertNodeType(boundType, boundsRoot);
-        List<ClassNode> bounds = new ArrayList<>();
-        for (AST boundsNode = boundsRoot.getFirstChild(); boundsNode != null; boundsNode = boundsNode.getNextSibling()) {
-            ClassNode bound = makeTypeWithArguments(boundsNode);
-            configureAST(bound, boundsNode);
-            bounds.add(bound);
-        }
-        if (bounds.isEmpty()) return null;
-        return bounds.toArray(ClassNode.EMPTY_ARRAY);
-    }
-
-    protected GenericsType[] makeGenericsType(AST rootNode) {
-        AST typeParameter = rootNode.getFirstChild();
-        List<GenericsType> generics = new ArrayList<>();
-        assertNodeType(TYPE_PARAMETER, typeParameter);
-
-        while (isType(TYPE_PARAMETER, typeParameter)) {
-            GenericsType gt = new GenericsType(makeType(typeParameter), makeGenericsBounds(typeParameter.getFirstChild(), TYPE_UPPER_BOUNDS), null);
-            configureAST(gt, typeParameter);
-            generics.add(gt);
-
-            typeParameter = typeParameter.getNextSibling();
-        }
-        return generics.toArray(GenericsType.EMPTY_ARRAY);
-    }
-
-    protected ClassNode makeType(AST typeNode) {
-        ClassNode answer = ClassHelper.DYNAMIC_TYPE;
-        AST node = typeNode.getFirstChild();
-        if (node != null) {
-            if (isType(ARRAY_DECLARATOR, node) || isType(INDEX_OP, node)) {
-                answer = makeArray(makeTypeWithArguments(node), node);
-            } else {
-                checkTypeArgs(node, false);
-                answer = ClassHelper.make(qualifiedName(node));
-                if (answer.isUsingGenerics()) {
-                    ClassNode proxy = ClassHelper.makeWithoutCaching(answer.getName());
-                    proxy.setRedirect(answer);
-                    answer = proxy;
-                }
-                configureAST(answer, node);
-            }
-        }
-        return answer;
-    }
-
-    private ClassNode makeArray(ClassNode elementType, AST node) {
-        if (elementType.equals(ClassHelper.VOID_TYPE)) {
-            throw new ASTRuntimeException(node.getFirstChild(), "void[] is an invalid type");
-        }
-        ClassNode arrayType = elementType.makeArray();
-        configureAST(arrayType, node);
-        return arrayType;
-    }
-
-    private boolean checkTypeArgs(AST node, boolean seenTypeArgs) {
-        if (isType(IDENT, node) && seenTypeArgs) {
-            throw new ASTRuntimeException(node, "Unexpected type arguments found prior to: " + qualifiedName(node));
-        }
-        if (isType(DOT, node)) {
-            AST next = node.getFirstChild();
-            while (next != null && !isType(TYPE_ARGUMENTS, next)) {
-                seenTypeArgs |= checkTypeArgs(next, seenTypeArgs);
-                seenTypeArgs |= isType(TYPE_ARGUMENTS, next.getFirstChild()) || isType(TYPE_ARGUMENTS, next.getNextSibling());
-                next = next.getNextSibling();
-            }
-        }
-        return seenTypeArgs;
-    }
-
-    protected ClassNode buildName(AST node) {
-        if (isType(TYPE, node)) {
-            node = node.getFirstChild();
-        }
-        String name;
-        if (isType(ARRAY_DECLARATOR, node) || isType(INDEX_OP, node)) {
-            return makeArray(buildName(node.getFirstChild()), node);
-        } else if (isType(DOT, node) || isType(OPTIONAL_DOT, node)) {
-            name = qualifiedName(node);
-        } else {
-            name = node.getText();
-        }
-        ClassNode answer = ClassHelper.make(name);
-        AST nextSibling = node.getNextSibling();
-        if (isType(ARRAY_DECLARATOR, nextSibling) || isType(INDEX_OP, nextSibling)) {
-            return makeArray(answer, node);
-        } else {
-            configureAST(answer, node);
-            return answer;
-        }
-    }
-
-    protected boolean isPrimitiveTypeLiteral(AST node) {
-        int type = node.getType();
-        switch (type) {
-            case LITERAL_boolean:
-            case LITERAL_byte:
-            case LITERAL_char:
-            case LITERAL_double:
-            case LITERAL_float:
-            case LITERAL_int:
-            case LITERAL_long:
-            case LITERAL_short:
-                return true;
-
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Extracts an identifier from the Antlr AST
-     */
-    protected String identifier(AST node) {
-        assertNodeType(IDENT, node);
-        return node.getText();
-    }
-
-    protected String label(AST labelNode) {
-        AST node = labelNode.getFirstChild();
-        if (node == null) {
-            return null;
-        }
-        return identifier(node);
-    }
-
-    // Helper methods
-    //-------------------------------------------------------------------------
-
-    /**
-     * Returns true if the modifiers flags contain a visibility modifier
-     */
-    protected boolean hasVisibility(int modifiers) {
-        return (modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) != 0;
-    }
-
-    protected void configureAST(ASTNode node, AST ast) {
-        if (ast == null)
-            throw new ASTRuntimeException(ast, "PARSER BUG: Tried to configure " + node.getClass().getName() + " with null AST");
-        node.setLineNumber(ast.getLine());
-        node.setColumnNumber(ast.getColumn());
-        if (ast instanceof GroovySourceAST) {
-            node.setLastLineNumber(((GroovySourceAST) ast).getLineLast());
-            node.setLastColumnNumber(((GroovySourceAST) ast).getColumnLast());
-        }
-    }
-
-    protected static Token makeToken(int typeCode, AST node) {
-        return Token.newSymbol(typeCode, node.getLine(), node.getColumn());
-    }
-
-    protected String getFirstChildText(AST node) {
-        AST child = node.getFirstChild();
-        return child != null ? child.getText() : null;
-    }
-
-    public static boolean isType(int typeCode, AST node) {
-        return node != null && node.getType() == typeCode;
-    }
-
-    private String getTokenName(int token) {
-        if (tokenNames == null) return "" + token;
-        return tokenNames[token];
-    }
-
-    private String getTokenName(AST node) {
-        if (node == null) return "null";
-        return getTokenName(node.getType());
-    }
-
-    protected void assertNodeType(int type, AST node) {
-        if (node == null) {
-            throw new ASTRuntimeException(node, "No child node available in AST when expecting type: " + getTokenName(type));
-        }
-        if (node.getType() != type) {
-            throw new ASTRuntimeException(node, "Unexpected node type: " + getTokenName(node) + " found when expecting type: " + getTokenName(type));
-        }
-    }
-
-    protected void notImplementedYet(AST node) {
-        throw new ASTRuntimeException(node, "AST node not implemented yet for type: " + getTokenName(node));
-    }
-
-    protected void unknownAST(AST node) {
-        if (node.getType() == CLASS_DEF) {
-            throw new ASTRuntimeException(node,
-                    "Class definition not expected here. Please define the class at an appropriate place or perhaps try using a block/Closure instead.");
-        }
-        if (node.getType() == METHOD_DEF) {
-            throw new ASTRuntimeException(node,
-                    "Method definition not expected here. Please define the method at an appropriate place or perhaps try using a block/Closure instead.");
-        }
-        throw new ASTRuntimeException(node, "Unknown type: " + getTokenName(node));
-    }
-
-    protected void dumpTree(AST ast) {
-        for (AST node = ast.getFirstChild(); node != null; node = node.getNextSibling()) {
-            dump(node);
-        }
-    }
-
-    protected void dump(AST node) {
-        System.out.println("Type: " + getTokenName(node) + " text: " + node.getText());
-    }
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPluginFactory.java b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPluginFactory.java
deleted file mode 100644
index f0f3f9e..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPluginFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import org.codehaus.groovy.control.ParserPlugin;
-import org.codehaus.groovy.control.ParserPluginFactory;
-
-@Deprecated
-public class AntlrParserPluginFactory extends ParserPluginFactory {
-    @Deprecated
-    public ParserPlugin createParserPlugin() {
-        return new AntlrParserPlugin();
-    }
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java b/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java
deleted file mode 100644
index ae57409..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import antlr.CommonAST;
-import antlr.Token;
-import antlr.collections.AST;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * We have an AST subclass so we can track source information.
- * Very odd that ANTLR doesn't do this by default.
- */
-public class GroovySourceAST extends CommonAST implements Comparable, SourceInfo {
-    private static final long serialVersionUID = 9116765466538981906L;
-    private int line;
-    private int col;
-    private int lineLast;
-    private int colLast;
-    private String snippet;
-
-    public GroovySourceAST() {
-    }
-
-    public GroovySourceAST(Token t) {
-        super(t);
-    }
-
-    public void initialize(AST ast) {
-        super.initialize(ast);
-        line = ast.getLine();
-        col = ast.getColumn();
-        if (ast instanceof GroovySourceAST) {
-            GroovySourceAST node = (GroovySourceAST)ast;
-            lineLast = node.getLineLast();
-            colLast = node.getColumnLast();
-        }
-    }
-
-    public void initialize(Token t) {
-        super.initialize(t);
-        line = t.getLine();
-        col = t.getColumn();
-        if (t instanceof SourceInfo) {
-            SourceInfo info = (SourceInfo) t;
-            lineLast = info.getLineLast();
-            colLast  = info.getColumnLast();
-        }
-    }
-
-    public void setLast(Token last) {
-        lineLast = last.getLine();
-        colLast = last.getColumn();
-    }
-
-    public int getLineLast() {
-        return lineLast;
-    }
-
-    public void setLineLast(int lineLast) {
-        this.lineLast = lineLast;
-    }
-
-    public int getColumnLast() {
-        return colLast;
-    }
-
-    public void setColumnLast(int colLast) {
-        this.colLast = colLast;
-    }
-
-    public void setLine(int line) {
-        this.line = line;
-    }
-
-    public int getLine() {
-        return (line);
-    }
-
-    public void setColumn(int column) {
-        this.col = column;
-    }
-
-    public int getColumn() {
-        return (col);
-    }
-
-    public void setSnippet(String snippet) {
-        this.snippet = snippet;
-    }
-
-    public String getSnippet() {
-        return snippet;
-    }
-
-    public int compareTo(Object object) {
-        if (object == null) {
-            return 0;
-        }
-        if (!(object instanceof AST)) {
-            return 0;
-        }
-        AST that = (AST) object;
-
-        // todo - possibly check for line/col with values of 0 or less...
-
-        if (this.getLine() < that.getLine()) {
-            return -1;
-        }
-        if (this.getLine() > that.getLine()) {
-            return 1;
-        }
-
-        return Integer.compare(this.getColumn(), that.getColumn());
-
-    }
-
-    public GroovySourceAST childAt(int position) {
-        int cur = 0;
-        AST child = this.getFirstChild();
-        while (child != null && cur <= position) {
-            if (cur == position) {
-                return (GroovySourceAST) child;
-            }
-            cur++;
-            child = child.getNextSibling();
-        }
-        return null;
-    }
-
-    public GroovySourceAST childOfType(int type) {
-        AST child = this.getFirstChild();
-        while (child != null) {
-            if (child.getType() == type) { return (GroovySourceAST)child; }
-            child = child.getNextSibling();
-        }
-        return null;
-    }
-
-    public List<GroovySourceAST> childrenOfType(int type) {
-        List<GroovySourceAST> result = new ArrayList<GroovySourceAST>();
-        AST child = this.getFirstChild();
-        while (child != null) {
-            if (child.getType() == type) { result.add((GroovySourceAST) child); }
-            child = child.getNextSibling();
-        }
-        return result;
-    }
-
-}
diff --git a/src/main/java/org/codehaus/groovy/antlr/GroovySourceToken.java b/src/main/java/org/codehaus/groovy/antlr/GroovySourceToken.java
deleted file mode 100644
index b4b6ab8..0000000
--- a/src/main/java/org/codehaus/groovy/antlr/GroovySourceToken.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.antlr;
-
-import antlr.Token;
-
-/**
... 9401 lines suppressed ...