diff --git a/src/main/grammar/JastAddAspect.bnf b/src/main/grammar/JastAddAspect.bnf
index 01b821327f07c06bee036c3e9539d835021ddfbb..8611058fbd123e342d9394f5fb778e53b668c75b 100644
--- a/src/main/grammar/JastAddAspect.bnf
+++ b/src/main/grammar/JastAddAspect.bnf
@@ -13,15 +13,161 @@
   tokenTypeClass="org.jastadd.tooling.aspect.JastAddAspectTokenType"
 }
 
-jastaddAspectFile ::= (attribute_equation|comment)*
+jastaddAspectFile ::= (aspect_declaration|comment)*
 
 comment ::= (WHITESPACE | MULTILINECOMMENT | DOCCOMMENT | SINGLELINECOMMENT)
 
-attribute_equation ::= EQ java_block
+//attribute_equation ::= EQ java_block
+//
+//java_block ::= JAVABLOCK
+//{
+//  implements="org.jastadd.tooling.aspect.psi.JastAddAspectJavaBlockExtension"
+//  extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectJavaBlockImplExtension"
+//}
 
-java_block ::= JAVABLOCK
-{
-  implements="org.jastadd.tooling.aspect.psi.JastAddAspectJavaBlockExtension"
-  extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectJavaBlockImplExtension"
-}
+aspect_declaration ::= ASPECT aspect_body
+
+aspect_body ::= LBRACE aspect_body_declaration* RBRACE
+
+aspect_body_declaration ::= ( aspect_refine_inh_equation
+                            | aspect_refine_syn_equation
+                            | aspect_refine_method_declaration
+                            | aspect_refine_constructor_declaration
+                            | aspect_class_declaration
+                            | aspect_interface_declaration
+                            | aspect_enum_declaration
+                            | aspect_syn_attribute_declaration
+                            | aspect_inh_attribute_declaration
+                            | aspect_rewrite
+                            | aspect_inh_equation
+                            | aspect_syn_equation
+                            | aspect_add_interface
+                            | aspect_extend_interface
+                            | collection_attribute
+                            | collection_contribution
+                            | aspect_method_declaration
+                            | aspect_constructor_declaration
+                            | aspect_field_declaration
+                            | aspect_cache_declaration )
+
+aspect_body_declarations_eof ::= aspect_body_declaration* EOF
+
+aspect_class_declaration ::= modifiers CLASS id type_parameters (EXTENDS class_or_interface_type)? (IMPLEMENTS type_name_list)? aspect_class_body
+
+aspect_class_body ::= JAVA_CLASS_BODY_DECLARATION // including curly braces
+
+aspect_interface_declaration ::= modifiers INTERFACE id type_parameters? (EXTENDS type_name_list)? LBRACE aspect_interface_member_declaration* RBRACE
+
+aspect_interface_member_declaration ::= ( aspect_nested_class_declaration
+                                        | aspect_nested_interface_declaration
+                                        | aspect_interface_syn_attribute_declaration
+                                        | aspect_interface_inh_attribute_declaration
+                                        | aspect_interface_method_declaration
+                                        | aspect_interface_field_declaration )
+
+aspect_interface_syn_attribute_declaration ::= annotation* SYN LAZY? FINAL? aspect_type attribute_name LPAREN (type ID (COMMA type ID)* )? RPAREN (CIRCULAR LBRACKET JAVA_EXPRESSION RBRACKET)? SCOL
+
+aspect_interface_inh_attribute_declaration ::= annotation* INH LAZY? FINAL? aspect_type attribute_name LPAREN (type ID (COMMA type ID)* )? RPAREN (CIRCULAR LBRACKET JAVA_EXPRESSION RBRACKET)? SCOL
+
+aspect_interface_method_declaration ::= (PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED )* aspect_result_type method_declarator (THROWS name_list ) SCOL
+
+aspect_interface_field_declaration ::= modifiers aspect_type variable_declarator (COMMA variable_declarator)* SCOL
+
+aspect_nested_interface_declaration ::= modifiers INTERFACE ID type_parameters? EXTENDS? LBRACE JAVA_INTERFACE_MEMBER_DECLARATIONS RBRACE
+
+aspect_nested_class_declaration ::= modifiers CLASS ID type_parameters? (EXTENDS class_or_interface_type)? (IMPLEMENTS type_name_list)? JAVA_CLASS_BODY_DECLARATION
+
+aspect_method_declaration ::= modifiers type_parameters? aspect_result_type ID DOT method_declarator (THROWS name_list)? (block | SCOL)
+
+aspect_refine_method_declaration ::= REFINE [ID] modifers type_parameters? aspect_result_type ID DOT method_declarator (THROWS name_list)? (block | SCOL)
+
+aspect_constructor_declaration ::= modifiers ID DOT ID formal_parameters (THROWS name_list)? LBRACE JAVA_EXPLICIT_CONSTRUCTUR_BLOCK RBRACE
+
+aspect_refine_constructor_declaration ::= REFINE ID (PUBLIC | PROTECTED | PRIVATE) ID DOT ID formal_parameters (THROWS name_list)? LBRACE block_statement* RBRACE
+
+aspect_field_declaration ::= modifiers aspect_type ID DOT variable_declarator (COMMA variable_declarator)* SCOL
+
+aspect_syn_attribute_declaration ::= annotation* SYN NTA? LAZY? FINAL? aspect_type ID DOT attribute_name LPAREN type ID (COMMA type ID)* RPAREN (CIRCULAR LBRACKET JAVA_EXPRESSION RBRACKET)? ( EQ JAVA_EXPRESSION SCOL | block | SCOL )
+
+aspect_inh_attribute_declaration ::= annotation* INH NTA? LAZY? FINAL? aspect_type ID DOT attribute_name LPAREN (type ID (COMMA type ID)* )? (CIRCULAR LBRACKET JAVA_EXPRESSION RBRACKET)? SCOL
+
+aspect_rewrite ::= REWRITE ID (ID DOT ID LPAREN RPAREN)? LBRACE ((WHEN LPAREN JAVA_EXPRESSION RPAREN)? TO aspect_type ( JAVA_EXPRESSION SCOL | block ))+ RBRACE
+
+aspect_syn_equation ::= annotation* ID DOT attribute_name LPAREN (type ID (COMMA type ID)*)? RPAREN ( EQ JAVA_EXPRESSION SCOL | block )
+
+aspect_refine_syn_equation ::= REFINE ID EQ ID attribute_name LPAREN (type ID (COMMA type ID)*)? RPAREN (EQ JAVA_EXPRESSION SCOL | block)
+
+aspect_inh_equation ::= annotation* EQ ID DOT ID LPAREN (INT ID)? DOT attribute_name LPAREN (type ID (COMMA type ID)*)? RPAREN (EQ JAVA_EXPRESSION | block)
+
+aspect_refine_inh_equation ::= REFINE ID EQ ID DOT ID LPAREN (INT ID)? RPAREN DOT attribute_name LPAREN (type ID (COMMA type ID)*)? RPAREN (EQ JAVA_EXPRESSION | block)
+
+collection_attribute ::= annotation* COLL aspect_type ID DOT attribute_name LPAREN RPAREN CIRCULAR? (LBRACKET JAVA_EXPRESSION RBRACKET)? (WITH ID)? (ROOT ID)? SCOL
+
+collection_contribution ::= annotation* CONTRIBUTES ( NTA JAVA_EXPRESSION TO ID DOT attribute_name LPAREN RPAREN | EACH? JAVA_EXPRESSION (WHEN JAVA_EXPRESSION)? TO ID DOT attribute_name LPAREN RPAREN (FOR  EACH? JAVA_EXPRESSION)? | block TO ID DOT attribute_name LPAREN RPAREN ) SCOL
+
+aspect_add_interface ::= IO IMPLEMENTS type_name_list SCOL
+
+aspect_extend_interface ::= ID EXTENDS type_name_list SCOL
+
+// added
+
+type_name_list ::= class_or_interface_type (COMMA class_or_interface_type)*
+
+attribute_name ::= ID
+
+// TODO | UnmodifiedClassDeclaration("")
+block_statement ::= (FINAL? type java_identifier local_variable_declaration SCOL) | statement
+
+aspect_cache_declaration ::= (CACHE | UNCACHE) ID DOT attribute_name LPAREN (type ID? (type ID?)* )? RPAREN SCOL
+
+modifiers ::= (PUBLIC | STATIC  | PROTECTED | PRIVATE | FINAL | ABSTRACT | SYNCHRONIZED | NATIVE | TRANSIENT | VOLATILE | STRICTFP)*
+
+// Attribute type names can not start with JastAdd reserved words such as 'syn', 'eq', etc.
+aspect_type ::= aspect_reference_type | ( primitive_type (LBRACKET RBRACKET)? )
+
+formal_parameters ::= LPAREN ( formal_parameter ( COMMA formal_parameter )* )? RPAREN
+
+name_list ::= name (COMMA name)*
+
+formal_parameter ::= FINAL? type DOTS? variable_declarator_id
+
+variable_declarator_id ::= java_identifier ( LBRACKET RBRACKET )*
+
+java_identifier ::= ID | INH | SYN | LAZY | REWRITE | TO | WHEN | ASPECT | EQUATION | CIRCULAR | REFINE | COLL | CONTRIBUTES | EACH | NTA | CACHE | UNCACHE
+
+aspect_enum_declaration ::= modifiers ENUM ID (IMPLEMENTS type_name_list)? JAVA_ENUM_BODY
+
+variable_declarator ::= variable_declarator_id ( EQ variable_initializer )?
+
+variable_initializer ::= array_initializer | expression
+
+array_initializer ::= LBRACE ( variable_initializer (COMMA variable_initializer)* )? RBRACE
+
+primitive_type ::= boolean | char | byte | short | int | long | float | double
+
+class_or_interface_type ::= java_identifier type_arguments? (DOT java_identifier type_arguments? )*
+
+type_arguments ::= LESSTHAN (type_argument (COMMA type_argument)* )? MORETHAN
+
+type_argument ::= reference_type | (QUESTIONMARK wildcard_bounds?)
+
+wildcard_bounds ::= (EXTENDS reference_type) | SUPER reference_type
+
+reference_type ::= ( primitive_type (LBRACKET RBRACKET)+ ) | ( class_or_interface_type (LBRACKET RBRACKET)* )
+
+aspect_reference_type ::= aspect_class_or_interface_type (LBRACKET RBRACKET)*
+
+aspect_class_or_interface_type ::= ID type_arguments? (DOT java_identifier type_arguments? )*
+
+local_variable_declaration ::= FINAL? type variable_declarator (COMMA variable_declarator)*
+
+type_parameters ::= LESSTHAN type_parameter (COMMA type_parameter)* GREATERTHAN
+
+type_parameter ::= java_identifier type_bound?
+
+type_bound ::= EXTENDS class_or_interface_type (AMPERSAND class_or_interface_type)*
+
+aspect_result_type ::= VOID | aspect_type
+
+method_declarator ::= java_identifier formal_parameters (LBRACKET RBRACKET)*
 
diff --git a/src/main/grammar/JastAddAspect.flex b/src/main/grammar/JastAddAspect.flex
index fafc09948777b0855329ca2b4776b0a1a393317f..9f12d97ca8125b60ff2c5fd0b24f54af459c064a 100644
--- a/src/main/grammar/JastAddAspect.flex
+++ b/src/main/grammar/JastAddAspect.flex
@@ -37,8 +37,82 @@ NotParenthesis    = [^{}]*
  "{"                            { yybegin(JAVA); counter = 1;  }
 }
 
-<JAVA> {
+<JAVA_PARENTHESIS_BLOCK> {
  {NotParenthesis}               {}
  "{"                            { counter++; yybegin(JAVA); }
  "}"                            { counter--; if (counter==0) { yybegin(YYINITIAL); return JastAddAspectTypes.JAVABLOCK; } }
 }
+
+<JAVATOKENS> {
+ "abstract"                     { return JastAddAspectTypes.ABSTRACT; }
+ "assert"                       { return JastAddAspectTypes.ASSERT; }
+ "boolean"                      { return JastAddAspectTypes.BOOLEAN; }
+ "break"                        { return JastAddAspectTypes.BREAK; }
+ "byte"                         { return JastAddAspectTypes.BYTE; }
+ "case"                         { return JastAddAspectTypes.CASE; }
+ "catch"                        { return JastAddAspectTypes.CATCH; }
+ "char"                         { return JastAddAspectTypes.CHAR; }
+ "class"                        { return JastAddAspectTypes.CLASS; }
+ "const"                        { return JastAddAspectTypes.CONST; }
+ "continue"                     { return JastAddAspectTypes.CONTINUE; }
+ "default"                      { return JastAddAspectTypes._DEFAULT; }
+ "do"                           { return JastAddAspectTypes.DO; }
+ "double"                       { return JastAddAspectTypes.DOUBLE; }
+ "else"                         { return JastAddAspectTypes.ELSE; }
+ "enum"                         { return JastAddAspectTypes.ENUM; }
+ "extends"                      { return JastAddAspectTypes.EXTENDS; }
+ "false"                        { return JastAddAspectTypes.FALSE; }
+ "final"                        { return JastAddAspectTypes.FINAL; }
+ "finally"                      { return JastAddAspectTypes.FINALLY; }
+ "float"                        { return JastAddAspectTypes.FLOAT; }
+ "for"                          { return JastAddAspectTypes.FOR; }
+ "goto"                         { return JastAddAspectTypes.GOTO; }
+ "if"                           { return JastAddAspectTypes.IF; }
+ "implements"                   { return JastAddAspectTypes.IMPLEMENTS; }
+ "import"                       { return JastAddAspectTypes.IMPORT; }
+ "instanceof"                   { return JastAddAspectTypes.INSTANCEOF; }
+ "int"                          { return JastAddAspectTypes.INT; }
+ "interface"                    { return JastAddAspectTypes.INTERFACE; }
+ "long"                         { return JastAddAspectTypes.LONG; }
+ "native"                       { return JastAddAspectTypes.NATIVE; }
+ "new"                          { return JastAddAspectTypes.NEW; }
+ "null"                         { return JastAddAspectTypes.NULL; }
+ "package"                      { return JastAddAspectTypes.PACKAGE; }
+ "private"                      { return JastAddAspectTypes.PRIVATE; }
+ "protected"                    { return JastAddAspectTypes.PROTECTED; }
+ "public"                       { return JastAddAspectTypes.PUBLIC; }
+ "return"                       { return JastAddAspectTypes.RETURN; }
+ "short"                        { return JastAddAspectTypes.SHORT; }
+ "static"                       { return JastAddAspectTypes.STATIC; }
+ "strictfp"                     { return JastAddAspectTypes.STRICTFP; }
+ "super"                        { return JastAddAspectTypes.SUPER; }
+ "switch"                       { return JastAddAspectTypes.SWITCH; }
+ "synchronized"                 { return JastAddAspectTypes.SYNCHRONIZED; }
+ "this"                         { return JastAddAspectTypes.THIS; }
+ "throw"                        { return JastAddAspectTypes.THROW; }
+ "throws"                       { return JastAddAspectTypes.THROWS; }
+ "transient"                    { return JastAddAspectTypes.TRANSIENT; }
+ "true"                         { return JastAddAspectTypes.TRUE; }
+ "try"                          { return JastAddAspectTypes.TRY; }
+ "void"                         { return JastAddAspectTypes.VOID; }
+ "volatile"                     { return JastAddAspectTypes.VOLATILE; }
+ "while"                        { return JastAddAspectTypes.WHILE; }
+
+ // JastAdd
+
+  "inh"                         { return JastAddAspectTypes.INH; }
+  "syn"                         { return JastAddAspectTypes.SYN; }
+  "lazy"                        { return JastAddAspectTypes.LAZY; }
+  "rewrite"                     { return JastAddAspectTypes.REWRITE; }
+  "to"                          { return JastAddAspectTypes.TO; }
+  "when"                        { return JastAddAspectTypes.WHEN; }
+  "aspect"                      { return JastAddAspectTypes.ASPECT; }
+  "eq"                          { return JastAddAspectTypes.EQUATION; }
+  "circular"                    { return JastAddAspectTypes.CIRCULAR; }
+  "refine"                      { return JastAddAspectTypes.REFINE; }
+  "contributes"                 { return JastAddAspectTypes.CONTRIBUTES; }
+  "each"                        { return JastAddAspectTypes.EACH; }
+  "nta"                         { return JastAddAspectTypes.NTA; }
+  "cache"                       { return JastAddAspectTypes.CACHE; }
+  "uncache"                     { return JastAddAspectTypes.UNCACHE; }
+}
diff --git a/src/main/grammar/Jrag.jjt b/src/main/grammar/Jrag.jjt
new file mode 100644
index 0000000000000000000000000000000000000000..0fad94504848b91080e3d8e0fe3c94ce0468bb79
--- /dev/null
+++ b/src/main/grammar/Jrag.jjt
@@ -0,0 +1,2733 @@
+/* Copyright (c) 2006, Sun Microsystems, Inc.
+ *               2006-2018, The JastAdd Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Sun Microsystems, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived from
+ *       this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This file is based on the Java1.1.jjt file from the VTransformer example
+ * from JavaCC by Sun Microsystems, Inc. Modifications have been made by the
+ * JastAdd team to add support for JastAdd features.  The original author of
+ * this file, according to older releases of JavaCC, was Sriram Sankar. A date
+ * tag in the older releases shows the file was created on 3/5/97.
+ */
+options {
+  JAVA_UNICODE_ESCAPE = true;
+
+  STATIC=false;
+  MULTI=true;
+  VISITOR=true;
+  NODE_USES_PARSER=true;
+  NODE_SCOPE_HOOK= true;
+  NODE_PACKAGE="org.jastadd.jrag.AST";
+}
+
+PARSER_BEGIN(JragParser)
+package org.jastadd.jrag.AST;
+import java.util.*;
+import org.jastadd.jrag.*;
+
+import org.jastadd.ast.AST.Grammar;
+
+public class JragParser {
+
+  /* Added attributes to the parser: */
+  public String className = ""; // Name of class currently parsed.
+  public String enclosingAspect = ""; // The name of the aspect currently being parsed.
+  public String fileName; // Name of parsed file.
+
+  private java.util.List<String> contextStack = new java.util.ArrayList<String>();
+
+  public boolean inTopLevelOrAspect() {
+    int size = contextStack.size();
+    return size == 0 || (size == 1 && contextStack.get(0).equals("aspect"));
+  }
+
+  public boolean shouldAddClassBodyDecl() {
+    int size = contextStack.size();
+    return size == 1 &&
+        (contextStack.get(0).equals("aspect") ||
+         contextStack.get(0).equals("class") ||
+         contextStack.get(0).equals("interface"));
+  }
+
+  public void pushTopLevelOrAspect(String context) {
+    contextStack.add(context);
+  }
+
+  public void popTopLevelOrAspect() {
+    contextStack.remove(contextStack.size()-1);
+  }
+
+  public Grammar root;
+  public java.io.InputStream inputStream;
+
+  /** Set name of parsed file. */
+  public void setFileName(String name) {
+    fileName = name;
+    className = "";
+    contextStack = new java.util.ArrayList<String>();
+  }
+
+  /* ------ Added methods for NODE_SCOPE_HOOKS ---------*/
+  public  void jjtreeOpenNodeScope(Node n) {
+    ((SimpleNode) n).firstToken = getToken(1);
+  }
+
+  public void jjtreeCloseNodeScope(Node n) {
+    ((SimpleNode) n).lastToken = getToken(0);
+  }
+  /* ------End of methods for NODE_SCOPE_HOOK------------*/
+
+  /** Returns string consisting of all chars before a dot. */
+  public String beforeDot(String s) {
+    int i = s.indexOf('.');
+    if (i < 0) {
+      return s;
+    } else {
+      return s.substring(0, i);
+    }
+  }
+
+  /**
+   * Returns string consisting of all chars between "get" and before a '('.
+   * Returns null if "get" is not a prefix; s  if no "(" found.
+   */
+  public String stripGet(String s) {
+    if (!s.startsWith("get")) {
+      return null;
+    }
+    s = s.substring(3, s.length());
+    return s;
+  }
+
+  /** Returns string consisting of all chars after a dot. */
+  public String afterDot(String s) {
+    int i = s.indexOf('.');
+    if (i < 0) {
+      return null;
+    } else {
+      return s.substring(i+1,s.length());
+    }
+  }
+}
+
+PARSER_END(JragParser)
+
+/* WHITE SPACE */
+
+<DEFAULT,COLLECTION_DECL>
+SPECIAL_TOKEN :
+{
+  " "
+| "\t"
+| "\n"
+| "\r"
+| "\f"
+}
+
+/* COMMENTS */
+
+<DEFAULT,COLLECTION_DECL>
+MORE :
+{
+  "//" : IN_SINGLE_LINE_COMMENT
+|
+  <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
+|
+  "/*" : IN_MULTI_LINE_COMMENT
+}
+
+
+<IN_SINGLE_LINE_COMMENT>
+SPECIAL_TOKEN :
+{
+  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT
+}
+
+<IN_FORMAL_COMMENT>
+SPECIAL_TOKEN :
+{
+  <FORMAL_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_MULTI_LINE_COMMENT>
+SPECIAL_TOKEN :
+{
+  <MULTI_LINE_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
+MORE :
+{
+  < ~[] >
+}
+
+/* RESERVED WORDS AND LITERALS */
+
+<DEFAULT,COLLECTION_DECL>
+TOKEN :
+{
+  < ABSTRACT: "abstract" >
+| < ASSERT: "assert" >
+| < BOOLEAN: "boolean" >
+| < BREAK: "break" >
+| < BYTE: "byte" >
+| < CASE: "case" >
+| < CATCH: "catch" >
+| < CHAR: "char" >
+| < CLASS: "class" >
+| < CONST: "const" >
+| < CONTINUE: "continue" >
+| < _DEFAULT: "default" >
+| < DO: "do" >
+| < DOUBLE: "double" >
+| < ELSE: "else" >
+| < ENUM: "enum" >
+| < EXTENDS: "extends" >
+| < FALSE: "false" >
+| < FINAL: "final" >
+| < FINALLY: "finally" >
+| < FLOAT: "float" >
+| < FOR: "for" >
+| < GOTO: "goto" >
+| < IF: "if" >
+| < IMPLEMENTS: "implements" >
+| < IMPORT: "import" >
+| < INSTANCEOF: "instanceof" >
+| < INT: "int" >
+| < INTERFACE: "interface" >
+| < LONG: "long" >
+| < NATIVE: "native" >
+| < NEW: "new" >
+| < NULL: "null" >
+| < PACKAGE: "package">
+| < PRIVATE: "private" >
+| < PROTECTED: "protected" >
+| < PUBLIC: "public" >
+| < RETURN: "return" >
+| < SHORT: "short" >
+| < STATIC: "static" >
+| < STRICTFP: "strictfp" >
+| < SUPER: "super" >
+| < SWITCH: "switch" >
+| < SYNCHRONIZED: "synchronized" >
+| < THIS: "this" >
+| < THROW: "throw" >
+| < THROWS: "throws" >
+| < TRANSIENT: "transient" >
+| < TRUE: "true" >
+| < TRY: "try" >
+| < VOID: "void" >
+| < VOLATILE: "volatile" >
+| < WHILE: "while" >
+
+// JastAdd keywords:
+| < INH: "inh">
+| < SYN: "syn">
+| < LAZY: "lazy">
+| < REWRITE: "rewrite">
+| < TO: "to">
+| < WHEN: "when">
+| < ASPECT: "aspect">
+| < EQUATION: "eq">
+| < CIRCULAR: "circular">
+| < REFINE: "refine">
+| < CONTRIBUTES: "contributes">
+| < EACH: "each">
+| < NTA: "nta">
+| < CACHE: "cache">
+| < UNCACHE: "uncache">
+}
+
+TOKEN :
+{
+  < COLL: "coll"> : COLLECTION_DECL
+}
+
+<COLLECTION_DECL>
+TOKEN :
+{
+  < WITH: "with">
+| < ROOT: "root">
+}
+
+/* LITERALS */
+
+<DEFAULT,COLLECTION_DECL>
+TOKEN :
+{
+  < INTEGER_LITERAL:
+        <DECIMAL_LITERAL> (["l","L"])?
+      | <HEX_LITERAL> (["l","L"])?
+      | <OCTAL_LITERAL> (["l","L"])?
+  >
+|
+  < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
+|
+  < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
+|
+  < #OCTAL_LITERAL: "0" (["0"-"7"])* >
+|
+  < FLOATING_POINT_LITERAL:
+        (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
+      | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
+      | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
+      | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
+  >
+|
+  < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+|
+  < CHARACTER_LITERAL:
+      "'"
+      (   (~["'","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+      )
+      "'"
+  >
+|
+  < STRING_LITERAL:
+      "\""
+      (   (~["\"","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+      )*
+      "\""
+  >
+}
+
+/* IDENTIFIERS */
+
+<DEFAULT,COLLECTION_DECL>
+TOKEN :
+{
+  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+|
+  < #LETTER:
+      [
+       "\u0024",
+       "\u0041"-"\u005a",
+       "\u005f",
+       "\u0061"-"\u007a",
+       "\u00c0"-"\u00d6",
+       "\u00d8"-"\u00f6",
+       "\u00f8"-"\u00ff",
+       "\u0100"-"\u1fff",
+       "\u3040"-"\u318f",
+       "\u3300"-"\u337f",
+       "\u3400"-"\u3d2d",
+       "\u4e00"-"\u9fff",
+       "\uf900"-"\ufaff"
+      ]
+  >
+|
+  < #DIGIT:
+      [
+       "\u0030"-"\u0039",
+       "\u0660"-"\u0669",
+       "\u06f0"-"\u06f9",
+       "\u0966"-"\u096f",
+       "\u09e6"-"\u09ef",
+       "\u0a66"-"\u0a6f",
+       "\u0ae6"-"\u0aef",
+       "\u0b66"-"\u0b6f",
+       "\u0be7"-"\u0bef",
+       "\u0c66"-"\u0c6f",
+       "\u0ce6"-"\u0cef",
+       "\u0d66"-"\u0d6f",
+       "\u0e50"-"\u0e59",
+       "\u0ed0"-"\u0ed9",
+       "\u1040"-"\u1049"
+      ]
+  >
+}
+
+/* SEPARATORS */
+
+<DEFAULT,COLLECTION_DECL>
+TOKEN :
+{
+  < LPAREN: "(" >
+| < RPAREN: ")" >
+| < LBRACE: "{" >
+| < RBRACE: "}" >
+| < LBRACKET: "[" >
+| < RBRACKET: "]" >
+| < SEMICOLON: ";" >
+| < COMMA: "," >
+| < DOT: "." >
+| < AT: "@" >
+}
+
+/* OPERATORS */
+
+<DEFAULT,COLLECTION_DECL>
+TOKEN :
+{
+  < ASSIGN: "=" >
+| < LT: "<" >
+| < BANG: "!" >
+| < TILDE: "~" >
+| < HOOK: "?" >
+| < COLON: ":" >
+| < EQ: "==" >
+| < LE: "<=" >
+| < GE: ">=" >
+| < NE: "!=" >
+| < SC_OR: "||" >
+| < SC_AND: "&&" >
+| < INCR: "++" >
+| < DECR: "--" >
+| < PLUS: "+" >
+| < MINUS: "-" >
+| < STAR: "*" >
+| < SLASH: "/" >
+| < BIT_AND: "&" >
+| < BIT_OR: "|" >
+| < XOR: "^" >
+| < REM: "%" >
+| < LSHIFT: "<<" >
+| < PLUSASSIGN: "+=" >
+| < MINUSASSIGN: "-=" >
+| < STARASSIGN: "*=" >
+| < SLASHASSIGN: "/=" >
+| < ANDASSIGN: "&=" >
+| < ORASSIGN: "|=" >
+| < XORASSIGN: "^=" >
+| < REMASSIGN: "%=" >
+| < LSHIFTASSIGN: "<<=" >
+| < RSIGNEDSHIFTASSIGN: ">>=" >
+| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
+| < ELLIPSIS: "..." >
+| < ARROW: "->" >
+| < DOUBLECOLON: "::" >
+}
+
+/* >'s need special attention due to generics syntax. */
+<DEFAULT,COLLECTION_DECL>
+TOKEN :
+{
+  < RUNSIGNEDSHIFT: ">>>" >
+  {
+     matchedToken.kind = GT;
+     ((Token.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT;
+     input_stream.backup(2);
+  }
+| < RSIGNEDSHIFT: ">>" >
+  {
+     matchedToken.kind = GT;
+     ((Token.GTToken)matchedToken).realKind = RSIGNEDSHIFT;
+     input_stream.backup(1);
+  }
+| < GT: ">" >
+}
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Program structuring syntax follows.
+ */
+
+ASTCompilationUnit CompilationUnit() :
+{}
+{
+  ( ImportDeclaration() )*
+  ( TypeDeclaration() )*
+  <EOF>
+  {
+    return jjtThis;
+  }
+}
+
+void ImportDeclaration() :
+{}
+{
+  "import" [ "static" ] Name() [ "." "*" ] ";"
+}
+
+String Modifiers() :
+{
+  StringBuilder buf = new StringBuilder();
+  SimpleNode annotation;
+}
+{
+ (LOOKAHEAD(2)
+  (
+   "public"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "static"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "protected"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "private"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "final"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "abstract"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "synchronized"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "native"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "transient"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "volatile"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   "strictfp"
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(token.image);
+   }
+  |
+   annotation = Annotation()
+   {
+     if (buf.length() > 0) buf.append(" ");
+     buf.append(Unparser.unparse(annotation));
+   }
+  )
+ )*
+ { jjtree.popNode(); return buf.toString(); }
+}
+
+void TypeDeclaration() :
+{
+  String modifiers;
+}
+{
+  ";"
+|
+  modifiers = Modifiers()
+  (
+     ClassDeclaration(modifiers)
+   |
+     InterfaceDeclaration(modifiers)
+   |
+     UnmodifiedEnumDeclaration(modifiers)
+   |
+     AnnotationTypeDeclaration(modifiers)
+   |
+     AspectDeclaration(modifiers)
+  )
+}
+
+void AspectDeclaration(String modifiers) :
+{ Token t; }
+{
+  "aspect" { pushTopLevelOrAspect("aspect"); }
+    t = <IDENTIFIER> {
+    enclosingAspect = t.image;
+    root.registerAspect(enclosingAspect, Unparser.unparseComment(jjtThis));
+  }
+  AspectBody()
+  { popTopLevelOrAspect(); enclosingAspect = ""; }
+}
+
+void AspectBody() :
+{}
+{
+  "{" ( AspectBodyDeclaration() )* "}"
+}
+
+void AspectBodyDeclaration() :
+{}
+{
+  LOOKAHEAD(<REFINE> <IDENTIFIER> "eq" <IDENTIFIER> "." <IDENTIFIER> "(" [<INT> <IDENTIFIER>] ")" "." <IDENTIFIER>)
+  AspectRefineInhEquation()
+|
+  LOOKAHEAD(<REFINE> <IDENTIFIER> "eq")
+  AspectRefineSynEquation()
+|
+  LOOKAHEAD(AspectRefineMethodDeclarationLookahead())
+  AspectRefineMethodDeclaration()
+|
+  LOOKAHEAD(<REFINE>)
+  AspectRefineConstructorDeclaration()
+|
+  LOOKAHEAD( Modifiers() "class" )
+  AspectClassDeclaration()
+|
+  LOOKAHEAD( Modifiers() "interface" )
+  AspectInterfaceDeclaration()
+|
+  LOOKAHEAD( Modifiers() "enum" )
+  AspectEnumDeclaration()
+|
+  LOOKAHEAD( ( Annotation() )* "syn" )
+  AspectSynAttributeDeclaration()
+|
+  LOOKAHEAD( ( Annotation() )* "inh" )
+  AspectInhAttributeDeclaration()
+|
+  LOOKAHEAD( "rewrite" )
+  AspectRewrite()
+|
+  LOOKAHEAD( ( Annotation() )* "eq" <IDENTIFIER> "." <IDENTIFIER> "(" [<INT> <IDENTIFIER>] ")" "." )
+  AspectInhEquation()
+|
+  LOOKAHEAD( ( Annotation() )* "eq" )
+  AspectSynEquation()
+|
+  LOOKAHEAD( <IDENTIFIER> "implements" )
+  AspectAddInterface()
+|
+  LOOKAHEAD( <IDENTIFIER> "extends" )
+  AspectExtendInterface()
+|
+  LOOKAHEAD( ( Annotation() )* "coll" )
+  CollectionAttribute()
+|
+  LOOKAHEAD( <IDENTIFIER> "contributes" )
+  CollectionContribution()
+|
+  LOOKAHEAD( AspectMethodDeclarationLookahead() )
+  AspectMethodDeclaration()
+|
+  LOOKAHEAD( Modifiers() <IDENTIFIER> "." <IDENTIFIER> "(" )
+  AspectConstructorDeclaration()
+|
+  LOOKAHEAD( AspectFieldDeclarationLookahead() )
+  AspectFieldDeclaration()
+|
+  LOOKAHEAD( ( "cache" | "uncache" ) )
+  AspectCacheDeclaration()
+}
+
+/**
+ * This production is used for aspects generated by JastAdd and includes an EOF
+ */
+void AspectBodyDeclarationsEOF() :
+{}
+{
+  ( AspectBodyDeclaration() )* <EOF>
+}
+
+void AspectClassDeclaration() :
+{
+  Token t;
+  Token first;
+  String outerClassName;
+  String name = "";
+  SimpleNode nameList = null;
+  String modifiers;
+  SimpleNode node;
+  org.jastadd.ast.AST.TypeDecl typeDecl = null;
+  String typeParameters;
+}
+{
+  modifiers = Modifiers()
+  first = "class"
+  t = <IDENTIFIER> {
+    pushTopLevelOrAspect("class");
+    outerClassName = className;
+    className = t.image;
+    typeDecl = root.findClassDecl(className, Unparser.unparseComment(jjtThis),
+        fileName, first.beginLine, enclosingAspect);
+    typeDecl.modifiers = modifiers;
+  }
+  [ typeParameters = TypeParameters() { typeDecl.typeParameters = typeParameters; } ]
+  [ "extends"
+    node = ClassOrInterfaceType() {
+      name = Unparser.unparse(node);
+      if (!name.equals("") &&  typeDecl instanceof org.jastadd.ast.AST.ClassDecl) {
+        ((org.jastadd.ast.AST.ClassDecl)typeDecl).extendsName = name;
+      }
+    }
+  ]
+  [ "implements" nameList = TypeNameList() { root.addInterface(nameList, className, fileName); } ]
+  AspectClassBody() { className = outerClassName; popTopLevelOrAspect(); }
+}
+
+void AspectClassBody() :
+{
+  SimpleNode n;
+}
+{
+  "{" ( n = ClassBodyDeclaration() { root.addClassBodyDecl(n, className, fileName, enclosingAspect); } )* "}"
+}
+
+void AspectInterfaceDeclaration() :
+{
+  Token t;
+  Token first;
+  String outerClassName;
+  SimpleNode nameList = null;
+  org.jastadd.ast.AST.TypeDecl typeDecl = null;
+  String typeParameters;
+  String modifiers;
+}
+{
+  modifiers = Modifiers()
+  first = "interface"
+  t = <IDENTIFIER> {
+    pushTopLevelOrAspect("interface");
+    outerClassName = className;
+    className = t.image;
+    typeDecl = root.findInterfaceDecl(className, Unparser.unparseComment(jjtThis),
+        fileName, first.beginLine, enclosingAspect);
+    typeDecl.modifiers = modifiers;
+  }
+  [ typeParameters = TypeParameters() { typeDecl.typeParameters = typeParameters; } ]
+  [ "extends" nameList = TypeNameList() { root.addInterface(nameList, className, fileName); } ]
+  "{" ( AspectInterfaceMemberDeclaration() )* "}" { className = outerClassName; popTopLevelOrAspect(); }
+}
+
+void AspectInterfaceMemberDeclaration() :
+{}
+{
+  LOOKAHEAD( Modifiers() "class" )
+  AspectNestedClassDeclaration()
+|
+  LOOKAHEAD( Modifiers() "interface" )
+  AspectNestedInterfaceDeclaration()
+|
+  LOOKAHEAD("syn")
+  AspectInterfaceSynAttributeDeclaration()
+|
+  LOOKAHEAD("inh")
+  AspectInterfaceInhAttributeDeclaration()
+|
+  LOOKAHEAD( AspectInterfaceMethodDeclarationLookahead() )
+  AspectInterfaceMethodDeclaration()
+|
+  AspectInterfaceFieldDeclaration()
+}
+
+void AspectInterfaceSynAttributeDeclaration() :
+{ String attrType;
+  Token attrName;
+  Token t;
+  Token first, last;
+
+  String type;
+  Token name;
+  String targetName;
+
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+
+  SimpleNode eq = null;
+
+  boolean init = false;
+  boolean isLazy = false;
+  boolean isFinal = false;
+  SimpleNode bottomValue = null;
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseSkipComment(annotation)); } )*
+
+  "syn" { first = token; } ["lazy" {isLazy = true;}] ["final" {isFinal = true;}]
+  attrType = AspectType() attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+  ")"
+
+  [
+    <CIRCULAR> <LBRACKET> bottomValue = Expression() <RBRACKET>
+  ]
+
+  ";" { last = token; }
+  {
+    root.addSynDecl(attrName.image, attrType, className,
+        isLazy, fileName, first.beginLine, last.endLine, list,
+        bottomValue == null ? "" : Unparser.unparse(bottomValue),
+        isFinal, false, jjtThis, enclosingAspect, annotations);
+
+  }
+}
+
+void AspectInterfaceInhAttributeDeclaration() :
+{ String attrType;
+  Token attrName;
+  Token t;
+  Token first, last;
+
+  String type;
+  Token name;
+  String targetName;
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+  SimpleNode bottomValue = null;
+  boolean isLazy = false;
+  boolean isFinal = false;
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparse(annotation)); } )*
+
+  "inh" { first = token; } ["lazy" {isLazy = true;}] ["final" {isFinal = true;}] attrType = AspectType()
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+
+  ")"
+
+  [
+    <CIRCULAR> <LBRACKET> bottomValue = Expression() <RBRACKET>
+  ]
+
+  ";"
+  {
+    last = token;
+    root.addInhDecl(attrName.image, attrType, className,
+        isLazy, fileName, first.beginLine,
+        last.endLine, list, bottomValue == null ? "" : Unparser.unparse(bottomValue),
+        isFinal, false, jjtThis, enclosingAspect, annotations);
+  }
+}
+
+void AspectInterfaceMethodDeclarationLookahead() :
+{}
+{
+  ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" )*
+  AspectResultType() JavaIdentifier() "("
+}
+
+void AspectInterfaceMethodDeclaration() :
+{
+  Token t;
+}
+{
+  ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" )*
+  AspectResultType() MethodDeclarator() [ "throws" NameList() ]
+  ";" {
+    root.addClassBodyDecl(jjtThis, className, fileName, enclosingAspect);
+  }
+}
+
+void AspectInterfaceFieldDeclaration() :
+{
+  Token t;
+  String modifiers;
+}
+{
+  modifiers = Modifiers()
+  AspectType() VariableDeclarator() ( "," VariableDeclarator() )* ";"
+  {
+    root.addClassBodyDecl(jjtThis, className, fileName, enclosingAspect);
+  }
+}
+
+void AspectNestedInterfaceDeclaration() :
+{
+  String outerClassName = className;
+  className = "D$u$m$m$y";
+  String modifiers;
+}
+{
+  modifiers = Modifiers()
+  "interface" { pushTopLevelOrAspect("interface"); } <IDENTIFIER>
+  [ TypeParameters() ]
+  [ "extends" TypeNameList() ]
+  "{" ( InterfaceMemberDeclaration() )* "}"
+  {
+    className = outerClassName;
+    root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    popTopLevelOrAspect();
+  }
+}
+
+void AspectNestedClassDeclaration() :
+{
+  String outerClassName = className;
+  className = "D$u$m$m$y";
+  String modifiers;
+  String typeParameters;
+}
+{
+  modifiers = Modifiers()
+  "class" { pushTopLevelOrAspect("class"); } <IDENTIFIER>
+  [ TypeParameters() ]
+  [ "extends" ClassOrInterfaceType() ]
+  [ "implements" TypeNameList() ]
+  ClassBody()
+  {
+    className = outerClassName;
+    root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    popTopLevelOrAspect();
+  }
+}
+
+void AspectMethodDeclarationLookahead() :
+{}
+{
+  Modifiers()
+  [ TypeParameters() ]
+  AspectResultType() <IDENTIFIER> "." JavaIdentifier() "("
+}
+
+void AspectMethodDeclaration() :
+{Token t;}
+{
+  Modifiers()
+  [ TypeParameters() ]
+  AspectResultType() t = <IDENTIFIER> "." { className = t.image; } MethodDeclarator() [ "throws" NameList() ]
+  ( Block() | ";" ) {
+    root.addClassBodyDecl(jjtThis, className, fileName, enclosingAspect);
+  }
+}
+
+void AspectRefineMethodDeclarationLookahead() :
+{}
+{
+  <REFINE> [LOOKAHEAD(<IDENTIFIER>)<IDENTIFIER>]
+  Modifiers()
+  [ TypeParameters() ]
+  AspectResultType() <IDENTIFIER> "." JavaIdentifier() "("
+}
+
+void AspectRefineMethodDeclaration() :
+{Token t; String aspectName = ""; String secondAspectName; }
+{
+  t = <REFINE> { t.image = ""; } [LOOKAHEAD(<IDENTIFIER>) t = <IDENTIFIER> { aspectName = t.image; t.image = ""; }]
+  Modifiers()
+  [ TypeParameters() ]
+  AspectResultType() t = <IDENTIFIER> "." { className = t.image; } MethodDeclarator() [ "throws" NameList() ]
+  ( Block() | ";" ) {
+    root.addRefinedClassBodyDecl(jjtThis, className, fileName, aspectName, enclosingAspect);
+  }
+}
+void AspectConstructorDeclaration() :
+{Token t;}
+{
+  Modifiers()
+  t = <IDENTIFIER> "." { className = t.image; } <IDENTIFIER> FormalParameters() [ "throws" NameList() ]
+  "{"
+    [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ]
+    ( BlockStatement() )*
+  "}"
+  {
+    root.addClassBodyDecl(jjtThis, className, fileName, enclosingAspect);
+  }
+}
+
+void AspectRefineConstructorDeclaration() :
+{Token t; String aspectName; String secondAspectName; }
+{
+  t = <REFINE> { t.image = ""; } t = <IDENTIFIER> { aspectName = t.image; t.image = ""; } [ "public" | "protected" | "private" ]
+  t = <IDENTIFIER> "." { className = t.image; } <IDENTIFIER> FormalParameters() [ "throws" NameList() ]
+  "{"
+    [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ]
+    ( BlockStatement() )*
+  "}"
+  {
+    root.addRefinedClassBodyDecl(jjtThis, className, fileName, aspectName, enclosingAspect);
+  }
+}
+
+void AspectFieldDeclarationLookahead() :
+{}
+{
+  Modifiers()
+  AspectType() <IDENTIFIER> "." VariableDeclarator()
+}
+
+void AspectFieldDeclaration() :
+{Token t;}
+{
+  Modifiers()
+  AspectType() t = <IDENTIFIER> "." { className = t.image; } VariableDeclarator() ( "," VariableDeclarator() )* ";" {
+    root.addClassBodyDecl(jjtThis, className, fileName, enclosingAspect);
+  }
+}
+
+void AspectSynAttributeDeclaration() :
+{ String attrType;
+  Token attrName;
+  Token t;
+  Token first, last;
+
+  String type;
+  Token name;
+  String targetName;
+
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+
+  SimpleNode eq = null;
+
+  boolean init = false;
+  boolean isLazy = false;
+  SimpleNode bottomValue = null;
+  boolean isFinal = false;
+  boolean isNTA = false;
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseSkipComment(annotation)); } )*
+
+  "syn" { first = token; }
+
+  [<NTA> {isNTA = true; }]
+
+  ["lazy" {isLazy = true;}]
+
+  ["final" {isFinal = true; }]
+
+  attrType = AspectType()
+
+  t = <IDENTIFIER> "." { targetName = t.image; }
+
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+  ")"
+
+  [
+    <CIRCULAR> <LBRACKET> bottomValue = Expression() <RBRACKET>
+  ]
+
+  ( ("=" eq = Expression() ";" { last = token; init = true;} )
+  | (eq = Block() { last = token; init = true;})
+  | ";" { last = token; } )
+
+  {
+    root.addSynDecl(attrName.image, attrType, targetName,
+        isLazy, fileName, first.beginLine,
+        last.endLine, list, bottomValue == null ? "" : Unparser.unparse(bottomValue),
+        isFinal, isNTA, jjtThis, enclosingAspect, annotations);
+
+    if (init) {
+      root.addSynEq(attrName.image, targetName, eq, fileName, first.beginLine,
+          last.endLine, (org.jastadd.ast.AST.List)list.fullCopy(), jjtThis,
+          enclosingAspect, annotations);
+    }
+  }
+}
+
+void AspectInhAttributeDeclaration() :
+{ String attrType;
+  Token attrName;
+  Token t;
+  Token first, last;
+
+  String type;
+  Token name;
+  String targetName;
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+  SimpleNode bottomValue = null;
+  boolean isLazy = false;
+  boolean isFinal = false;
+  boolean isNTA = false;
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseSkipComment(annotation)); } )*
+
+  "inh" { first = token; } [<NTA> {isNTA = true;}] ["lazy" {isLazy = true;}] ["final" {isFinal = true; }] attrType = AspectType()
+  t = <IDENTIFIER> "." { targetName = t.image; }
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+
+  ")"
+
+  [
+    <CIRCULAR> <LBRACKET> bottomValue = Expression() <RBRACKET>
+  ]
+
+  ";"
+  {
+    last = token;
+    root.addInhDecl(attrName.image, attrType, targetName,
+        isLazy, fileName, first.beginLine,
+        last.endLine, list, bottomValue == null ? "" : Unparser.unparse(bottomValue),
+        isFinal, isNTA, jjtThis, enclosingAspect, annotations);
+  }
+}
+
+
+void AspectRewrite() :
+{
+  Token t;
+  SimpleNode cond;
+  SimpleNode eq;
+  Token first, last;
+
+  Token parent = null;
+  Token child = null;
+  String type;
+}
+{
+  "rewrite" {cond = null; first = token;} t = <IDENTIFIER> { className = t.image; }
+  [<IDENTIFIER> parent = <IDENTIFIER> "." child = <IDENTIFIER> <LPAREN> <RPAREN>]
+  <LBRACE>
+    ( ["when" { first = token; } <LPAREN> cond = Expression() <RPAREN>]
+      "to" type = AspectType() ( (eq = Expression() ";" { last = token; }) | eq = Block() { last = token; } )
+      {
+        if (parent != null && child != null) {
+          root.addRewriteList(className, cond, eq, type, fileName, first.beginLine, last.endLine, parent.image, child.image, enclosingAspect);
+        } else {
+          root.addRewrite(className, cond, eq, type, fileName, first.beginLine, last.endLine, enclosingAspect);
+        }
+        cond = null;
+      }
+    )+
+  <RBRACE>
+}
+
+void AspectSynEquation() :
+{
+  String t;
+  Token first, last;
+  SimpleNode eq;
+  String type;
+  Token name;
+  Token attrName;
+  Token targetName;
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseSkipComment(annotation)); } )*
+
+  "eq" { first = token; }
+
+  targetName = <IDENTIFIER> "."
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+
+  ")"
+
+  ( ("=" eq = Expression() ";" { last = token; })
+  | eq = Block() { last = token; } )
+
+  {
+    root.addSynEq(attrName.image, targetName.image, eq, fileName,
+        first.beginLine, last.endLine, list, jjtThis, enclosingAspect,
+        annotations);
+  }
+
+}
+void AspectRefineSynEquation() :
+{
+  String t;
+  Token first, last;
+  SimpleNode eq;
+  String type;
+  Token name;
+  Token attrName;
+  Token targetName;
+  Token aspectName;
+  Token secondAspectName;
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+}
+{
+  <REFINE> aspectName = <IDENTIFIER>
+  "eq" { first = token; }
+
+  targetName = <IDENTIFIER> "."
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+
+  ")"
+
+  (  ( ("=" eq = Expression() ";" { last = token; })
+    | eq = Block() { last = token; } )
+    { root.addRefinedSynEq(attrName.image, targetName.image, eq, fileName, first.beginLine, last.endLine, list, aspectName.image, jjtThis, enclosingAspect); }
+  )
+}
+
+void AspectInhEquation() :
+{
+  String t;
+  Token first, last;
+  SimpleNode eq;
+  Token name;
+  String type;
+  Token attrName;
+  Token targetName;
+  Token childName;
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+  org.jastadd.ast.AST.Parameter p = null;
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseSkipComment(annotation)); } )*
+
+  "eq" { first = token; }
+
+  targetName = <IDENTIFIER> "."
+  childName = <IDENTIFIER> "(" [ <INT> name = <IDENTIFIER> { p = new org.jastadd.ast.AST.Parameter("int", name.image); } ] ")" "."
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+
+  ")"
+
+  ( ("=" eq = Expression() ";" { last = token; })
+  | eq = Block() { last = token; } )
+
+  {
+    root.addInhEq(childName.image, attrName.image, targetName.image, eq,
+        fileName, first.beginLine, last.endLine, list, p, jjtThis,
+        enclosingAspect, annotations);
+  }
+}
+void AspectRefineInhEquation() :
+{
+  String t;
+  Token first, last;
+  SimpleNode eq;
+  Token name;
+  String type;
+  Token attrName;
+  Token targetName;
+  Token childName;
+  org.jastadd.ast.AST.List list = new org.jastadd.ast.AST.List();
+  org.jastadd.ast.AST.Parameter p = null;
+  Token aspectName;
+}
+{
+  <REFINE> aspectName = <IDENTIFIER> "eq" { first = token; }
+
+  targetName = <IDENTIFIER> "."
+  childName = <IDENTIFIER> "(" [ <INT> name = <IDENTIFIER> { p = new org.jastadd.ast.AST.Parameter("int", name.image); } ] ")" "."
+  attrName = AttributeName()
+
+  "("
+  [
+    type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); }
+    ( "," type = Type() name = <IDENTIFIER> { list.add(new org.jastadd.ast.AST.Parameter(type, name.image)); })*
+  ]
+
+  ")"
+
+  ( ("=" eq = Expression() ";" { last = token; })
+  | eq = Block() { last = token; } )
+
+  {
+    root.addRefinedInhEq(childName.image, attrName.image, targetName.image, eq, fileName, first.beginLine, last.endLine, list, p, aspectName.image, jjtThis, enclosingAspect);
+  }
+}
+
+void CollectionAttribute():
+{
+  Token t;
+  Token first, last;
+  String attrType;
+  String targetName;
+  Token attrName;
+  String combOp = "add";
+  String rootName = null;
+  SimpleNode startValue = null;
+  boolean isCircular = false;
+
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseSkipComment(annotation)); } )*
+  "coll" { first = token; }
+  attrType = AspectType() t = <IDENTIFIER> "." { targetName = t.image; } attrName = AttributeName() "(" ")"
+  [ <CIRCULAR> { isCircular = true; } ]
+  [ <LBRACKET> startValue = Expression() <RBRACKET> ]
+  [ <WITH> t = <IDENTIFIER> { combOp = t.image; } ]
+  [ <ROOT> t = <IDENTIFIER> { rootName = t.image; } ]
+  ";"
+  {
+    last = token;
+    root.addCollDecl(attrName.image, attrType, targetName, fileName,
+        first.beginLine, last.endLine,
+        startValue == null ? "new " + attrType + "()" : Unparser.unparse(startValue),
+        combOp,
+        isCircular, annotations, jjtThis, rootName, enclosingAspect);
+    token_source.SwitchTo(DEFAULT);
+  }
+}
+
+void CollectionContribution():
+{
+  Token t;
+  Token first, last;
+  SimpleNode block;
+  SimpleNode value = null;
+  SimpleNode condition = null;
+  SimpleNode ntaExpression = null;
+  String targetName;
+  String targetAttributeName;
+  String attributeType;
+  String surveyBlock = null;
+  SimpleNode reference = null;
+  org.jastadd.ast.AST.List contributionList = new org.jastadd.ast.AST.List();
+  boolean iterableValue = false;
+  boolean iterableTarget = false;
+  ArrayList<String> annotations = new ArrayList<String>();
+  SimpleNode annotation;
+}
+{
+  ( annotation = Annotation() { annotations.add(Unparser.unparseComment(annotation)); } )*
+  t = <IDENTIFIER> { first = token; attributeType = t.image; }
+  "contributes"
+  (
+    LOOKAHEAD("nta") "nta"
+    ntaExpression = Expression()
+    "to" t = <IDENTIFIER> "." { targetName = t.image; } t = AttributeName() { targetAttributeName = t.image; } "(" ")"
+  | [ LOOKAHEAD("each") "each" { iterableValue = true; } ]
+    value = Expression()
+    [ "when" condition = Expression() ]
+    "to" t = <IDENTIFIER> "." { targetName = t.image; } t = AttributeName() { targetAttributeName = t.image; } "(" ")"
+    [ "for" [ LOOKAHEAD("each") "each" { iterableTarget = true; } ] reference = Expression() ]
+  | block = Block() { surveyBlock = Unparser.unparse(block); }
+    "to" t = <IDENTIFIER> "." { targetName = t.image; } t = AttributeName() { targetAttributeName = t.image; } "(" ")"
+  )
+  ";" { last = token; }
+  {
+    if (surveyBlock != null) {
+      root.addCustomSurveyBlock(targetName,
+          targetAttributeName,
+          attributeType,
+          surveyBlock,
+          fileName,
+          first.beginLine,
+          last.endLine,
+          jjtThis,
+          enclosingAspect,
+          annotations);
+    } else if (ntaExpression != null) {
+      root.addCustomSurveyExpression(targetName,
+          targetAttributeName,
+          attributeType,
+          Unparser.unparse(ntaExpression),
+          fileName,
+          first.beginLine,
+          last.endLine,
+          jjtThis,
+          enclosingAspect,
+          annotations);
+    } else {
+      org.jastadd.ast.AST.CollEq equ = root.addCollEq(targetName,
+          targetAttributeName,
+          attributeType,
+          reference == null ? "" : Unparser.unparse(reference),
+          fileName,
+          first.beginLine,
+          last.endLine,
+          iterableValue,
+          iterableTarget,
+          jjtThis,
+          enclosingAspect,
+          annotations);
+      // TODO(joqvist): make the returned equ non-null.
+      if (equ != null) {
+        equ.setValue(Unparser.unparse(value));
+        if (condition != null) {
+            equ.setCondition(Unparser.unparse(condition));
+        }
+      }
+    }
+  }
+}
+
+void AspectAddInterface() :
+{
+  Token first, last;
+  Token targetName;
+  SimpleNode nameList;
+}
+{
+  targetName = <IDENTIFIER> { first = token; }
+  "implements"
+  nameList = TypeNameList()
+  ";"
+  {
+    last = token;
+    root.addInterface(nameList, targetName.image, fileName);
+  }
+
+}
+
+void AspectExtendInterface() :
+{
+  Token first, last;
+  Token targetName;
+  SimpleNode nameList;
+}
+{
+  targetName = <IDENTIFIER> { first = token; }
+  "extends"
+  nameList = TypeNameList()
+  ";"
+  {
+    last = token;
+    root.extendInterface(nameList, targetName.image, fileName);
+  }
+
+}
+
+
+/*
+ * Declaration syntax follows.
+ */
+
+void ClassDeclaration(String modifiers) :
+{ Token t;
+  Token first;
+  SimpleNode node;
+  String outerClassName;
+  StringBuffer name = new StringBuffer();
+  org.jastadd.ast.AST.TypeDecl typeDecl = null;
+  SimpleNode nameList = null;
+  String typeParameters;
+}
+{
+  first = "class"
+  t = <IDENTIFIER> {
+    pushTopLevelOrAspect("class");
+    outerClassName = className;
+    className = t.image;
+    typeDecl = root.findClassDecl(className, Unparser.unparseComment(jjtThis),
+        fileName, first.beginLine, enclosingAspect);
+    typeDecl.modifiers = modifiers;
+  }
+  [ typeParameters = TypeParameters() { typeDecl.typeParameters = typeParameters; } ]
+  [ "extends"
+    node = ClassOrInterfaceType() { name.append(Unparser.unparse(node)); }
+    { if(!name.toString().equals("") && typeDecl instanceof org.jastadd.ast.AST.ClassDecl)
+      ((org.jastadd.ast.AST.ClassDecl)typeDecl).extendsName = name.toString();
+    }
+  ]
+  [ "implements" nameList = TypeNameList() { root.addInterface(nameList, className, fileName);} ]
+  ClassBody() { className = outerClassName; popTopLevelOrAspect(); }
+}
+
+SimpleNode TypeNameList():
+{}
+{
+  (
+   ClassOrInterfaceType()
+   ( "," ClassOrInterfaceType() )*
+  )
+   { return jjtThis; }
+}
+
+
+/* Added action to set classname and add class to allClasses */
+void UnmodifiedClassDeclaration(String modifiers) :
+{
+  Token t;
+  SimpleNode nameList;
+  String outerClassName;
+}
+{
+  "class" t = <IDENTIFIER> { pushTopLevelOrAspect("class"); outerClassName = className; className = t.image; }
+  [ TypeParameters() ]
+  [ "extends" ClassOrInterfaceType() ] [ "implements" nameList = TypeNameList() ]
+  ClassBody() { className = outerClassName; popTopLevelOrAspect(); }
+  { if (shouldAddClassBodyDecl()) {
+      root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+
+void AspectEnumDeclaration():
+{
+  Token t;
+  Token first;
+  String outerClassName;
+  String modifiers;
+  SimpleNode node;
+  org.jastadd.ast.AST.EnumDecl typeDecl = null;
+}
+{
+  modifiers = Modifiers()
+  first = "enum"
+  t = <IDENTIFIER> {
+    pushTopLevelOrAspect("enum");
+    outerClassName = className;
+    className = t.image;
+    typeDecl = (org.jastadd.ast.AST.EnumDecl) root.findEnumDecl(className, Unparser.unparseComment(jjtThis),
+        fileName, first.beginLine, enclosingAspect);
+    typeDecl.modifiers = modifiers;
+    typeDecl.simpleNode = jjtThis;
+  }
+  [ "implements" TypeNameList() ]
+  EnumBody() { className = outerClassName; popTopLevelOrAspect(); }
+}
+
+void UnmodifiedEnumDeclaration(String modifiers):
+{}
+{
+  "enum" { pushTopLevelOrAspect("enum"); } JavaIdentifier()
+  [ "implements" TypeNameList() ]
+  EnumBody()
+  { popTopLevelOrAspect();
+    if (shouldAddClassBodyDecl()) {
+      root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+void EnumBody():
+{
+  SimpleNode n;
+}
+{
+  "{"
+  EnumConstant() ( "," EnumConstant() )*
+  [ ";" ( ClassBodyDeclaration() )* ]
+  "}"
+}
+
+void EnumConstant():
+{}
+{
+  JavaIdentifier() [ Arguments() ] [ ClassBody() ]
+}
+
+String TypeParameters():
+{}
+{
+  (
+   "<" TypeParameter() ( "," TypeParameter() )* ">"
+  )
+  { return Unparser.unparse(jjtThis); }
+}
+
+void TypeParameter():
+{}
+{
+   JavaIdentifier() [ TypeBound() ]
+}
+
+void TypeBound():
+{}
+{
+   "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )*
+}
+
+
+
+
+void ClassBody() :
+{}
+{
+  "{" ( ClassBodyDeclaration() )* "}"
+}
+
+/* Added one branch corresponding to attribute declarations
+   and two branches  for syn and inh attribute equations  */
+SimpleNode ClassBodyDeclaration() :
+{
+  String modifiers;
+}
+{
+  (
+  LOOKAHEAD(2)
+  Initializer()
+|
+  modifiers = Modifiers()
+  (
+    UnmodifiedClassDeclaration(modifiers)
+  |
+    UnmodifiedInterfaceDeclaration(modifiers)
+  |
+    AnnotationTypeDeclaration(modifiers)
+  |
+    UnmodifiedEnumDeclaration(modifiers)
+  |
+    LOOKAHEAD( [TypeParameters() ] JavaIdentifier() "(" )
+    ConstructorDeclaration(modifiers)
+  |
+    LOOKAHEAD( AspectType() JavaIdentifier() ( "[" "]" )* ( "," | "=" | ";" ) )
+    FieldDeclaration(modifiers)
+  |
+    MethodDeclaration(modifiers)
+  )
+|
+  ";"
+  )
+  {
+    return jjtThis;
+  }
+}
+
+void InterfaceDeclaration(String modifiers) :
+{}
+{
+  UnmodifiedInterfaceDeclaration(modifiers)
+}
+
+void UnmodifiedInterfaceDeclaration(String modifiers) :
+{
+  boolean isTopLevel;
+  Token t;
+  Token first;
+  String outerClassName;
+  SimpleNode nameList = null;
+  org.jastadd.ast.AST.TypeDecl typeDecl = null;
+  String typeParameters;
+}
+{
+  first = "interface"
+  t = <IDENTIFIER> {
+    isTopLevel = inTopLevelOrAspect();
+    pushTopLevelOrAspect("interface");
+    outerClassName = className;
+    className = t.image;
+    if (isTopLevel) {
+      typeDecl = root.findInterfaceDecl(className, Unparser.unparseComment(jjtThis),
+          fileName, first.beginLine, enclosingAspect);
+      typeDecl.modifiers = modifiers;
+    }
+  }
+  [ typeParameters = TypeParameters() { if (isTopLevel) typeDecl.typeParameters = typeParameters; } ]
+  [ "extends" nameList = TypeNameList() { if (isTopLevel) root.addInterface(nameList, className, fileName); } ]
+  "{" ( InterfaceMemberDeclaration() )* "}" { className = outerClassName; popTopLevelOrAspect(); }
+  { if (shouldAddClassBodyDecl()) {
+      root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+void InterfaceMemberDeclaration() :
+{
+  String modifiers;
+}
+{
+  modifiers = Modifiers()
+  (
+    UnmodifiedClassDeclaration(modifiers)
+  |
+    UnmodifiedInterfaceDeclaration(modifiers)
+  |
+    LOOKAHEAD( AspectType() JavaIdentifier() ( "[" "]" )* ( "," | "=" | ";" ) )
+    FieldDeclaration(modifiers)
+  |
+    MethodDeclaration(modifiers)
+  )
+|
+  ";"
+}
+
+void FieldDeclaration(String modifiers) :
+{}
+{
+  AspectType() VariableDeclarator() ( "," VariableDeclarator() )* ";"
+  { if (shouldAddClassBodyDecl()) {
+      root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+void VariableDeclarator() :
+{}
+{
+  VariableDeclaratorId() [ "=" VariableInitializer() ]
+
+}
+
+void  VariableDeclaratorId() :
+{}
+{
+  JavaIdentifier() ( "[" "]" )*
+}
+
+void VariableInitializer() :
+{}
+{
+  ArrayInitializer()
+|
+  Expression()
+}
+
+void ArrayInitializer() :
+{}
+{
+  "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}"
+}
+
+void MethodDeclaration(String modifiers) :
+{}
+{
+  [ TypeParameters() ]
+  AspectResultType()  MethodDeclarator() [ "throws" NameList() ]
+  ( Block() | ";" )
+  { if (shouldAddClassBodyDecl()) {
+      root.addMethodDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+void MethodDeclarator() :
+{}
+{
+  JavaIdentifier() FormalParameters() ( "[" "]" )*
+}
+
+void FormalParameters() :
+{}
+{
+  "(" [ FormalParameter() ( "," FormalParameter() )* ] ")"
+}
+
+void FormalParameter() :
+{}
+{
+  [ "final" ] Type() ["..."] VariableDeclaratorId()
+}
+
+void ConstructorDeclaration(String modifiers) :
+{}
+{
+  [ TypeParameters() ]
+  JavaIdentifier() FormalParameters() [ "throws" NameList() ]
+  "{"
+    [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ]
+    ( BlockStatement() )*
+  "}"
+  { if (shouldAddClassBodyDecl()) {
+      root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+void ExplicitConstructorInvocation() :
+{}
+{
+  LOOKAHEAD("this" Arguments() ";")
+  "this" Arguments() ";"
+|
+  [ LOOKAHEAD(2) PrimaryExpression() "." ] "super" Arguments() ";"
+}
+
+void Initializer() :
+{}
+{
+  [ "static" ] Block()
+}
+
+
+/*
+ * Type, name and expression syntax follows.
+ */
+
+// Attribute type names can not start with JastAdd reserved words such as 'syn', 'eq', etc.
+String AspectType():
+{}
+{
+ (
+   LOOKAHEAD(2) AspectReferenceType()
+ |
+   LOOKAHEAD(2) PrimitiveType() ( LOOKAHEAD(2) "[" "]" )+
+ |
+   PrimitiveType()
+ )
+ { return Unparser.unparse(jjtThis); }
+}
+
+void AspectResultType():
+{}
+{
+  "void"
+ |
+  AspectType()
+}
+
+void AspectReferenceType():
+{}
+{
+  ( AspectClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" )*
+}
+
+SimpleNode AspectClassOrInterfaceType():
+{}
+{
+  (
+  <IDENTIFIER> [ LOOKAHEAD(2) TypeArguments() ]
+  ( LOOKAHEAD(2) "." JavaIdentifier() [ LOOKAHEAD(2) TypeArguments() ] )*
+  )
+  { return jjtThis; }
+}
+
+/*Changed to return string */
+String Type():
+{}
+{
+ (
+   LOOKAHEAD(2) ReferenceType()
+ |
+   PrimitiveType()
+ )
+ { return Unparser.unparse(jjtThis); }
+}
+
+void ReferenceType():
+{}
+{
+   PrimitiveType() ( LOOKAHEAD(2) "[" "]" )+
+  |
+   ( ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" )*
+}
+
+SimpleNode ClassOrInterfaceType():
+{}
+{
+  (
+  JavaIdentifier() [ LOOKAHEAD(2) TypeArguments() ]
+  ( LOOKAHEAD(2) "." JavaIdentifier() [ LOOKAHEAD(2) TypeArguments() ] )*
+  )
+  { return jjtThis; }
+}
+
+void TypeArguments():
+{}
+{
+   "<" [ TypeArgument() ( "," TypeArgument() )* ] ">"
+}
+
+void TypeArgument():
+{}
+{
+   ReferenceType()
+ |
+   "?" [ WildcardBounds() ]
+}
+
+void WildcardBounds():
+{}
+{
+   "extends" ReferenceType()
+ |
+   "super" ReferenceType()
+}
+
+void PrimitiveType():
+{}
+{
+  "boolean"
+|
+  "char"
+|
+  "byte"
+|
+  "short"
+|
+  "int"
+|
+  "long"
+|
+  "float"
+|
+  "double"
+}
+
+void ResultType():
+{}
+{
+  "void"
+|
+  Type()
+}
+
+/* Changed to return token */
+String Name() :
+/*
+ * A lookahead of 2 is required below since "Name" can be followed
+ * by a ".*" when used in the context of an "ImportDeclaration".
+ */
+{}
+{
+  (JavaIdentifier()
+  ( LOOKAHEAD(2) "." JavaIdentifier()
+  )*
+  )
+  { return Unparser.unparse(jjtThis); }
+}
+
+SimpleNode NameList() :
+{}
+{
+  (Name()
+  ( "," Name()
+  )*
+  )
+  {
+    return jjtThis;
+  }
+}
+
+
+/*
+ * Expression syntax follows.
+ */
+
+SimpleNode Expression() :
+/*
+ * This expansion has been written this way instead of:
+ *   Assignment() | ConditionalExpression()
+ * for performance reasons.
+ * However, it is a weakening of the grammar for it allows the LHS of
+ * assignments to be any conditional expression whereas it can only be
+ * a primary expression.  Consider adding a semantic predicate to work
+ * around this.
+ */
+{}
+{
+(
+  LOOKAHEAD(LambdaExpression())
+  LambdaExpression()
+|
+  ConditionalExpression()
+  [
+    LOOKAHEAD(2)
+    AssignmentOperator() Expression()
+  ]
+)
+  {
+    return jjtThis;
+  }
+}
+
+void AssignmentOperator() :
+{}
+{
+  "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|="
+}
+
+void ConditionalExpression() :
+{}
+{
+  ConditionalOrExpression() [ "?" Expression() ":" ConditionalExpression() ]
+}
+
+void ConditionalOrExpression() :
+{}
+{
+  ConditionalAndExpression() ( "||" ConditionalAndExpression() )*
+}
+
+void ConditionalAndExpression() :
+{}
+{
+  InclusiveOrExpression() ( "&&" InclusiveOrExpression() )*
+}
+
+void InclusiveOrExpression() :
+{}
+{
+  ExclusiveOrExpression() ( "|" ExclusiveOrExpression() )*
+}
+
+void ExclusiveOrExpression() :
+{}
+{
+  AndExpression() ( "^" AndExpression() )*
+}
+
+void AndExpression() :
+{}
+{
+  EqualityExpression() ( "&" EqualityExpression() )*
+}
+
+void EqualityExpression() :
+{}
+{
+  InstanceOfExpression() ( ( "==" | "!=" ) InstanceOfExpression() )*
+}
+
+void InstanceOfExpression() :
+{}
+{
+  RelationalExpression() [ "instanceof" Type() ]
+}
+
+void RelationalExpression() :
+{}
+{
+  ShiftExpression() ( ( "<" | ">" | "<=" | ">=" ) ShiftExpression() )*
+}
+
+void ShiftExpression():
+{}
+{
+  AdditiveExpression() ( ( "<<" | RSIGNEDSHIFT() | RUNSIGNEDSHIFT() ) AdditiveExpression() )*
+}
+
+void AdditiveExpression() :
+{}
+{
+  MultiplicativeExpression() ( ( "+" | "-" ) MultiplicativeExpression() )*
+}
+
+void MultiplicativeExpression() :
+{}
+{
+  UnaryExpression() ( ( "*" | "/" | "%" ) UnaryExpression() )*
+}
+
+void UnaryExpression() :
+{}
+{
+  ( "+" | "-" ) UnaryExpression()
+|
+  PreIncrementExpression()
+|
+  PreDecrementExpression()
+|
+  UnaryExpressionNotPlusMinus()
+}
+
+void PreIncrementExpression() :
+{}
+{
+  "++" PrimaryExpression()
+}
+
+void PreDecrementExpression() :
+{}
+{
+  "--" PrimaryExpression()
+}
+
+void UnaryExpressionNotPlusMinus() :
+{}
+{
+  ( "~" | "!" ) UnaryExpression()
+|
+  LOOKAHEAD( CastLookahead() )
+  CastExpression()
+|
+  PostfixExpression()
+}
+
+// This production is to determine lookahead only.  The LOOKAHEAD specifications
+// below are not used, but they are there just to indicate that we know about
+// this.
+void CastLookahead() :
+{}
+{
+  LOOKAHEAD(2)
+  "(" PrimitiveType()
+|
+  LOOKAHEAD("(" Type() "[")
+  "(" Type() "[" "]"
+|
+  "(" Type() ")" ( "~" | "!" | "(" | JavaIdentifier() | "this" | "super" | "new" | Literal() )
+}
+
+void PostfixExpression() :
+{}
+{
+  PrimaryExpression() [ "++" | "--" ]
+}
+
+void CastExpression() :
+{}
+{
+  LOOKAHEAD("(" PrimitiveType())
+  "(" Type() ")" UnaryExpression()
+|
+  "(" Type() ")" UnaryExpressionNotPlusMinus()
+}
+
+void PrimaryExpression() :
+{}
+{
+  PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )*
+}
+
+void MemberSelector():
+{}
+{
+  "." TypeArguments() JavaIdentifier()
+}
+
+void PrimaryPrefix() :
+{}
+{
+  Literal()
+|
+  "this"
+|
+  "super" "." JavaIdentifier()
+|
+  "(" Expression() ")"
+|
+  AllocationExpression()
+|
+  LOOKAHEAD( ResultType() "." "class" )
+  ResultType() "." "class"
+|
+  Name()
+}
+
+void PrimarySuffix() :
+{}
+{
+  LOOKAHEAD(2)
+  "." "this"
+|
+  LOOKAHEAD(2)
+  "." AllocationExpression()
+|
+  LOOKAHEAD(3)
+  "." TypeArguments() JavaIdentifier()
+|
+  "[" Expression() "]"
+|
+  "." JavaIdentifier()
+|
+  Arguments()
+|
+  LOOKAHEAD(2)
+  "::" "new"
+|
+  LOOKAHEAD(2)
+  "::" JavaIdentifier()
+}
+
+void Literal() :
+{}
+{
+  <INTEGER_LITERAL>
+|
+  <FLOATING_POINT_LITERAL>
+|
+  <CHARACTER_LITERAL>
+|
+  <STRING_LITERAL>
+|
+  BooleanLiteral()
+|
+  NullLiteral()
+}
+
+void BooleanLiteral() :
+{}
+{
+  "true"
+|
+  "false"
+}
+
+void NullLiteral() :
+{}
+{
+  "null"
+}
+
+void Arguments() :
+{}
+{
+  "(" [ ArgumentList() ] ")"
+}
+
+void ArgumentList() :
+{}
+{
+  Expression() ( "," Expression() )*
+}
+
+void AllocationExpression() :
+{ String outerClassName = className;
+  className = "D$u$m$m$y";
+  pushTopLevelOrAspect("expr");
+}
+{
+  (
+  LOOKAHEAD(2)
+  "new" PrimitiveType() ArrayDimsAndInits()
+|
+  "new" ClassOrInterfaceType() [ TypeArguments() ]
+
+    (
+      ArrayDimsAndInits()
+    |
+      Arguments()
+      [ ClassBody() ]
+    )
+  )
+  {
+    className = outerClassName;
+    popTopLevelOrAspect();
+  }
+}
+
+/*
+ * The third LOOKAHEAD specification below is to parse to PrimarySuffix
+ * if there is an expression between the "[...]".
+ */
+void ArrayDimsAndInits() :
+{}
+{
+  LOOKAHEAD(2)
+  ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )*
+|
+  ( "[" "]" )+ ArrayInitializer()
+}
+
+/*
+ * Java 8 expression additions follow.
+ *
+ * New Java 8 expressions: lambdas, method/constructor reference, union types.
+ */
+void LambdaExpression() :
+{}
+{
+  LambdaParameters() "->" ( Expression() | Block() )
+}
+
+void LambdaParameters() :
+{}
+{
+  Name()
+|
+  "(" [ LOOKAHEAD(2) TypedLambdaParameters() | UntypedLambdaParameters() ] ")"
+}
+
+void TypedLambdaParameters() :
+{}
+{
+  Type() Name() ( "," Type() Name() )*
+}
+
+void UntypedLambdaParameters() :
+{}
+{
+  Name() ( "," Name() )*
+}
+
+/*
+ * Statement syntax follows.
+ */
+
+void Statement() :
+{}
+{
+  LOOKAHEAD(2)
+  LabeledStatement()
+|
+  AssertStatement()
+|
+  Block()
+|
+  EmptyStatement()
+|
+  StatementExpression() ";"
+|
+  SwitchStatement()
+|
+  IfStatement()
+|
+  WhileStatement()
+|
+  DoStatement()
+|
+  ForStatement()
+|
+  BreakStatement()
+|
+  ContinueStatement()
+|
+  ReturnStatement()
+|
+  ThrowStatement()
+|
+  SynchronizedStatement()
+|
+  TryStatement()
+}
+
+void AssertStatement():
+{}
+{
+  "assert" Expression() [ ":" Expression() ] ";"
+}
+
+void LabeledStatement() :
+{}
+{
+  JavaIdentifier() ":" Statement()
+}
+
+SimpleNode Block() :
+{}
+{
+  (
+  "{" ( BlockStatement() )* "}"
+  )
+  {
+    return jjtThis;
+  }
+}
+
+void BlockStatement() :
+{}
+{
+  LOOKAHEAD([ "final" ] Type() JavaIdentifier())
+  LocalVariableDeclaration() ";"
+|
+  Statement()
+|
+  UnmodifiedClassDeclaration("")
+}
+
+void LocalVariableDeclaration() :
+{}
+{
+  [ "final" ] Type() VariableDeclarator() ( "," VariableDeclarator() )*
+}
+
+void EmptyStatement() :
+{}
+{
+  ";"
+}
+
+void StatementExpression() :
+/*
+ * The last expansion of this production accepts more than the legal
+ * Java expansions for StatementExpression.  This expansion does not
+ * use PostfixExpression for performance reasons.
+ */
+{}
+{
+  PreIncrementExpression()
+|
+  PreDecrementExpression()
+|
+  PrimaryExpression()
+  [
+    "++"
+  |
+    "--"
+  |
+    AssignmentOperator() Expression()
+  ]
+}
+
+void SwitchStatement() :
+{}
+{
+  "switch" "(" Expression() ")" "{"
+    ( SwitchLabel() ( BlockStatement() )* )*
+  "}"
+}
+
+void SwitchLabel() :
+{}
+{
+  "case" Expression() ":"
+|
+  "default" ":"
+}
+
+void IfStatement() :
+/*
+ * The disambiguating algorithm of JavaCC automatically binds dangling
+ * else's to the innermost if statement.  The LOOKAHEAD specification
+ * is to tell JavaCC that we know what we are doing.
+ */
+{}
+{
+  "if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" Statement() ]
+}
+
+void WhileStatement() :
+{}
+{
+  "while" "(" Expression() ")" Statement()
+}
+
+void DoStatement() :
+{}
+{
+  "do" Statement() "while" "(" Expression() ")" ";"
+}
+
+void ForStatement() :
+{}
+{
+  "for" "("
+
+  (
+      LOOKAHEAD(Type() JavaIdentifier() ":")
+      Type() JavaIdentifier() ":" Expression()
+    |
+     [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ]
+  )
+
+  ")" Statement()
+}
+
+void ForInit() :
+{}
+{
+  LOOKAHEAD( [ "final" ] Type() JavaIdentifier() )
+  LocalVariableDeclaration()
+|
+  StatementExpressionList()
+}
+
+void StatementExpressionList() :
+{}
+{
+  StatementExpression() ( "," StatementExpression() )*
+}
+
+void ForUpdate() :
+{}
+{
+  StatementExpressionList()
+}
+
+void BreakStatement() :
+{}
+{
+  "break" [ JavaIdentifier() ] ";"
+}
+
+void ContinueStatement() :
+{}
+{
+  "continue" [ JavaIdentifier() ] ";"
+}
+
+void ReturnStatement() :
+{}
+{
+  "return" [ Expression() ] ";"
+}
+
+void ThrowStatement() :
+{}
+{
+  "throw" Expression() ";"
+}
+
+void SynchronizedStatement() :
+{}
+{
+  "synchronized" "(" Expression() ")" Block()
+}
+
+void TryStatement() :
+/*
+ * Semantic check required here to make sure that at least one
+ * finally/catch is present.
+ */
+{}
+{
+  "try"
+  // Java 7 extension (resource declarations):
+  [ "(" LocalVariableDeclaration() ( LOOKAHEAD(2) ";" LocalVariableDeclaration() )* [ ";" ] ")" ]
+  Block()
+  ( "catch" "(" ["final"] Type() ( "|" ["final"] Type() )* VariableDeclaratorId() ")" Block() )*
+  [ "finally" Block() ]
+}
+
+/* We use productions to match >>>, >> and > so that we can keep the
+ * type declaration syntax with generics clean
+ */
+
+void RUNSIGNEDSHIFT():
+{}
+{
+  ( LOOKAHEAD({ getToken(1).kind == GT &&
+                ((Token.GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT} )
+   ">" ">" ">"
+  )
+}
+
+void RSIGNEDSHIFT():
+{}
+{
+  ( LOOKAHEAD({ getToken(1).kind == GT &&
+                ((Token.GTToken)getToken(1)).realKind == RSIGNEDSHIFT} )
+  ">" ">"
+  )
+}
+
+/* Annotation syntax follows. */
+
+SimpleNode Annotation():
+{}
+{
+ (
+   LOOKAHEAD( NormalAnnotation() )
+   NormalAnnotation()
+ |
+   LOOKAHEAD( SingleMemberAnnotation() )
+   SingleMemberAnnotation()
+ |
+   LOOKAHEAD( MarkerAnnotation() )
+   MarkerAnnotation()
+ )
+ { return jjtThis; }
+}
+
+void NormalAnnotation():
+{}
+{
+   "@" Name() "(" [ MemberValuePairs() ] ")"
+}
+
+void MarkerAnnotation():
+{}
+{
+  "@" Name()
+}
+
+void SingleMemberAnnotation():
+{}
+{
+  "@" Name() "(" MemberValue() ")"
+}
+
+void MemberValuePairs():
+{}
+{
+   MemberValuePair() ( "," MemberValuePair() )*
+}
+
+void MemberValuePair():
+{}
+{
+    JavaIdentifier() "=" MemberValue()
+}
+
+void MemberValue():
+{}
+{
+   Annotation()
+ |
+   MemberValueArrayInitializer()
+ |
+   ConditionalExpression()
+}
+
+void  MemberValueArrayInitializer():
+{}
+{
+  "{" MemberValue() ( LOOKAHEAD(2) "," MemberValue() )* [ "," ] "}"
+}
+
+
+/* Annotation Types. */
+
+void AnnotationTypeDeclaration(String modifiers):
+{}
+{
+  "@" "interface" { pushTopLevelOrAspect("annotation"); } JavaIdentifier() AnnotationTypeBody() { popTopLevelOrAspect(); }
+  { if (shouldAddClassBodyDecl()) {
+      root.addClassBodyDecl(jjtThis, className, fileName, modifiers, enclosingAspect);
+    }
+  }
+}
+
+void AnnotationTypeBody():
+{}
+{
+  "{" ( AnnotationTypeMemberDeclaration() )* "}"
+}
+
+void AnnotationTypeMemberDeclaration():
+{
+   String modifiers;
+}
+{
+ modifiers = Modifiers()
+ (
+   LOOKAHEAD(AspectType() JavaIdentifier() "(")
+   AspectType() JavaIdentifier() "(" ")" [ DefaultValue() ] ";"
+  |
+   UnmodifiedClassDeclaration(modifiers)
+  |
+   UnmodifiedInterfaceDeclaration(modifiers)
+  |
+   UnmodifiedEnumDeclaration(modifiers)
+  |
+   AnnotationTypeDeclaration(modifiers)
+  |
+   FieldDeclaration(modifiers)
+ )
+ |
+   ( ";" )
+}
+
+void DefaultValue():
+{}
+{
+  "default" MemberValue()
+}
+
+// Adding (cache|uncached) keywords in front of each line in the cache configuration.
+// This information is propagated to the grammar via setAttributeCacheMode(..)
+void AspectCacheDeclaration():
+{
+  Token t;
+  Token cacheConfig;
+  Token hostType;
+  Token attrName;
+
+  int paramIndex = 1;
+  String paramType;
+  Token paramName;
+  org.jastadd.ast.AST.List paramList = new org.jastadd.ast.AST.List();
+}
+{
+  ( cacheConfig = "cache" | cacheConfig = "uncache" )
+  hostType = <IDENTIFIER> "."
+  attrName = AttributeName()
+  "(" { paramList = new org.jastadd.ast.AST.List(); }
+  [
+    paramType = Type() (<IDENTIFIER>)?
+      { paramList.add(new org.jastadd.ast.AST.Parameter(paramType, "p0")); }
+    (
+      "," paramType = Type() (<IDENTIFIER>)?
+        { paramList.add(new org.jastadd.ast.AST.Parameter(paramType, "p" + (paramIndex++))); }
+    )*
+  ]
+  ")"
+  ";"
+  {
+    root.setAttributeCacheMode(cacheConfig.image, hostType.image, attrName.image,
+        paramList, fileName, cacheConfig.beginLine);
+  }
+}
+
+// Valid Java identifiers include 'syn', 'eq', etc. (reserved JastAdd words are legal in pure Java)
+void JavaIdentifier() :
+{}
+{
+  <IDENTIFIER>
+| <INH>
+| <SYN>
+| <LAZY>
+| <REWRITE>
+| <TO>
+| <WHEN>
+| <ASPECT>
+| <EQUATION>
+| <CIRCULAR>
+| <REFINE>
+| <COLL>
+| <CONTRIBUTES>
+| <EACH>
+| <NTA>
+| <CACHE>
+| <UNCACHE>
+}
+
+Token AttributeName() :
+{Token t;}
+{
+  t = <IDENTIFIER> { return t; }
+}
+