Mathias Landhäußer 11 лет назад
Родитель
Сommit
e97ca88cd1
31 измененных файлов с 3745 добавлено и 0 удалено
  1. 101 0
      jplag.frontend.java-1.7/pom.xml
  2. 765 0
      jplag.frontend.java-1.7/src/main/antlr4/jplag/java17/grammar/Java7.g4
  3. 170 0
      jplag.frontend.java-1.7/src/main/java/jplag/java17/JavaToken.java
  4. 76 0
      jplag.frontend.java-1.7/src/main/java/jplag/java17/JavaTokenConstants.java
  5. 1600 0
      jplag.frontend.java-1.7/src/main/java/jplag/java17/JplagJava7Listener.java
  6. 63 0
      jplag.frontend.java-1.7/src/main/java/jplag/java17/Language.java
  7. 119 0
      jplag.frontend.java-1.7/src/main/java/jplag/java17/Parser.java
  8. 79 0
      jplag.frontend.java-1.7/src/test/java/jplag/antlr4Learning/Antlr4LearningTests.java
  9. 45 0
      jplag.frontend.java-1.7/src/test/java/jplag/java17/Bug58.java
  10. 295 0
      jplag.frontend.java-1.7/src/test/java/jplag/java17/ParserTest.java
  11. 22 0
      jplag.frontend.java-1.7/src/test/resources/AnnotationText.java
  12. 15 0
      jplag.frontend.java-1.7/src/test/resources/AnonymousClass.java
  13. 15 0
      jplag.frontend.java-1.7/src/test/resources/ArrayTest.java
  14. 0 0
      jplag.frontend.java-1.7/src/test/resources/EmptyFile.java
  15. 5 0
      jplag.frontend.java-1.7/src/test/resources/EmptyFileOneComment.java
  16. 2 0
      jplag.frontend.java-1.7/src/test/resources/EmptyFileOnlyComments.java
  17. 27 0
      jplag.frontend.java-1.7/src/test/resources/EnumTest.java
  18. 7 0
      jplag.frontend.java-1.7/src/test/resources/ExceptionOne.java
  19. 5 0
      jplag.frontend.java-1.7/src/test/resources/ExceptionThree.java
  20. 7 0
      jplag.frontend.java-1.7/src/test/resources/ExceptionTwo.java
  21. 31 0
      jplag.frontend.java-1.7/src/test/resources/GenericPocket.java
  22. 24 0
      jplag.frontend.java-1.7/src/test/resources/IfElsifElse.java
  23. 21 0
      jplag.frontend.java-1.7/src/test/resources/InnerClass.java
  24. 5 0
      jplag.frontend.java-1.7/src/test/resources/J7Generics.java
  25. 13 0
      jplag.frontend.java-1.7/src/test/resources/J7StringSwitch.java
  26. 43 0
      jplag.frontend.java-1.7/src/test/resources/J7TryCatch.java
  27. 112 0
      jplag.frontend.java-1.7/src/test/resources/Java7FeatureTest.java
  28. 32 0
      jplag.frontend.java-1.7/src/test/resources/Kalender.java
  29. 31 0
      jplag.frontend.java-1.7/src/test/resources/OptimizeAnnotation.java
  30. 13 0
      jplag.frontend.java-1.7/src/test/resources/SimpleClass.java
  31. 2 0
      jplag.frontend.java-1.7/src/test/resources/package-info.java

+ 101 - 0
jplag.frontend.java-1.7/pom.xml

@@ -0,0 +1,101 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>java-1.7</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+
+	<repositories>
+		<repository>
+			<id>ipdNexus</id>
+			<name>Recaa Repository</name>
+			<url>http://bob.ipd.kit.edu/nexus/content/repositories/public/</url>
+		</repository>
+	</repositories>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>build-helper-maven-plugin</artifactId>
+				<version>1.7</version>
+				<configuration>
+					<sources>
+						<source>target/generated-sources/antlr4</source>
+					</sources>
+				</configuration>
+				<executions>
+					<execution>
+						<id>generate-antlr-sources</id>
+						<phase>generate-sources</phase>
+						<goals>
+							<goal>add-source</goal>
+						</goals>
+					</execution>
+					<execution>
+						<id>compile-with-antlr-sources</id>
+						<phase>compile</phase>
+						<goals>
+							<goal>add-source</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.antlr</groupId>
+				<artifactId>antlr4-maven-plugin</artifactId>
+				<version>4.0</version>
+				<configuration>
+					<!-- Comma separated list of grammar files or pattern grammar files 
+						By default, grammar file(s) is in ${basedir}/src/main/antlr -->
+					<!-- <grammars>*.g</grammars> -->
+					<grammars>Java7.g4</grammars>
+				</configuration>
+				<executions>
+					<execution>
+						<goals>
+							<goal>antlr4</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>jplag.java17.Parser</mainClass>
+							<packageName>jplag.java17</packageName>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>edu.kit.ipd.jplag</groupId>
+			<artifactId>frontend-utils</artifactId>
+			<version>0.0.3-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>org.antlr</groupId>
+			<artifactId>antlr4-runtime</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>edu.kit.ipd.jplag.frontend</groupId>
+			<artifactId>java-1.5</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+	<parent>
+		<groupId>edu.kit.ipd.jplag.frontend</groupId>
+		<artifactId>frontend-parent</artifactId>
+		<version>0.3-SNAPSHOT</version>
+	</parent>
+</project>

+ 765 - 0
jplag.frontend.java-1.7/src/main/antlr4/jplag/java17/grammar/Java7.g4

@@ -0,0 +1,765 @@
+/*
+ [The "BSD licence"]
+ Copyright (c) 2012 George S. Cowan
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. 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.
+ 3. The name of the author may not be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+
+/** Java 7 grammar for Antlr 4
+    Based on Terence Parr's Java 6 grammar at
+      https://github.com/antlr/grammars-v4/tree/master/java
+    with changes from the Java 7 Language Specification
+      http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
+    but with my own refactorings.
+  */
+grammar Java7;
+
+/* the keywords enum and assert have compiler options to allow their use as
+   identifiers instead. This presents a problem best solved with
+   implementation dependent code. I have commented out a Java solution.
+ */
+// @lexer::members {
+//   protected boolean enumIsKeyword = true;  // A subclass of Java7Parser.java can
+//   protected boolean assertIsKeyword = true;// accept parameters and override these
+// }
+
+/*******************************************************************************
+        Parser section -
+*******************************************************************************/
+
+compilationUnit
+  : packageDeclaration? importDeclaration* typeDeclaration* EOF
+  ;
+
+packageDeclaration
+  : annotation* 'package' qualifiedIdentifier ';'
+  ;
+
+importDeclaration
+  : 'import' 'static'? qualifiedIdentifier ('.' '*')? ';'
+  ;
+
+typeDeclaration
+  : classOrInterfaceDeclaration
+  | ';'
+  ;
+
+classOrInterfaceDeclaration
+  : modifier* (classDeclaration | interfaceDeclaration)
+  ;
+
+
+classDeclaration
+  : normalClassDeclaration
+  | enumDeclaration
+  ;
+
+normalClassDeclaration
+  : 'class' Identifier typeParameters?
+    ('extends' typeRef)?
+    ('implements' typeList)?
+    classBody
+  ;
+
+typeParameters
+  : '<' typeParameter (',' typeParameter)* '>'
+  ;
+
+typeParameter
+  : Identifier ('extends' bound)?
+  ;
+
+bound
+  : classOrInterfaceType ('&' classOrInterfaceType)*
+  ;
+
+enumDeclaration
+  : ENUM Identifier ('implements' typeList)?
+    '{' enumConstants?
+        ( ';' classBodyDeclaration* )?
+    '}'
+  ;
+
+enumConstants
+  // The comma after the last enumConstant is optional.
+  // Oddly, there may also be a comma without any enumConstants
+  : enumConstant (',' enumConstant)* ','?
+  | ','
+  ;
+
+interfaceDeclaration
+  : normalInterfaceDeclaration
+  | annotationTypeDeclaration
+  ;
+normalInterfaceDeclaration
+  : 'interface' Identifier typeParameters? ('extends' typeList)? interfaceBody
+  ;
+
+classBody
+  :   '{' classBodyDeclaration* '}'
+  ;
+
+interfaceBody
+  : '{'
+       ( modifier* interfaceMemberDecl | ';' )*
+    '}'
+  ;
+
+classBodyDeclaration
+  : ';'                             #cbdSemicolon
+  | modifier* memberDecl            #cbdMember
+  | 'static'? block                 #cbdBlock
+  ;
+
+memberDecl
+  : methodDeclaration // generic and void methods are here, too
+  | fieldDeclaration
+  | constructorDeclaration
+  | interfaceDeclaration
+  | classDeclaration
+  ;
+
+fieldDeclaration
+  : typeRef variableDeclarators ';'
+  ;
+
+block
+  : '{' blockStatement* '}'
+  ;
+
+blockStatement
+  : localVariableDeclaration ';'
+  | classOrInterfaceDeclaration
+  | statement
+  ;
+
+enumConstant
+  : annotation* Identifier arguments? classBody?
+  ;
+
+typeList
+  : classOrInterfaceType (',' classOrInterfaceType)*
+  ;
+
+typeArguments
+  : '<' typeArgument (',' typeArgument)* '>'
+  ;
+
+typeArgument
+  : classOrInterfaceType ('[' ']')* // array types are allowed here, as an type argument
+  | '?' (('extends' | 'super') classOrInterfaceType)?
+  ;
+
+interfaceMemberDecl
+  : interfaceMethodOrFieldDecl
+  | interfaceGenericMethodDecl
+  | 'void' Identifier voidInterfaceMethodDeclaratorRest
+  | interfaceDeclaration
+  | classDeclaration
+  ;
+
+
+/** Allows brackets after parameters for backwards compatibility only; do not use. */
+methodDeclaration
+  : typeParameters? (typeRef | 'void')
+    Identifier formalParameters ('[' ']')*   ('throws' qualifiedIdentifierList)?
+    ( methodBody
+    | ';'
+    )
+  ;
+
+constructorDeclaration
+  : typeParameters? Identifier formalParameters ('throws' qualifiedIdentifierList)?
+    '{'
+        explicitConstructorInvocation?
+        blockStatement*
+    '}'
+  ;
+
+variableModifier
+  : 'final'
+  | annotation
+  ;
+
+interfaceMethodOrFieldDecl
+  : typeRef Identifier interfaceMethodOrFieldRest
+  ;
+
+interfaceMethodOrFieldRest
+  : constantDeclaratorsRest ';'
+  | interfaceMethodDeclaratorRest
+  ;
+
+interfaceMethodDeclaratorRest
+  : formalParameters ('[' ']')* ('throws' qualifiedIdentifierList)? ';'
+  ;
+
+interfaceGenericMethodDecl
+  : typeParameters (typeRef | 'void') Identifier
+    interfaceMethodDeclaratorRest
+  ;
+
+voidInterfaceMethodDeclaratorRest
+  : formalParameters ('throws' qualifiedIdentifierList)? ';'
+  ;
+
+constantDeclarator
+  : Identifier constantDeclaratorRest
+  ;
+
+variableDeclarators
+  : variableDeclarator (',' variableDeclarator)*
+  ;
+
+variableDeclarator
+  : variableDeclaratorId ('=' variableInitializer)?
+  ;
+
+constantDeclaratorsRest
+  : constantDeclaratorRest (',' constantDeclarator)*
+  ;
+
+constantDeclaratorRest
+  : ('[' ']')* '=' variableInitializer
+  ;
+
+variableDeclaratorId
+  : Identifier ('[' ']')*
+  ;
+
+variableInitializer
+  : arrayInitializer
+  | expression
+  ;
+
+arrayInitializer
+  : '{' ( variableInitializer (',' variableInitializer)* (',')?
+        )?
+    '}'
+  ;
+
+modifier
+  : annotation
+  | 'public'
+  | 'protected'
+  | 'private'
+  | 'static'
+  | 'abstract'
+  | 'final'       // not for interface or annotation declarations
+  | 'native'
+  | 'synchronized'
+  | 'transient'
+  | 'volatile'
+  | 'strictfp'
+  ;
+
+packageOrTypeName
+  : qualifiedIdentifier
+  ;
+
+enumConstantName
+  : Identifier
+  ;
+
+typeName
+  : qualifiedIdentifier
+  ;
+
+typeRef
+  : classOrInterfaceType ('[' ']')*
+  | primitiveType ('[' ']')*
+  ;
+
+/** classOrInterfaceType is not used in the Java 7 Language Specification. We use
+    it as a substitute name for the ReferenceType that is defined in the Syntax
+    section (Chapter 18, p. 593). The reason that we do not just use the rule name
+    referenceType instead of classOrInterfaceType is that elsewhere in the
+    Java 7 Reference (topic 4.3, p.52), ReferenceType is defined differently.
+    We are doing our best here to avoid confusion.
+  */
+classOrInterfaceType
+  : Identifier typeArguments? ( '.' Identifier typeArguments? )*
+  ;
+
+primitiveType
+  : 'boolean'
+  | 'char'
+  | 'byte'
+  | 'short'
+  | 'int'
+  | 'long'
+  | 'float'
+  | 'double'
+  ;
+
+qualifiedIdentifierList
+  : qualifiedIdentifier (',' qualifiedIdentifier)*
+  ;
+
+formalParameters
+  : '(' formalParameterDeclarations? ')'
+  ;
+
+formalParameterDeclarations
+  : variableModifier* typeRef formalParameterVariables
+  ;
+
+formalParameterVariables
+  : '...' variableDeclaratorId // variable-arity parameter must be the last one
+  | variableDeclaratorId (',' formalParameterDeclarations)?
+  ;
+
+methodBody
+  : block
+  ;
+
+explicitConstructorInvocation
+  : nonWildcardTypeArguments? ('this' | 'super') arguments ';'
+  | primary '.' nonWildcardTypeArguments? 'super' arguments ';'
+  ;
+
+qualifiedIdentifier
+  : Identifier ('.' Identifier)*
+  ;
+literal
+  : integerLiteral
+  | FloatingPointLiteral
+  | CharacterLiteral
+  | StringLiteral
+  | booleanLiteral
+  | 'null'
+  ;
+
+integerLiteral
+  : HexLiteral
+  | OctalLiteral
+  | DecimalLiteral
+  | BinaryLiteral
+  ;
+
+booleanLiteral
+  : 'true'
+  | 'false'
+  ;
+
+// ANNOTATIONS
+
+annotation
+  : '@' annotationName ( '(' ( elementValuePairs | elementValue )? ')' )?
+  ;
+
+annotationName
+  : Identifier ('.' Identifier)*
+  ;
+
+elementValuePairs
+  : elementValuePair (',' elementValuePair)*
+  ;
+
+elementValuePair
+  : Identifier '=' elementValue
+  ;
+
+elementValue
+  : expression
+  | annotation
+  | elementValueArrayInitializer
+  ;
+
+elementValueArrayInitializer
+  : '{' (elementValue (',' elementValue)*)? (',')? '}'
+  ;
+
+annotationTypeDeclaration
+  : '@' 'interface' Identifier
+    '{'
+       (modifier* annotationTypeElement)*
+    '}'
+  ;
+
+annotationTypeElement
+  : typeRef (annotationMethod | variableDeclarators) ';'
+  | classDeclaration ';'?
+  | normalInterfaceDeclaration ';'?
+  | enumDeclaration ';'?
+  | annotationTypeDeclaration ';'?
+  ;
+
+annotationMethod
+  : Identifier '(' ')' defaultValue?
+  ;
+
+defaultValue
+  : 'default' elementValue
+  ;
+
+// STATEMENTS / BLOCKS
+
+localVariableDeclaration
+  : variableModifier* typeRef variableDeclarators
+  ;
+
+statement
+  : block                                                   #blockStmt
+  | ASSERT expression (':' expression)? ';'                 #assertStmt
+  | 'if' parExpression statement ('else' statement)?        #ifStmt
+  | 'for' '(' forControl ')' statement                      #forStmt
+  | 'while' parExpression statement                         #whileStmt
+  | 'do' statement 'while' parExpression ';'                #doWhileStmt
+  | tryStatement                                            #tryStmt
+  | 'switch' parExpression switchBlock                      #switchStmt
+  | 'synchronized' parExpression block                      #synchronizedStmt
+  | 'return' expression? ';'                                #returnStmt
+  | 'throw' expression ';'                                  #throwStmt
+  | 'break' Identifier? ';'                                 #break
+  | 'continue' Identifier? ';'                              #continueStmt
+  | ';'                                                     #semicStmt
+  | statementExpression ';'                                 #statementExpressStmt
+  | Identifier ':' statement                                #identifiedStmt
+  ;
+
+tryStatement
+  // must contain at least one resource, catch, or finally
+  : 'try' '(' resources ')' block   catchClause* ('finally' block)?
+  | 'try'                   block ( catchClause+ ('finally' block)?
+                                  |               'finally' block
+                                  )
+  ;
+
+catchClause
+  : 'catch' '(' variableModifier* typeRef ('|' typeRef)* Identifier ')' block
+  ;
+
+resources
+  // Semicolon may be ommited for last resource
+  : resource (';' resource)* ';'?
+  ;
+
+resource
+  : variableModifier* classOrInterfaceType variableDeclaratorId '=' expression
+  ;
+
+switchBlock
+  : '{' switchBlockStatementGroup* switchLabel* '}'
+  ;
+
+switchBlockStatementGroup
+  : switchLabel+ blockStatement*
+  ;
+
+switchLabel
+  : 'case' constantExpression ':'
+  | 'case' enumConstantName ':'
+  | 'default' ':'
+  ;
+
+forControl
+  : enhancedForControl
+  | forInit? ';' expression? ';' forUpdate?
+  ;
+
+forInit
+  : localVariableDeclaration
+  | expressionList
+  ;
+
+enhancedForControl
+  : variableModifier* typeRef Identifier ':' expression
+  ;
+
+forUpdate
+  : expressionList
+  ;
+
+// EXPRESSIONS
+
+parExpression
+  : '(' expression ')'
+  ;
+
+expressionList
+  : expression (',' expression)*
+  ;
+
+statementExpression
+  : expression
+  ;
+
+constantExpression
+  : expression
+  ;
+
+expression
+  : primary                                                             #exprPrimary
+  | expression '.' Identifier                                           #exprIdentifier
+  | expression '.' 'this'                                               #exprThis
+  | expression '.' 'super' '(' expressionList? ')'                      #exprSuper
+  | expression '.' 'new' Identifier '(' expressionList? ')'             #exprNewIdentidier
+  | expression '.' 'super' '.' Identifier arguments?                    #exprSuperIdentifier
+  | expression '.' explicitGenericInvocation                            #exprExplicitGenericInvocation
+  | expression '[' expression ']'                                       #exprArrayExpression
+  | expression '(' expressionList? ')'                                  #exprMethodExpressionList
+  | expression ('++' | '--')                                            #exprExpressionIncDec
+  | ('+'|'-'|'++'|'--') expression                                      #exprIncDecExpression
+  | ('~'|'!') expression                                                #exprNotExpression
+  | '(' typeRef ')' expression                                          #exprCastExpression
+  | 'new' creator                                                       #exprNewCreator
+  | expression ('*'|'/'|'%') expression                                 #exprBinaryOperatorMult
+  | expression ('+'|'-') expression                                     #exprBinaryOperatorAdd
+  | expression ('<' '<' | '>' '>' '>' | '>' '>') expression             #exprBinaryOperatorComp
+  | expression ('<' '=' | '>' '=' | '>' | '<') expression               #exprBinaryOperatorGT
+  | expression 'instanceof' typeRef                                     #exprBinaryOperatorInstanceof
+  | expression ('==' | '!=') expression                                 #exprBinaryEquals
+  | expression '&' expression                                           #exprBinaryAnd
+  | expression '^' expression                                           #exprBinaryNot
+  | expression '|' expression                                           #exprBinaryOr
+  | expression '&&' expression                                          #exprBinaryBoolAnd
+  | expression '||' expression                                          #exprBinaryBoolOr
+  | expression '?' expression ':' expression                            #exprConditionalExpression
+  | expression                                                          
+    ( '^='            <assoc=right>
+    | '+='            <assoc=right>
+    | '-='            <assoc=right>
+    | '*='            <assoc=right>
+    | '/='            <assoc=right>
+    | '&='            <assoc=right>
+    | '|='            <assoc=right>
+    | '='             <assoc=right>
+    | '>' '>' '='     <assoc=right>
+    | '>' '>' '>' '=' <assoc=right>
+    | '<' '<' '='     <assoc=right>
+    | '%='            <assoc=right>
+    )
+    expression                                                          #exprAssignment
+  ;
+
+primary
+  : '(' expression ')'
+  | 'this'
+  | 'super'
+  | literal
+  | Identifier
+  | typeRef '.' 'class'
+  | 'void' '.' 'class'
+  ;
+
+creator
+  : nonWildcardTypeArguments createdName classCreatorRest
+  | createdName (arrayCreatorRest | classCreatorRest)
+  ;
+
+createdName
+  : primitiveType
+  | // classOrInterfaceType but with possible <>
+    Identifier (typeArguments | '<' '>')? ('.' Identifier (typeArguments | '<' '>')? )*
+  ;
+
+innerCreator
+  : (nonWildcardTypeArguments | '<' '>')? Identifier classCreatorRest
+  ;
+
+explicitGenericInvocation
+  : nonWildcardTypeArguments Identifier arguments
+  ;
+
+arrayCreatorRest
+  : '['
+    (   ']' ('[' ']')* arrayInitializer
+    |   expression ']' ('[' expression ']')* ('[' ']')*
+    |   ']'
+    )
+  ;
+
+classCreatorRest
+  : arguments classBody?
+  ;
+
+nonWildcardTypeArguments
+  : '<' typeList '>'
+  ;
+
+arguments
+  : '(' expressionList? ')'
+  ;
+
+
+// LEXER =====================================================
+
+HexLiteral
+  // underscores may be freely inserted after first hex digit and before last
+  : '0' ('x'|'X')
+    HexDigits
+    IntegerTypeSuffix?
+  ;
+
+DecimalLiteral
+  // Only a single zero digit may begin with a zero
+  // Underscores may be freely inserted after first digit and before last
+  : ( '0' | '1'..'9' ('_'* Digit)* ) IntegerTypeSuffix?
+  ;
+
+OctalLiteral
+  // Underscores may be freely inserted before the last digit.
+  // Don't know why underscores here are different from others -
+  // Maybe the leading 0 is considered a digit as well as a marker
+  // indicating that the following is a base 8 number
+  : '0' ('_'* '0'..'7')+ IntegerTypeSuffix?
+  ;
+
+BinaryLiteral
+  // underscores may be freely inserted after first digit and before last
+  : '0' ('b'|'B')
+    BinaryDigit ('_'* BinaryDigit)*
+    IntegerTypeSuffix?
+  ;
+
+fragment
+BinaryDigit : ('0'|'1') ;
+
+fragment
+HexDigits : HexDigit ('_'* HexDigit)* ;
+
+fragment
+HexDigit : (Digit|'a'..'f'|'A'..'F') ;
+
+fragment
+Digits : Digit ('_'* Digit)* ;
+
+fragment
+Digit : '0'..'9' ;
+
+fragment
+IntegerTypeSuffix : ('l'|'L') ;
+
+FloatingPointLiteral
+  : Digits '.' Digits? Exponent? FloatTypeSuffix?
+  | '.' Digits Exponent? FloatTypeSuffix?
+  | Digits Exponent FloatTypeSuffix?
+  | Digits FloatTypeSuffix
+
+    // Hex float literal
+  | ('0x' | '0X')
+    HexDigits? ('.' HexDigits?)?
+    ( 'p' | 'P' ) ( '+' | '-' )? Digits // note decimal exponent
+    FloatTypeSuffix?
+  ;
+
+fragment
+Exponent : ('e'|'E') ('+'|'-')? Digits ;
+
+fragment
+FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
+
+CharacterLiteral
+  : '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
+  ;
+
+StringLiteral
+  :  '"' ( EscapeSequence | ~('\\'|'"') )* '"'
+  ;
+
+fragment
+EscapeSequence
+  : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
+  | UnicodeEscape
+  | OctalEscape
+  ;
+
+fragment
+OctalEscape
+  : '\\' ('0'..'3') ('0'..'7') ('0'..'7')
+  | '\\' ('0'..'7') ('0'..'7')
+  | '\\' ('0'..'7')
+  ;
+
+fragment
+UnicodeEscape
+  : '\\' 'u' HexDigit HexDigit HexDigit HexDigit
+  ;
+
+ENUM
+  : 'enum' // {if (!enumIsKeyword) setType(Identifier);}
+  ;
+
+ASSERT
+  : 'assert' // {if (!assertIsKeyword) setType(Identifier);}
+  ;
+
+Identifier
+  : Letter (Letter|JavaIDDigit)*
+  ;
+
+/**I found this char range in JavaCC's grammar, but Letter and Digit overlap.
+   Still works, but...
+ */
+fragment
+Letter
+  : '\u0024'                 // $
+  | '\u0041'..'\u005a'       // A-Z
+  | '\u005f'                 // _
+  | '\u0061'..'\u007a'       // a-z
+  | '\u00c0'..'\u00d6'       // Latin Capital Letter A with grave - Latin Capital letter O with diaeresis
+  | '\u00d8'..'\u00f6'       // Latin Capital letter O with stroke - Latin Small Letter O with diaeresis
+  | '\u00f8'..'\u00ff'       // Latin Small Letter O with stroke - Latin Small Letter Y with diaeresis
+  | '\u0100'..'\u1fff'       // Latin Capital Letter A with macron - Latin Small Letter O with stroke and acute
+  | '\u3040'..'\u318f'       // Hiragana
+  | '\u3300'..'\u337f'       // CJK compatibility
+  | '\u3400'..'\u3d2d'       // CJK compatibility
+  | '\u4e00'..'\u9fff'       // CJK compatibility
+  | '\uf900'..'\ufaff'       // CJK compatibility
+  ;
+
+fragment
+JavaIDDigit
+  : '\u0030'..'\u0039'       // 0-9
+  | '\u0660'..'\u0669'       // Arabic-Indic Digit 0-9
+  | '\u06f0'..'\u06f9'       // Extended Arabic-Indic Digit 0-9
+  | '\u0966'..'\u096f'       // Devanagari 0-9
+  | '\u09e6'..'\u09ef'       // Bengali 0-9
+  | '\u0a66'..'\u0a6f'       // Gurmukhi 0-9
+  | '\u0ae6'..'\u0aef'       // Gujarati 0-9
+  | '\u0b66'..'\u0b6f'       // Oriya 0-9
+  | '\u0be7'..'\u0bef'       // Tami 0-9
+  | '\u0c66'..'\u0c6f'       // Telugu 0-9
+  | '\u0ce6'..'\u0cef'       // Kannada 0-9
+  | '\u0d66'..'\u0d6f'       // Malayala 0-9
+  | '\u0e50'..'\u0e59'       // Thai 0-9
+  | '\u0ed0'..'\u0ed9'       // Lao 0-9
+  | '\u1040'..'\u1049'       // Myanmar 0-9?
+  ;
+
+WS
+  : [ \r\t\u000C\n]+ -> channel(HIDDEN)
+  ;
+
+COMMENT
+  : '/*' .*? '*/'    -> channel(HIDDEN)
+  ;
+
+LINE_COMMENT
+  : '//' ~[\r\n]* -> channel(HIDDEN)
+  ;
+

+ 170 - 0
jplag.frontend.java-1.7/src/main/java/jplag/java17/JavaToken.java

@@ -0,0 +1,170 @@
+package jplag.java17;
+
+public class JavaToken extends jplag.Token implements JavaTokenConstants {
+	private static final long serialVersionUID = -383581430479870696L;
+	private int line, column, length;
+
+	public JavaToken(int type, String file, int line, int column, int length) {
+		super(type, file, line, column, length);
+	}
+
+	public int getLine() {
+		return line;
+	}
+
+	public int getColumn() {
+		return column;
+	}
+
+	public int getLength() {
+		return length;
+	}
+
+	public void setLine(int line) {
+		this.line = line;
+	}
+
+	public void setColumn(int column) {
+		this.column = column;
+	}
+
+	public void setLength(int length) {
+		this.length = length;
+	}
+
+	public static String type2string(int type) {
+		switch (type) {
+		case JavaTokenConstants.FILE_END:
+			return "********";
+		case JavaTokenConstants.SEPARATOR_TOKEN:
+			return "METHOD_SEPARATOR";
+		case J_PACKAGE:
+			return "PACKAGE ";
+		case J_IMPORT:
+			return "IMPORT  ";
+		case J_CLASS_BEGIN:
+			return "CLASS{  ";
+		case J_CLASS_END:
+			return "}CLASS  ";
+		case J_METHOD_BEGIN:
+			return "METHOD{ ";
+		case J_METHOD_END:
+			return "}METHOD ";
+		case J_VARDEF:
+			return "VARDEF  ";
+		case J_SYNC_BEGIN:
+			return "SYNC{   ";
+		case J_SYNC_END:
+			return "}SYNC   ";
+		case J_DO_BEGIN:
+			return "DO{     ";
+		case J_DO_END:
+			return "}DO     ";
+		case J_WHILE_BEGIN:
+			return "WHILE{  ";
+		case J_WHILE_END:
+			return "}WHILE  ";
+		case J_FOR_BEGIN:
+			return "FOR{    ";
+		case J_FOR_END:
+			return "}FOR    ";
+		case J_SWITCH_BEGIN:
+			return "SWITCH{ ";
+		case J_SWITCH_END:
+			return "}SWITCH ";
+		case J_CASE:
+			return "CASE    ";
+		case J_TRY_BEGIN:
+			return "TRY{    ";
+		case J_CATCH_BEGIN:
+			return "CATCH{  ";
+		case J_CATCH_END:
+			return "}CATCH  ";
+		case J_FINALLY:
+			return "FINALLY ";
+		case J_IF_BEGIN:
+			return "IF{     ";
+		case J_ELSE:
+			return "ELSE    ";
+		case J_IF_END:
+			return "}IF     ";
+		case J_COND:
+			return "COND    ";
+		case J_BREAK:
+			return "BREAK   ";
+		case J_CONTINUE:
+			return "CONTINUE";
+		case J_RETURN:
+			return "RETURN  ";
+		case J_THROW:
+			return "THROW   ";
+		case J_IN_CLASS_BEGIN:
+			return "INCLASS{";
+		case J_IN_CLASS_END:
+			return "}INCLASS";
+		case J_APPLY:
+			return "APPLY   ";
+		case J_NEWCLASS:
+			return "NEWCLASS";
+		case J_NEWARRAY:
+			return "NEWARRAY";
+		case J_ASSIGN:
+			return "ASSIGN  ";
+		case J_INTERFACE_BEGIN:
+			return "INTERF{ ";
+		case J_INTERFACE_END:
+			return "}INTERF ";
+		case J_CONSTR_BEGIN:
+			return "CONSTR{ ";
+		case J_CONSTR_END:
+			return "}CONSTR ";
+		case J_INIT_BEGIN:
+			return "INIT{   ";
+		case J_INIT_END:
+			return "}INIT   ";
+		case J_VOID:
+			return "VOID    ";
+		case J_ARRAY_INIT_BEGIN:
+			return "ARRINIT{";
+		case J_ARRAY_INIT_END:
+			return "ARRINIT}";
+		case J_ENUM_BEGIN:
+			return "ENUM{   ";
+		case J_ENUM_CLASS_BEGIN:
+			return "ENUM_CLA";
+		case J_ENUM_END:
+			return "}ENUM   ";
+		case J_GENERIC:
+			return "GENERIC ";
+		case J_ASSERT:
+			return "ASSERT  ";
+		case J_ANNO:
+			return "ANNO    ";
+		case J_ANNO_MARKER:
+			return "ANNOMARK";
+		case J_ANNO_M_BEGIN:
+			return "ANNO_M{ ";
+		case J_ANNO_M_END:
+			return "}ANNO_M ";
+		case J_ANNO_T_BEGIN:
+			return "ANNO_T{ ";
+		case J_ANNO_T_END:
+			return "}ANNO_T ";
+		case J_ANNO_C_BEGIN:
+			return "ANNO_C{ ";
+		case J_ANNO_C_END:
+			return "}ANNO_C ";
+
+		case J_TRY_WITH_RESOURCE:
+			return "TRY_RES ";
+
+		default:
+			System.err.println("*UNKNOWN: " + type);
+			return "*UNKNOWN" + type;
+		}
+	}
+
+	public static int numberOfTokens() {
+		return NUM_DIFF_TOKENS;
+	}
+}

+ 76 - 0
jplag.frontend.java-1.7/src/main/java/jplag/java17/JavaTokenConstants.java

@@ -0,0 +1,76 @@
+package jplag.java17;
+
+public interface JavaTokenConstants extends jplag.TokenConstants {
+	final static int FILE_END = 0;
+
+	// Used to optionally separate methods from each other
+	// with an always marked token (for 1.5 grammar)
+	final static int SEPARATOR_TOKEN = 1;// @formatter:off
+
+	final static int J_PACKAGE = 2;				//  a // at the end of the constant means that there is a test case covering the token
+	final static int J_IMPORT = 3;				//
+	final static int J_CLASS_BEGIN = 4;			//
+	final static int J_CLASS_END = 5;			//
+	final static int J_METHOD_BEGIN = 6;		//
+	final static int J_METHOD_END = 7;			//
+	final static int J_VARDEF = 8;				//
+	final static int J_SYNC_BEGIN = 9;			//
+	final static int J_SYNC_END = 10;			//
+	final static int J_DO_BEGIN = 11;			//
+	final static int J_DO_END = 12;				//
+	final static int J_WHILE_BEGIN = 13;		//
+	final static int J_WHILE_END = 14;			//		
+	final static int J_FOR_BEGIN = 15;			//
+	final static int J_FOR_END = 16;			//
+	final static int J_SWITCH_BEGIN = 17;		//
+	final static int J_SWITCH_END = 18;			//
+	final static int J_CASE = 19;				//
+	final static int J_TRY_BEGIN = 20;			//
+	final static int J_CATCH_BEGIN = 21;    	//
+	final static int J_CATCH_END = 22;      	//
+	final static int J_FINALLY = 23;			//
+	final static int J_IF_BEGIN = 24;			//
+	final static int J_ELSE = 25;				//
+	final static int J_IF_END = 26;				//
+	final static int J_COND = 27;				//
+	final static int J_BREAK = 28;				//
+	final static int J_CONTINUE = 29;			//
+	final static int J_RETURN = 30;				//
+	final static int J_THROW = 31;				//
+	final static int J_IN_CLASS_BEGIN = 32;		//
+	final static int J_IN_CLASS_END = 33;		//
+	final static int J_APPLY = 34;				//
+	final static int J_NEWCLASS = 35;			//
+	final static int J_NEWARRAY = 36;			//
+	final static int J_ASSIGN = 37;				//
+	final static int J_INTERFACE_BEGIN = 38;	//
+	final static int J_INTERFACE_END = 39;		//
+	final static int J_CONSTR_BEGIN = 40;		//
+	final static int J_CONSTR_END = 41;			//
+	final static int J_INIT_BEGIN = 42;			//
+	final static int J_INIT_END = 43;			//
+	final static int J_VOID = 44;				//
+	final static int J_ARRAY_INIT_BEGIN = 45;	//
+	final static int J_ARRAY_INIT_END = 46; 	//
+
+	// new in 1.5:
+	final static int J_ENUM_BEGIN = 47;			//
+	final static int J_ENUM_CLASS_BEGIN = 48;	//
+	final static int J_ENUM_END = 49;			//
+	final static int J_GENERIC = 50;			//
+	final static int J_ASSERT = 51;				//
+
+	final static int J_ANNO = 52;				//
+	final static int J_ANNO_MARKER = 53;		//
+	final static int J_ANNO_M_BEGIN = 54;		//
+	final static int J_ANNO_M_END = 55;			//
+	final static int J_ANNO_T_BEGIN = 56;		//
+	final static int J_ANNO_T_END = 57;			//
+	final static int J_ANNO_C_BEGIN = 58;		//
+	final static int J_ANNO_C_END = 59;			//
+
+	// new in 1.7
+	final static int J_TRY_WITH_RESOURCE = 60; 	//
+
+	final static int NUM_DIFF_TOKENS = 61;		// @formatter:on
+}

+ 1600 - 0
jplag.frontend.java-1.7/src/main/java/jplag/java17/JplagJava7Listener.java

@@ -0,0 +1,1600 @@
+package jplag.java17;
+
+import jplag.java17.grammar.*;
+import jplag.java17.grammar.Java7Parser.AnnotationContext;
+import jplag.java17.grammar.Java7Parser.AnnotationMethodContext;
+import jplag.java17.grammar.Java7Parser.AnnotationNameContext;
+import jplag.java17.grammar.Java7Parser.AnnotationTypeDeclarationContext;
+import jplag.java17.grammar.Java7Parser.AnnotationTypeElementContext;
+import jplag.java17.grammar.Java7Parser.ArgumentsContext;
+import jplag.java17.grammar.Java7Parser.ArrayCreatorRestContext;
+import jplag.java17.grammar.Java7Parser.ArrayInitializerContext;
+import jplag.java17.grammar.Java7Parser.AssertStmtContext;
+import jplag.java17.grammar.Java7Parser.BlockContext;
+import jplag.java17.grammar.Java7Parser.BlockStatementContext;
+import jplag.java17.grammar.Java7Parser.BlockStmtContext;
+import jplag.java17.grammar.Java7Parser.BooleanLiteralContext;
+import jplag.java17.grammar.Java7Parser.BoundContext;
+import jplag.java17.grammar.Java7Parser.BreakContext;
+import jplag.java17.grammar.Java7Parser.CatchClauseContext;
+import jplag.java17.grammar.Java7Parser.CbdBlockContext;
+import jplag.java17.grammar.Java7Parser.CbdMemberContext;
+import jplag.java17.grammar.Java7Parser.CbdSemicolonContext;
+import jplag.java17.grammar.Java7Parser.ClassBodyContext;
+import jplag.java17.grammar.Java7Parser.ClassCreatorRestContext;
+import jplag.java17.grammar.Java7Parser.ClassDeclarationContext;
+import jplag.java17.grammar.Java7Parser.ClassOrInterfaceDeclarationContext;
+import jplag.java17.grammar.Java7Parser.ClassOrInterfaceTypeContext;
+import jplag.java17.grammar.Java7Parser.CompilationUnitContext;
+import jplag.java17.grammar.Java7Parser.ConstantDeclaratorContext;
+import jplag.java17.grammar.Java7Parser.ConstantDeclaratorRestContext;
+import jplag.java17.grammar.Java7Parser.ConstantDeclaratorsRestContext;
+import jplag.java17.grammar.Java7Parser.ConstantExpressionContext;
+import jplag.java17.grammar.Java7Parser.ConstructorDeclarationContext;
+import jplag.java17.grammar.Java7Parser.ContinueStmtContext;
+import jplag.java17.grammar.Java7Parser.CreatedNameContext;
+import jplag.java17.grammar.Java7Parser.CreatorContext;
+import jplag.java17.grammar.Java7Parser.DefaultValueContext;
+import jplag.java17.grammar.Java7Parser.DoWhileStmtContext;
+import jplag.java17.grammar.Java7Parser.ElementValueArrayInitializerContext;
+import jplag.java17.grammar.Java7Parser.ElementValueContext;
+import jplag.java17.grammar.Java7Parser.ElementValuePairContext;
+import jplag.java17.grammar.Java7Parser.ElementValuePairsContext;
+import jplag.java17.grammar.Java7Parser.EnhancedForControlContext;
+import jplag.java17.grammar.Java7Parser.EnumConstantContext;
+import jplag.java17.grammar.Java7Parser.EnumConstantNameContext;
+import jplag.java17.grammar.Java7Parser.EnumConstantsContext;
+import jplag.java17.grammar.Java7Parser.EnumDeclarationContext;
+import jplag.java17.grammar.Java7Parser.ExplicitConstructorInvocationContext;
+import jplag.java17.grammar.Java7Parser.ExplicitGenericInvocationContext;
+import jplag.java17.grammar.Java7Parser.ExprArrayExpressionContext;
+import jplag.java17.grammar.Java7Parser.ExprAssignmentContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryAndContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryBoolAndContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryBoolOrContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryEqualsContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryNotContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryOperatorAddContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryOperatorCompContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryOperatorGTContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryOperatorInstanceofContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryOperatorMultContext;
+import jplag.java17.grammar.Java7Parser.ExprBinaryOrContext;
+import jplag.java17.grammar.Java7Parser.ExprCastExpressionContext;
+import jplag.java17.grammar.Java7Parser.ExprConditionalExpressionContext;
+import jplag.java17.grammar.Java7Parser.ExprExplicitGenericInvocationContext;
+import jplag.java17.grammar.Java7Parser.ExprExpressionIncDecContext;
+import jplag.java17.grammar.Java7Parser.ExprIdentifierContext;
+import jplag.java17.grammar.Java7Parser.ExprIncDecExpressionContext;
+import jplag.java17.grammar.Java7Parser.ExprMethodExpressionListContext;
+import jplag.java17.grammar.Java7Parser.ExprNewCreatorContext;
+import jplag.java17.grammar.Java7Parser.ExprNewIdentidierContext;
+import jplag.java17.grammar.Java7Parser.ExprNotExpressionContext;
+import jplag.java17.grammar.Java7Parser.ExprPrimaryContext;
+import jplag.java17.grammar.Java7Parser.ExprSuperContext;
+import jplag.java17.grammar.Java7Parser.ExprSuperIdentifierContext;
+import jplag.java17.grammar.Java7Parser.ExprThisContext;
+import jplag.java17.grammar.Java7Parser.ExpressionListContext;
+import jplag.java17.grammar.Java7Parser.FieldDeclarationContext;
+import jplag.java17.grammar.Java7Parser.ForControlContext;
+import jplag.java17.grammar.Java7Parser.ForInitContext;
+import jplag.java17.grammar.Java7Parser.ForStmtContext;
+import jplag.java17.grammar.Java7Parser.ForUpdateContext;
+import jplag.java17.grammar.Java7Parser.FormalParameterDeclarationsContext;
+import jplag.java17.grammar.Java7Parser.FormalParameterVariablesContext;
+import jplag.java17.grammar.Java7Parser.FormalParametersContext;
+import jplag.java17.grammar.Java7Parser.IdentifiedStmtContext;
+import jplag.java17.grammar.Java7Parser.IfStmtContext;
+import jplag.java17.grammar.Java7Parser.ImportDeclarationContext;
+import jplag.java17.grammar.Java7Parser.InnerCreatorContext;
+import jplag.java17.grammar.Java7Parser.IntegerLiteralContext;
+import jplag.java17.grammar.Java7Parser.InterfaceBodyContext;
+import jplag.java17.grammar.Java7Parser.InterfaceDeclarationContext;
+import jplag.java17.grammar.Java7Parser.InterfaceGenericMethodDeclContext;
+import jplag.java17.grammar.Java7Parser.InterfaceMemberDeclContext;
+import jplag.java17.grammar.Java7Parser.InterfaceMethodDeclaratorRestContext;
+import jplag.java17.grammar.Java7Parser.InterfaceMethodOrFieldDeclContext;
+import jplag.java17.grammar.Java7Parser.InterfaceMethodOrFieldRestContext;
+import jplag.java17.grammar.Java7Parser.LiteralContext;
+import jplag.java17.grammar.Java7Parser.LocalVariableDeclarationContext;
+import jplag.java17.grammar.Java7Parser.MemberDeclContext;
+import jplag.java17.grammar.Java7Parser.MethodBodyContext;
+import jplag.java17.grammar.Java7Parser.MethodDeclarationContext;
+import jplag.java17.grammar.Java7Parser.ModifierContext;
+import jplag.java17.grammar.Java7Parser.NonWildcardTypeArgumentsContext;
+import jplag.java17.grammar.Java7Parser.NormalClassDeclarationContext;
+import jplag.java17.grammar.Java7Parser.NormalInterfaceDeclarationContext;
+import jplag.java17.grammar.Java7Parser.PackageDeclarationContext;
+import jplag.java17.grammar.Java7Parser.PackageOrTypeNameContext;
+import jplag.java17.grammar.Java7Parser.ParExpressionContext;
+import jplag.java17.grammar.Java7Parser.PrimaryContext;
+import jplag.java17.grammar.Java7Parser.PrimitiveTypeContext;
+import jplag.java17.grammar.Java7Parser.QualifiedIdentifierContext;
+import jplag.java17.grammar.Java7Parser.QualifiedIdentifierListContext;
+import jplag.java17.grammar.Java7Parser.ResourceContext;
+import jplag.java17.grammar.Java7Parser.ResourcesContext;
+import jplag.java17.grammar.Java7Parser.ReturnStmtContext;
+import jplag.java17.grammar.Java7Parser.SemicStmtContext;
+import jplag.java17.grammar.Java7Parser.StatementExpressStmtContext;
+import jplag.java17.grammar.Java7Parser.StatementExpressionContext;
+import jplag.java17.grammar.Java7Parser.SwitchBlockContext;
+import jplag.java17.grammar.Java7Parser.SwitchBlockStatementGroupContext;
+import jplag.java17.grammar.Java7Parser.SwitchLabelContext;
+import jplag.java17.grammar.Java7Parser.SwitchStmtContext;
+import jplag.java17.grammar.Java7Parser.SynchronizedStmtContext;
+import jplag.java17.grammar.Java7Parser.ThrowStmtContext;
+import jplag.java17.grammar.Java7Parser.TryStatementContext;
+import jplag.java17.grammar.Java7Parser.TryStmtContext;
+import jplag.java17.grammar.Java7Parser.TypeArgumentContext;
+import jplag.java17.grammar.Java7Parser.TypeArgumentsContext;
+import jplag.java17.grammar.Java7Parser.TypeDeclarationContext;
+import jplag.java17.grammar.Java7Parser.TypeListContext;
+import jplag.java17.grammar.Java7Parser.TypeNameContext;
+import jplag.java17.grammar.Java7Parser.TypeParameterContext;
+import jplag.java17.grammar.Java7Parser.TypeParametersContext;
+import jplag.java17.grammar.Java7Parser.TypeRefContext;
+import jplag.java17.grammar.Java7Parser.VariableDeclaratorContext;
+import jplag.java17.grammar.Java7Parser.VariableDeclaratorIdContext;
+import jplag.java17.grammar.Java7Parser.VariableDeclaratorsContext;
+import jplag.java17.grammar.Java7Parser.VariableInitializerContext;
+import jplag.java17.grammar.Java7Parser.VariableModifierContext;
+import jplag.java17.grammar.Java7Parser.VoidInterfaceMethodDeclaratorRestContext;
+import jplag.java17.grammar.Java7Parser.WhileStmtContext;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ErrorNode;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+public class JplagJava7Listener implements Java7Listener, JavaTokenConstants {
+
+	private jplag.java17.Parser jplagParser;
+
+	public JplagJava7Listener(jplag.java17.Parser jplag) {
+		jplagParser = jplag;
+	}
+
+	@Override
+	public void enterEveryRule(ParserRuleContext arg0) {
+
+	}
+
+	@Override
+	public void exitEveryRule(ParserRuleContext arg0) {
+
+	}
+
+	@Override
+	public void visitErrorNode(ErrorNode arg0) {
+
+	}
+
+	@Override
+	public void visitTerminal(TerminalNode arg0) {
+		if (arg0.getText().equals("else")) {
+			jplagParser.add(J_ELSE, arg0.getSymbol());
+		}
+
+	}
+
+	@Override
+	public void enterInnerCreator(InnerCreatorContext ctx) {
+
+	}
+
+	@Override
+	public void exitInnerCreator(InnerCreatorContext ctx) {
+
+	}
+
+	@Override
+	public void enterAnnotationTypeDeclaration(AnnotationTypeDeclarationContext ctx) {
+		jplagParser.add(J_ANNO_T_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitAnnotationTypeDeclaration(AnnotationTypeDeclarationContext ctx) {
+		jplagParser.add(J_ANNO_T_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterVariableDeclarator(VariableDeclaratorContext ctx) {
+		jplagParser.add(J_VARDEF, ctx.getStart());
+	}
+
+	@Override
+	public void exitVariableDeclarator(VariableDeclaratorContext ctx) {
+
+	}
+
+	@Override
+	public void enterResources(ResourcesContext ctx) {
+
+	}
+
+	@Override
+	public void exitResources(ResourcesContext ctx) {
+
+	}
+
+	@Override
+	public void enterExpressionList(ExpressionListContext ctx) {
+
+	}
+
+	@Override
+	public void exitExpressionList(ExpressionListContext ctx) {
+
+	}
+
+	@Override
+	public void enterQualifiedIdentifier(QualifiedIdentifierContext ctx) {
+
+	}
+
+	@Override
+	public void exitQualifiedIdentifier(QualifiedIdentifierContext ctx) {
+
+	}
+
+	@Override
+	public void enterTypeDeclaration(TypeDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void exitTypeDeclaration(TypeDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void enterForUpdate(ForUpdateContext ctx) {
+
+	}
+
+	@Override
+	public void exitForUpdate(ForUpdateContext ctx) {
+
+	}
+
+	@Override
+	public void enterFormalParameterVariables(FormalParameterVariablesContext ctx) {
+
+	}
+
+	@Override
+	public void exitFormalParameterVariables(FormalParameterVariablesContext ctx) {
+
+	}
+
+	@Override
+	public void enterElementValueArrayInitializer(ElementValueArrayInitializerContext ctx) {
+
+	}
+
+	@Override
+	public void exitElementValueArrayInitializer(ElementValueArrayInitializerContext ctx) {
+
+	}
+
+	@Override
+	public void enterAnnotation(AnnotationContext ctx) {
+		jplagParser.add(J_ANNO, ctx.getStart());
+	}
+
+	@Override
+	public void exitAnnotation(AnnotationContext ctx) {
+
+	}
+
+	@Override
+	public void enterMemberDecl(MemberDeclContext ctx) {
+
+	}
+
+	@Override
+	public void exitMemberDecl(MemberDeclContext ctx) {
+
+	}
+
+	@Override
+	public void enterEnumConstant(EnumConstantContext ctx) {
+
+	}
+
+	@Override
+	public void exitEnumConstant(EnumConstantContext ctx) {
+
+	}
+
+	@Override
+	public void enterAnnotationName(AnnotationNameContext ctx) {
+
+	}
+
+	@Override
+	public void exitAnnotationName(AnnotationNameContext ctx) {
+
+	}
+
+	@Override
+	public void enterEnhancedForControl(EnhancedForControlContext ctx) {
+
+	}
+
+	@Override
+	public void exitEnhancedForControl(EnhancedForControlContext ctx) {
+
+	}
+
+	@Override
+	public void enterPrimary(PrimaryContext ctx) {
+
+	}
+
+	@Override
+	public void exitPrimary(PrimaryContext ctx) {
+
+	}
+
+	@Override
+	public void enterNormalClassDeclaration(NormalClassDeclarationContext ctx) {
+		jplagParser.add(J_CLASS_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitNormalClassDeclaration(NormalClassDeclarationContext ctx) {
+		jplagParser.add(J_CLASS_END, ctx.getStop());
+
+	}
+
+	@Override
+	public void enterClassBody(ClassBodyContext ctx) {
+
+	}
+
+	@Override
+	public void exitClassBody(ClassBodyContext ctx) {
+
+	}
+
+	@Override
+	public void enterDefaultValue(DefaultValueContext ctx) {
+
+	}
+
+	@Override
+	public void exitDefaultValue(DefaultValueContext ctx) {
+
+	}
+
+	@Override
+	public void enterImportDeclaration(ImportDeclarationContext ctx) {
+		jplagParser.add(J_IMPORT, ctx.getStart());
+	}
+
+	@Override
+	public void exitImportDeclaration(ImportDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void enterVariableModifier(VariableModifierContext ctx) {
+
+	}
+
+	@Override
+	public void exitVariableModifier(VariableModifierContext ctx) {
+
+	}
+
+	@Override
+	public void enterEnumConstantName(EnumConstantNameContext ctx) {
+
+	}
+
+	@Override
+	public void exitEnumConstantName(EnumConstantNameContext ctx) {
+
+	}
+
+	@Override
+	public void enterCreatedName(CreatedNameContext ctx) {
+	}
+
+	@Override
+	public void exitCreatedName(CreatedNameContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceDeclaration(InterfaceDeclarationContext ctx) {
+	}
+
+	@Override
+	public void exitInterfaceDeclaration(InterfaceDeclarationContext ctx) {
+	}
+
+	@Override
+	public void enterQualifiedIdentifierList(QualifiedIdentifierListContext ctx) {
+
+	}
+
+	@Override
+	public void exitQualifiedIdentifierList(QualifiedIdentifierListContext ctx) {
+
+	}
+
+	@Override
+	public void enterPackageDeclaration(PackageDeclarationContext ctx) {
+		if (!ctx.annotation().isEmpty()) {
+			// if we have an annoation, we have an package-info.java and suppress the package token
+		} else {
+			jplagParser.add(J_PACKAGE, ctx.getStart());
+		}
+	}
+
+	@Override
+	public void exitPackageDeclaration(PackageDeclarationContext ctx) {
+	}
+
+	@Override
+	public void enterTypeRef(TypeRefContext ctx) {
+
+	}
+
+	@Override
+	public void exitTypeRef(TypeRefContext ctx) {
+
+	}
+
+	@Override
+	public void enterConstantDeclarator(ConstantDeclaratorContext ctx) {
+		jplagParser.add(J_VARDEF, ctx.getStart());
+	}
+
+	@Override
+	public void exitConstantDeclarator(ConstantDeclaratorContext ctx) {
+
+	}
+
+	@Override
+	public void enterConstantDeclaratorRest(ConstantDeclaratorRestContext ctx) {
+
+	}
+
+	@Override
+	public void exitConstantDeclaratorRest(ConstantDeclaratorRestContext ctx) {
+
+	}
+
+	@Override
+	public void enterElementValuePairs(ElementValuePairsContext ctx) {
+
+	}
+
+	@Override
+	public void exitElementValuePairs(ElementValuePairsContext ctx) {
+
+	}
+
+	@Override
+	public void enterVariableDeclarators(VariableDeclaratorsContext ctx) {
+
+	}
+
+	@Override
+	public void exitVariableDeclarators(VariableDeclaratorsContext ctx) {
+
+	}
+
+	@Override
+	public void enterTypeArguments(TypeArgumentsContext ctx) {
+
+	}
+
+	@Override
+	public void exitTypeArguments(TypeArgumentsContext ctx) {
+
+	}
+
+	@Override
+	public void enterClassCreatorRest(ClassCreatorRestContext ctx) {
+		if (ctx.classBody() != null) {
+			jplagParser.add(J_IN_CLASS_BEGIN, ctx.getStart());
+		}
+	}
+
+	@Override
+	public void exitClassCreatorRest(ClassCreatorRestContext ctx) {
+		if (ctx.classBody() != null) {
+			jplagParser.add(J_IN_CLASS_END, ctx.getStop());
+		}
+	}
+
+	@Override
+	public void enterSwitchBlock(SwitchBlockContext ctx) {
+
+	}
+
+	@Override
+	public void exitSwitchBlock(SwitchBlockContext ctx) {
+
+	}
+
+	@Override
+	public void enterAnnotationMethod(AnnotationMethodContext ctx) {
+
+	}
+
+	@Override
+	public void exitAnnotationMethod(AnnotationMethodContext ctx) {
+
+	}
+
+	@Override
+	public void enterModifier(ModifierContext ctx) {
+
+	}
+
+	@Override
+	public void exitModifier(ModifierContext ctx) {
+
+	}
+
+	@Override
+	public void enterCatchClause(CatchClauseContext ctx) {
+		jplagParser.add(J_CATCH_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitCatchClause(CatchClauseContext ctx) {
+		jplagParser.add(J_CATCH_END, ctx.getStop());
+	}
+
+
+	@Override
+	public void enterEnumConstants(EnumConstantsContext ctx) {
+		jplagParser.add(J_ENUM_CLASS_BEGIN, ctx.getStop());
+	}
+
+	@Override
+	public void exitEnumConstants(EnumConstantsContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceBody(InterfaceBodyContext ctx) {
+
+	}
+
+	@Override
+	public void exitInterfaceBody(InterfaceBodyContext ctx) {
+
+	}
+
+	@Override
+	public void enterConstantExpression(ConstantExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitConstantExpression(ConstantExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterPackageOrTypeName(PackageOrTypeNameContext ctx) {
+	}
+
+	@Override
+	public void exitPackageOrTypeName(PackageOrTypeNameContext ctx) {
+	}
+
+	@Override
+	public void enterForControl(ForControlContext ctx) {
+	}
+
+	@Override
+	public void exitForControl(ForControlContext ctx) {
+	}
+
+	@Override
+	public void enterEnumDeclaration(EnumDeclarationContext ctx) {
+		jplagParser.add(J_ENUM_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitEnumDeclaration(EnumDeclarationContext ctx) {
+		jplagParser.add(J_ENUM_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterLocalVariableDeclaration(LocalVariableDeclarationContext ctx) {
+	}
+
+	@Override
+	public void exitLocalVariableDeclaration(LocalVariableDeclarationContext ctx) {
+	}
+
+	@Override
+	public void enterTypeList(TypeListContext ctx) {
+	}
+
+	@Override
+	public void exitTypeList(TypeListContext ctx) {
+
+	}
+
+	@Override
+	public void enterTypeParameter(TypeParameterContext ctx) {
+
+	}
+
+	@Override
+	public void exitTypeParameter(TypeParameterContext ctx) {
+
+	}
+
+	@Override
+	public void enterVariableDeclaratorId(VariableDeclaratorIdContext ctx) {
+
+	}
+
+	@Override
+	public void exitVariableDeclaratorId(VariableDeclaratorIdContext ctx) {
+
+	}
+
+	@Override
+	public void enterExplicitConstructorInvocation(ExplicitConstructorInvocationContext ctx) {
+		jplagParser.add(J_APPLY, ctx.start);
+	}
+
+	@Override
+	public void exitExplicitConstructorInvocation(ExplicitConstructorInvocationContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceMethodDeclaratorRest(InterfaceMethodDeclaratorRestContext ctx) {
+
+	}
+
+	@Override
+	public void exitInterfaceMethodDeclaratorRest(InterfaceMethodDeclaratorRestContext ctx) {
+
+	}
+
+	@Override
+	public void enterElementValue(ElementValueContext ctx) {
+
+	}
+
+	@Override
+	public void exitElementValue(ElementValueContext ctx) {
+
+	}
+
+	@Override
+	public void enterCompilationUnit(CompilationUnitContext ctx) {
+
+	}
+
+	@Override
+	public void exitCompilationUnit(CompilationUnitContext ctx) {
+
+	}
+
+	@Override
+	public void enterStatementExpression(StatementExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitStatementExpression(StatementExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterClassOrInterfaceType(ClassOrInterfaceTypeContext ctx) {
+
+	}
+
+	@Override
+	public void exitClassOrInterfaceType(ClassOrInterfaceTypeContext ctx) {
+
+	}
+
+	@Override
+	public void enterFormalParameterDeclarations(FormalParameterDeclarationsContext ctx) {
+
+	}
+
+	@Override
+	public void exitFormalParameterDeclarations(FormalParameterDeclarationsContext ctx) {
+
+	}
+
+	@Override
+	public void enterBlock(BlockContext ctx) {
+
+	}
+
+	@Override
+	public void exitBlock(BlockContext ctx) {
+
+	}
+
+	@Override
+	public void enterVariableInitializer(VariableInitializerContext ctx) {
+		if (ctx.parent instanceof ArrayInitializerContext) {
+			// dont print assignment, as this is part of an array initialization
+		} else {
+			jplagParser.add(J_ASSIGN, ctx.getStart());
+		}
+	}
+
+	@Override
+	public void exitVariableInitializer(VariableInitializerContext ctx) {
+
+	}
+
+	@Override
+	public void enterBlockStatement(BlockStatementContext ctx) {
+
+	}
+
+	@Override
+	public void exitBlockStatement(BlockStatementContext ctx) {
+
+	}
+
+	@Override
+	public void enterIntegerLiteral(IntegerLiteralContext ctx) {
+
+	}
+
+	@Override
+	public void exitIntegerLiteral(IntegerLiteralContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceMemberDecl(InterfaceMemberDeclContext ctx) {
+
+	}
+
+	@Override
+	public void exitInterfaceMemberDecl(InterfaceMemberDeclContext ctx) {
+
+	}
+
+	@Override
+	public void enterCreator(CreatorContext ctx) {
+		if (ctx.classCreatorRest() != null) {
+			if (// @formatter:off
+				// "normal" generic
+				ctx.createdName().typeArguments().size() > 0 
+				// allow diamond operator 
+				|| ctx.createdName().children.size() > 1 && (ctx.createdName().getChild(1).getText().equals("<") && ctx.createdName().getChild(2).getText().equals(">"))
+				|| ctx.createdName().children.size() > 3 && (ctx.createdName().getChild(3).getText().equals("<") && ctx.createdName().getChild(4).getText().equals(">"))) {
+			    // @formatter: on
+				jplagParser.add(J_GENERIC, ctx.start);
+			}
+			jplagParser.add(J_NEWCLASS, ctx.start);
+		} else if (ctx.arrayCreatorRest() != null) {
+			jplagParser.add(J_NEWARRAY, ctx.start);
+
+		}
+
+	}
+
+	@Override
+	public void exitCreator(CreatorContext ctx) {
+
+	}
+
+	@Override
+	public void enterConstantDeclaratorsRest(ConstantDeclaratorsRestContext ctx) {
+
+	}
+
+	@Override
+	public void exitConstantDeclaratorsRest(ConstantDeclaratorsRestContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceGenericMethodDecl(InterfaceGenericMethodDeclContext ctx) {
+
+	}
+
+	@Override
+	public void exitInterfaceGenericMethodDecl(InterfaceGenericMethodDeclContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceMethodOrFieldDecl(InterfaceMethodOrFieldDeclContext ctx) {
+
+	}
+
+	@Override
+	public void exitInterfaceMethodOrFieldDecl(InterfaceMethodOrFieldDeclContext ctx) {
+
+	}
+
+	@Override
+	public void enterTryStatement(TryStatementContext ctx) {
+		jplagParser.add(J_TRY_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitTryStatement(TryStatementContext ctx) {
+		if (hasFinally(ctx)) {
+			jplagParser.add(J_FINALLY, ctx.start);
+		}
+	}
+
+	private boolean hasFinally(TryStatementContext ctx) {
+		for (ParseTree pt : ctx.children) {
+			if (pt instanceof TerminalNode) {
+				if (((TerminalNode) pt).getText().equals("finally")) {
+					return true;
+				}
+			}
+		}
+		
+		return false;
+	}
+
+	@Override
+	public void enterFieldDeclaration(FieldDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void exitFieldDeclaration(FieldDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void enterNormalInterfaceDeclaration(NormalInterfaceDeclarationContext ctx) {
+		jplagParser.add(J_INTERFACE_BEGIN, ctx.start);
+	}
+
+	@Override
+	public void exitNormalInterfaceDeclaration(NormalInterfaceDeclarationContext ctx) {
+		jplagParser.add(J_INTERFACE_END, ctx.start);
+	}
+
+	@Override
+	public void enterExplicitGenericInvocation(ExplicitGenericInvocationContext ctx) {
+		jplagParser.add(J_APPLY, ctx.start);
+	}
+
+	@Override
+	public void exitExplicitGenericInvocation(ExplicitGenericInvocationContext ctx) {
+
+	}
+
+	@Override
+	public void enterMethodDeclaration(MethodDeclarationContext ctx) {
+		if (ctx.start.getText().equals("void")) {
+			jplagParser.add(J_VOID, ctx.start);
+		}
+		jplagParser.add(J_METHOD_BEGIN, ctx.start);
+	}
+
+	@Override
+	public void exitMethodDeclaration(MethodDeclarationContext ctx) {
+		jplagParser.add(J_METHOD_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterParExpression(ParExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitParExpression(ParExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterSwitchLabel(SwitchLabelContext ctx) {
+
+	}
+
+	@Override
+	public void exitSwitchLabel(SwitchLabelContext ctx) {
+		jplagParser.add(J_CASE, ctx.getStop());
+	}
+
+	@Override
+	public void enterConstructorDeclaration(ConstructorDeclarationContext ctx) {
+		jplagParser.add(J_CONSTR_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitConstructorDeclaration(ConstructorDeclarationContext ctx) {
+		jplagParser.add(J_CONSTR_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterTypeParameters(TypeParametersContext ctx) {
+
+	}
+
+	@Override
+	public void exitTypeParameters(TypeParametersContext ctx) {
+
+	}
+
+	@Override
+	public void enterAnnotationTypeElement(AnnotationTypeElementContext ctx) {
+
+	}
+
+	@Override
+	public void exitAnnotationTypeElement(AnnotationTypeElementContext ctx) {
+
+	}
+
+	@Override
+	public void enterResource(ResourceContext ctx) {
+		jplagParser.add(J_TRY_WITH_RESOURCE, ctx.getStart());
+	}
+
+	@Override
+	public void exitResource(ResourceContext ctx) {
+
+	}
+
+	@Override
+	public void enterClassDeclaration(ClassDeclarationContext ctx) {
+	}
+
+	@Override
+	public void exitClassDeclaration(ClassDeclarationContext ctx) {
+	}
+
+	@Override
+	public void enterElementValuePair(ElementValuePairContext ctx) {
+
+	}
+
+	@Override
+	public void exitElementValuePair(ElementValuePairContext ctx) {
+
+	}
+
+	@Override
+	public void enterBooleanLiteral(BooleanLiteralContext ctx) {
+
+	}
+
+	@Override
+	public void exitBooleanLiteral(BooleanLiteralContext ctx) {
+
+	}
+
+	@Override
+	public void enterVoidInterfaceMethodDeclaratorRest(VoidInterfaceMethodDeclaratorRestContext ctx) {
+
+	}
+
+	@Override
+	public void exitVoidInterfaceMethodDeclaratorRest(VoidInterfaceMethodDeclaratorRestContext ctx) {
+
+	}
+
+	@Override
+	public void enterInterfaceMethodOrFieldRest(InterfaceMethodOrFieldRestContext ctx) {
+
+	}
+
+	@Override
+	public void exitInterfaceMethodOrFieldRest(InterfaceMethodOrFieldRestContext ctx) {
+
+	}
+
+	@Override
+	public void enterTypeName(TypeNameContext ctx) {
+
+	}
+
+	@Override
+	public void exitTypeName(TypeNameContext ctx) {
+
+	}
+
+	@Override
+	public void enterArguments(ArgumentsContext ctx) {
+	}
+
+	@Override
+	public void exitArguments(ArgumentsContext ctx) {
+
+	}
+
+	@Override
+	public void enterMethodBody(MethodBodyContext ctx) {
+
+	}
+
+	@Override
+	public void exitMethodBody(MethodBodyContext ctx) {
+
+	}
+
+	@Override
+	public void enterArrayInitializer(ArrayInitializerContext ctx) {
+		jplagParser.add(J_ARRAY_INIT_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitArrayInitializer(ArrayInitializerContext ctx) {
+		jplagParser.add(J_ARRAY_INIT_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterFormalParameters(FormalParametersContext ctx) {
+
+	}
+
+	@Override
+	public void exitFormalParameters(FormalParametersContext ctx) {
+
+	}
+
+	@Override
+	public void enterPrimitiveType(PrimitiveTypeContext ctx) {
+
+	}
+
+	@Override
+	public void exitPrimitiveType(PrimitiveTypeContext ctx) {
+
+	}
+
+	@Override
+	public void enterNonWildcardTypeArguments(NonWildcardTypeArgumentsContext ctx) {
+
+	}
+
+	@Override
+	public void exitNonWildcardTypeArguments(NonWildcardTypeArgumentsContext ctx) {
+
+	}
+
+	@Override
+	public void enterTypeArgument(TypeArgumentContext ctx) {
+		if ( ctx.parent.parent instanceof CreatedNameContext) {	
+			// the generic token has already been emitted by the class emitter
+		} else {
+			jplagParser.add(J_GENERIC, ctx.getStart());
+		}
+	}
+
+	@Override
+	public void exitTypeArgument(TypeArgumentContext ctx) {
+
+	}
+
+	@Override
+	public void enterClassOrInterfaceDeclaration(ClassOrInterfaceDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void exitClassOrInterfaceDeclaration(ClassOrInterfaceDeclarationContext ctx) {
+
+	}
+
+	@Override
+	public void enterForInit(ForInitContext ctx) {
+
+	}
+
+	@Override
+	public void exitForInit(ForInitContext ctx) {
+
+	}
+
+	@Override
+	public void enterArrayCreatorRest(ArrayCreatorRestContext ctx) {
+
+	}
+
+	@Override
+	public void exitArrayCreatorRest(ArrayCreatorRestContext ctx) {
+
+	}
+
+	@Override
+	public void enterBound(BoundContext ctx) {
+
+	}
+
+	@Override
+	public void exitBound(BoundContext ctx) {
+
+	}
+
+	@Override
+	public void enterSwitchBlockStatementGroup(SwitchBlockStatementGroupContext ctx) {
+
+	}
+
+	@Override
+	public void exitSwitchBlockStatementGroup(SwitchBlockStatementGroupContext ctx) {
+
+	}
+
+	@Override
+	public void enterLiteral(LiteralContext ctx) {
+
+	}
+
+	@Override
+	public void exitLiteral(LiteralContext ctx) {
+
+	}
+
+	@Override
+	public void enterDoWhileStmt(DoWhileStmtContext ctx) {
+		jplagParser.add(J_DO_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitDoWhileStmt(DoWhileStmtContext ctx) {
+		jplagParser.add(J_DO_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterBreak(BreakContext ctx) {
+		jplagParser.add(J_BREAK, ctx.getStart());
+	}
+
+	@Override
+	public void exitBreak(BreakContext ctx) {
+
+	}
+
+	@Override
+	public void enterIfStmt(IfStmtContext ctx) {
+		jplagParser.add(J_IF_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitIfStmt(IfStmtContext ctx) {
+		jplagParser.add(J_IF_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterThrowStmt(ThrowStmtContext ctx) {
+		jplagParser.add(J_THROW, ctx.getStart());
+	}
+
+	@Override
+	public void exitThrowStmt(ThrowStmtContext ctx) {
+	}
+
+	@Override
+	public void enterSynchronizedStmt(SynchronizedStmtContext ctx) {
+		jplagParser.add(J_SYNC_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitSynchronizedStmt(SynchronizedStmtContext ctx) {
+		jplagParser.add(J_SYNC_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterStatementExpressStmt(StatementExpressStmtContext ctx) {
+	}
+
+	@Override
+	public void exitStatementExpressStmt(StatementExpressStmtContext ctx) {
+
+	}
+
+	@Override
+	public void enterBlockStmt(BlockStmtContext ctx) {
+
+	}
+
+	@Override
+	public void exitBlockStmt(BlockStmtContext ctx) {
+
+	}
+
+	@Override
+	public void enterReturnStmt(ReturnStmtContext ctx) {
+		jplagParser.add(J_RETURN, ctx.getStart());
+	}
+
+	@Override
+	public void exitReturnStmt(ReturnStmtContext ctx) {
+
+	}
+
+	@Override
+	public void enterSemicStmt(SemicStmtContext ctx) {
+
+	}
+
+	@Override
+	public void exitSemicStmt(SemicStmtContext ctx) {
+
+	}
+
+	@Override
+	public void enterIdentifiedStmt(IdentifiedStmtContext ctx) {
+
+	}
+
+	@Override
+	public void exitIdentifiedStmt(IdentifiedStmtContext ctx) {
+
+	}
+
+	@Override
+	public void enterTryStmt(TryStmtContext ctx) {
+		// nothing happens here see enterTryStatement
+	}
+
+	@Override
+	public void exitTryStmt(TryStmtContext ctx) {
+		// nothing happens here see exitTryStatement
+	}
+
+	@Override
+	public void enterContinueStmt(ContinueStmtContext ctx) {
+		jplagParser.add(J_CONTINUE, ctx.getStart());
+	}
+
+	@Override
+	public void exitContinueStmt(ContinueStmtContext ctx) {
+	}
+
+	@Override
+	public void enterAssertStmt(AssertStmtContext ctx) {
+		jplagParser.add(J_ASSERT, ctx.getStart());
+	}
+
+	@Override
+	public void exitAssertStmt(AssertStmtContext ctx) {
+	}
+
+	@Override
+	public void enterSwitchStmt(SwitchStmtContext ctx) {
+		jplagParser.add(J_SWITCH_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitSwitchStmt(SwitchStmtContext ctx) {
+		jplagParser.add(J_SWITCH_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterForStmt(ForStmtContext ctx) {
+		jplagParser.add(J_FOR_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitForStmt(ForStmtContext ctx) {
+		jplagParser.add(J_FOR_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterWhileStmt(WhileStmtContext ctx) {
+		jplagParser.add(J_WHILE_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitWhileStmt(WhileStmtContext ctx) {
+		jplagParser.add(J_WHILE_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterExprBinaryOperatorInstanceof(ExprBinaryOperatorInstanceofContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryOperatorInstanceof(ExprBinaryOperatorInstanceofContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryOperatorGT(ExprBinaryOperatorGTContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryOperatorGT(ExprBinaryOperatorGTContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprNotExpression(ExprNotExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprNotExpression(ExprNotExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprNewCreator(ExprNewCreatorContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprNewCreator(ExprNewCreatorContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryOperatorAdd(ExprBinaryOperatorAddContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryOperatorAdd(ExprBinaryOperatorAddContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryOperatorMult(ExprBinaryOperatorMultContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryOperatorMult(ExprBinaryOperatorMultContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprPrimary(ExprPrimaryContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprPrimary(ExprPrimaryContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprExplicitGenericInvocation(ExprExplicitGenericInvocationContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprExplicitGenericInvocation(ExprExplicitGenericInvocationContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprSuperIdentifier(ExprSuperIdentifierContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprSuperIdentifier(ExprSuperIdentifierContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprSuper(ExprSuperContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprSuper(ExprSuperContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprThis(ExprThisContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprThis(ExprThisContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryBoolAnd(ExprBinaryBoolAndContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryBoolAnd(ExprBinaryBoolAndContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryAnd(ExprBinaryAndContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryAnd(ExprBinaryAndContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprIncDecExpression(ExprIncDecExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprIncDecExpression(ExprIncDecExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryBoolOr(ExprBinaryBoolOrContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryBoolOr(ExprBinaryBoolOrContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryEquals(ExprBinaryEqualsContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryEquals(ExprBinaryEqualsContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprAssignment(ExprAssignmentContext ctx) {
+		jplagParser.add(J_ASSIGN, ctx.getStart());
+	}
+
+	@Override
+	public void exitExprAssignment(ExprAssignmentContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryNot(ExprBinaryNotContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryNot(ExprBinaryNotContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprNewIdentidier(ExprNewIdentidierContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprNewIdentidier(ExprNewIdentidierContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprMethodExpressionList(ExprMethodExpressionListContext ctx) {
+		jplagParser.add(J_APPLY, ctx.getStart());
+	}
+
+	@Override
+	public void exitExprMethodExpressionList(ExprMethodExpressionListContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprCastExpression(ExprCastExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprCastExpression(ExprCastExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryOperatorComp(ExprBinaryOperatorCompContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryOperatorComp(ExprBinaryOperatorCompContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprBinaryOr(ExprBinaryOrContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprBinaryOr(ExprBinaryOrContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprExpressionIncDec(ExprExpressionIncDecContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprExpressionIncDec(ExprExpressionIncDecContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprArrayExpression(ExprArrayExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprArrayExpression(ExprArrayExpressionContext ctx) {
+
+	}
+
+	@Override
+	public void enterExprIdentifier(ExprIdentifierContext ctx) {
+
+	}
+
+	@Override
+	public void exitExprIdentifier(ExprIdentifierContext ctx) {
+
+	}
+
+	@Override
+	public void enterCbdMember(CbdMemberContext ctx) {
+
+	}
+
+	@Override
+	public void exitCbdMember(CbdMemberContext ctx) {
+
+	}
+
+	@Override
+	public void enterCbdSemicolon(CbdSemicolonContext ctx) {
+
+	}
+
+	@Override
+	public void exitCbdSemicolon(CbdSemicolonContext ctx) {
+
+	}
+
+	@Override
+	public void enterCbdBlock(CbdBlockContext ctx) {
+		jplagParser.add(J_INIT_BEGIN, ctx.getStart());
+	}
+
+	@Override
+	public void exitCbdBlock(CbdBlockContext ctx) {
+		jplagParser.add(J_INIT_END, ctx.getStop());
+	}
+
+	@Override
+	public void enterExprConditionalExpression(ExprConditionalExpressionContext ctx) {
+		jplagParser.add(J_COND, ctx.getStart());
+	}
+
+	@Override
+	public void exitExprConditionalExpression(ExprConditionalExpressionContext ctx) {
+	}
+}

+ 63 - 0
jplag.frontend.java-1.7/src/main/java/jplag/java17/Language.java

@@ -0,0 +1,63 @@
+package jplag.java17;
+
+import java.io.File;
+
+import jplag.ProgramI;
+
+public class Language implements jplag.Language {
+	private jplag.java17.Parser parser;
+
+	public Language(ProgramI program) {
+		this.parser = new jplag.java17.Parser();
+		this.parser.setProgram(program);
+	}
+
+	public String[] suffixes() {
+		String[] res = { ".java", ".jav", ".JAVA", ".JAV" };
+		return res;
+	}
+
+	public int errorsCount() {
+		return this.parser.errorsCount();
+	}
+
+	public String name() {
+		return "Java1.7 Parser";
+	}
+
+	public String getShortName() {
+		return "java17";
+	}
+
+	public int min_token_match() {
+		return 9;
+	}
+
+	public jplag.Structure parse(File dir, String[] files) {
+		return this.parser.parse(dir, files);
+	}
+
+	public boolean errors() {
+		return this.parser.getErrors();
+	}
+
+	public boolean supportsColumns() {
+		return false; // was true - should be true :/
+	}
+
+	public boolean isPreformated() {
+		return true;
+	}
+
+	public boolean usesIndex() {
+		return false;
+	}
+
+	public int noOfTokens() {
+		return jplag.java17.JavaToken.numberOfTokens();
+	}
+
+	public String type2string(int type) {
+		return jplag.java17.JavaToken.type2string(type);
+	}
+}

+ 119 - 0
jplag.frontend.java-1.7/src/main/java/jplag/java17/Parser.java

@@ -0,0 +1,119 @@
+package jplag.java17;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+
+import jplag.Structure;
+import jplag.java17.grammar.Java7Lexer;
+import jplag.java17.grammar.Java7Parser;
+import jplag.java17.grammar.Java7Parser.CompilationUnitContext;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+
+public class Parser extends jplag.Parser implements JavaTokenConstants {
+	private Structure struct = new Structure();;
+	private String currentFile;
+
+	public static void main(String args[]) {
+		if (args.length < 1) {
+			System.out.println("Only one ore more files as parameter allowed.");
+			System.exit(-1);
+		}
+		Parser parser = new Parser();
+		parser.setProgram(new jplag.StrippedProgram());
+		jplag.Structure struct = parser.parse(null, args);
+		try {
+			BufferedReader reader = new BufferedReader(new FileReader(new File(args[0])));
+			int lineNr = 1;
+			int token = 0;
+			String line;
+			while ((line = reader.readLine()) != null) {
+				if (token < struct.size()) {
+					boolean first = true;
+					while (struct.tokens[token] != null
+							&& struct.tokens[token].getLine() == lineNr) {
+						if (!first)
+							System.out.println();
+						JavaToken tok=(JavaToken) struct.tokens[token];
+						System.out.print(JavaToken.type2string(tok.type) + " ("
+							+ tok.getLine() + ","
+							+ tok.getColumn() + ","
+							+ tok.getLength() + ")\t");
+						first = false;
+						token++;
+					}
+					if (first)
+						System.out.print("                \t");
+				}
+				System.out.println(line);
+				lineNr++;
+			}
+			reader.close();
+		} catch (IOException e) {
+			System.out.println(e);
+		}
+	}
+	
+	public jplag.Structure parse(File dir, String files[]) {
+		struct = new Structure();
+		errors = 0;
+		for (int i = 0; i < files.length; i++) {
+			getProgram().print(null, "Parsing file " + files[i] + "\n");
+			if (!parseFile(dir, files[i]))
+				errors++;
+			System.gc();//Emeric
+			struct.addToken(new JavaToken(FILE_END, files[i], -1, -1, -1));
+		}
+		this.parseEnd();
+		return struct;
+	}
+
+	public boolean parseFile(File dir, String file) {
+		BufferedInputStream fis;
+
+		ANTLRInputStream input;
+		try {
+			fis = new BufferedInputStream(new FileInputStream(new File(dir, file)));
+			currentFile = file;
+			input = new ANTLRInputStream(fis);
+
+			// create a lexer that feeds off of input CharStream
+			Java7Lexer lexer = new Java7Lexer(input);
+
+			// create a buffer of tokens pulled from the lexer
+			CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+			// create a parser that feeds off the tokens buffer
+			Java7Parser parser = new Java7Parser(tokens);
+			CompilationUnitContext cuc = parser.compilationUnit();
+
+			ParseTreeWalker ptw = new ParseTreeWalker();
+			for (int i = 0; i < cuc.getChildCount(); i++) {
+				ParseTree pt = cuc.getChild(i);
+				ptw.walk(new JplagJava7Listener(this), pt);
+			}
+
+		} catch (IOException e) {
+			getProgram().addError("Parsing Error in '" + file + "':\n" + e.getMessage() + "\n");
+			return false;
+		}
+
+		return true;
+	}
+
+	//	public void addTerminal(int type, int line, int start, String text) {
+	//		struct.addToken(new JavaToken(type, (currentFile == null ? "null" : currentFile), line, start, text.length()));
+	//	}
+	
+	public void add(int type, org.antlr.v4.runtime.Token tok) {
+		struct.addToken(new JavaToken(type, (currentFile == null ? "null" : currentFile), tok.getLine(), tok.getStartIndex(), 
+				tok.getText().length()));
+	}
+}

+ 79 - 0
jplag.frontend.java-1.7/src/test/java/jplag/antlr4Learning/Antlr4LearningTests.java

@@ -0,0 +1,79 @@
+package jplag.antlr4Learning;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import jplag.java17.JplagJava7Listener;
+import jplag.java17.grammar.Java7Lexer;
+import jplag.java17.grammar.Java7Parser;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class Antlr4LearningTests {
+	private static File srcTestResources;
+
+	@BeforeClass
+	public static void getPaths() {
+		srcTestResources = new File(System.getProperty("user.dir"), "src/test/resources");
+	}
+
+	@Test
+	public void testVisitor() throws IOException {
+		BufferedInputStream fis = new BufferedInputStream(new FileInputStream(new File(srcTestResources, "ExceptionOne.java")));
+		ANTLRInputStream input = new ANTLRInputStream(fis);
+
+		// create a lexer that feeds off of input CharStream
+		Java7Lexer lexer = new Java7Lexer(input);
+
+		// create a buffer of tokens pulled from the lexer
+		CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+		jplag.java17.grammar.Java7Parser j7p = new Java7Parser(tokens);
+		j7p.addParseListener(new JplagJava7Listener(new jplag.java17.Parser()));
+
+		j7p.compilationUnit();
+	}
+
+	@Ignore
+	public void howToUseAntlr4() throws IOException {
+		FileInputStream fis = new FileInputStream(new File(srcTestResources, "Java7FeatureTest.java"));
+		// create a CharStream that reads from file input stream
+		ANTLRInputStream input = new ANTLRInputStream(fis);
+
+		// create a lexer that feeds off of input CharStream
+		Java7Lexer lexer = new Java7Lexer(input);
+
+		// create a buffer of tokens pulled from the lexer
+		CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+		// create a parser that feeds off the tokens buffer
+		Java7Parser parser = new Java7Parser(tokens);
+
+		ParseTree tree = parser.compilationUnit(); // begin parsing at compilationUnit rule
+		System.out.println(tree.toStringTree(parser)); // print LISP-style tree
+
+	}
+
+	@Ignore
+	public void howToUseAntlr4Tokens() throws IOException {
+		FileInputStream fis = new FileInputStream(new File(srcTestResources, "Java7FeatureTest.java"));
+		// create a CharStream that reads from file input stream
+		ANTLRInputStream input = new ANTLRInputStream(fis);
+
+		// create a lexer that feeds off of input CharStream
+		Java7Lexer lexer = new Java7Lexer(input);
+
+		for (Token t : lexer.getAllTokens()) {
+			System.out.println(lexer.getTokenNames()[t.getType()]);
+		}
+	}
+
+}

+ 45 - 0
jplag.frontend.java-1.7/src/test/java/jplag/java17/Bug58.java

@@ -0,0 +1,45 @@
+package jplag.java17;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/** See https://svn.ipd.kit.edu/trac/jplag/ticket/58 */
+public class Bug58 {
+	private static File srcTestResources;
+
+	@BeforeClass
+	public static void getPaths() {
+		srcTestResources = new File(System.getProperty("user.dir"), "src/test/resources");
+	}
+
+	@Test
+	public void parseEmptyFile() throws IOException {
+		parseWithActualParser(new File(srcTestResources, "EmptyFile.java"));
+	}
+
+	@Test
+	public void parseEmptyFileOnlyComments() throws IOException {
+		parseWithActualParser(new File(srcTestResources, "EmptyFileOnlyComments.java"));
+	}
+
+	@Test
+	public void parseEmptyFileOnlyOneComment() throws IOException {
+		parseWithActualParser(new File(srcTestResources, "EmptyFileOneComment.java"));
+	}
+
+	/**
+	 * Uses the actual parser component (not only the antlr parser but the jplag
+	 * frontend) to parse a file. Should throw no errors and exceptions :)
+	 * 
+	 * @param file
+	 *            file to parse
+	 */
+	private void parseWithActualParser(File file) {
+		Parser parser = new Parser();
+		parser.setProgram(new jplag.StrippedProgram());
+		parser.parse(null, new String[] { file.toString() });
+	}
+}

+ 295 - 0
jplag.frontend.java-1.7/src/test/java/jplag/java17/ParserTest.java

@@ -0,0 +1,295 @@
+package jplag.java17;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import jplag.StrippedProgram;
+import jplag.java17.grammar.Java7Lexer;
+import jplag.java17.grammar.Java7Parser;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class ParserTest {
+
+	private static File srcTestResources;
+
+	@BeforeClass
+	public static void getPaths() {
+		srcTestResources = new File(System.getProperty("user.dir"), "src/test/resources");
+	}
+
+	/**
+	 * Parses a (useless) class that uses all the fancy Java 7 syntax features
+	 * that I was able to find so far. The output is not compared to anything.
+	 * This test should only assure that we have covered all new features with
+	 * the grammar.
+	 * 
+	 * @throws IOException
+	 */
+	@Test
+	public void testTheNewFancyJava7Features() throws IOException {
+		File file = new File(srcTestResources, "Java7FeatureTest.java");
+		FileInputStream fis = new FileInputStream(file);
+		ANTLRInputStream input = new ANTLRInputStream(fis);
+		Java7Lexer lexer = new Java7Lexer(input);
+		CommonTokenStream tokens = new CommonTokenStream(lexer);
+		Java7Parser parser = new Java7Parser(tokens);
+		parser.compilationUnit();
+	}
+
+	@Ignore
+	public void j7Template() throws IOException {
+		File file = new File(srcTestResources, "J7StringSwitch.java");
+		String expected = ""// @formatter:off
+				+ "********\n"; // @formatter:on
+		String tokens = parseWithJ7Parser(file, false);
+		assertEquals(expected, tokens);
+	}
+
+	/**
+	 * added for ticket #58
+	 */
+	@Test
+	public void emptyFileOnlyComments() throws IOException {
+		compareWithParser15(new File(srcTestResources, "EmptyFileOnlyComments.java"));
+	}
+
+	@Test
+	public void emptyFile() throws IOException {
+		compareWithParser15(new File(srcTestResources, "EmptyFile.java"));
+	}
+
+	@Test
+	public void j7StringSwitchTest() throws IOException {
+		File file = new File(srcTestResources, "J7StringSwitch.java");
+		String expected ="" // @formatter:off
+				+"CLASS{  \n"
+				+"VOID    \n"
+				+"METHOD{ \n"
+				+"SWITCH{ \n"
+				+"CASE    \n"
+				+"BREAK   \n"
+				+"CASE    \n"
+				+"CASE    \n"
+				+"BREAK   \n"
+				+"CASE    \n"
+				+"BREAK   \n"
+				+"}SWITCH \n"
+				+"}METHOD \n"
+				+"}CLASS  \n"
+				+ "********\n"; // @formatter:on
+		String tokens = parseWithJ7Parser(file, false);
+		assertEquals(expected, tokens);
+	}
+
+	@Test
+	public void j7TryCatchTest() throws IOException {
+		File file = new File(srcTestResources, "J7TryCatch.java");
+		String expected ="IMPORT  \n" // @formatter:off
+				+"IMPORT  \n"
+				+"IMPORT  \n"
+				+"CLASS{  \n"
+				+"VOID    \n"
+				+"METHOD{ \n"
+				+"TRY{    \n"
+				+"CATCH{  \n"
+				+"}CATCH  \n"
+				+"FINALLY \n"
+				+"}METHOD \n"
+				+"VOID    \n"
+				+"METHOD{ \n"
+				+"TRY{    \n"
+				+"TRY_RES \n"
+				+"NEWCLASS\n"
+				+"APPLY   \n"
+				+"CATCH{  \n"
+				+"}CATCH  \n"
+				+"}METHOD \n"
+				+"VOID    \n"
+				+"METHOD{ \n"
+				+"TRY{    \n"
+				+"TRY_RES \n"
+				+"NEWCLASS\n"
+				+"TRY_RES \n"
+				+"NEWCLASS\n"
+				+"APPLY   \n"
+				+"CATCH{  \n"
+				+"}CATCH  \n"
+				+"}METHOD \n"
+				+"VOID    \n"
+				+"METHOD{ \n"
+				+"TRY{    \n"
+				+"APPLY   \n"
+				+"CATCH{  \n"
+				+"}CATCH  \n"
+				+"}METHOD \n"
+				+"VOID    \n"
+				+"METHOD{ \n"
+				+"TRY{    \n"
+				+"APPLY   \n"
+				+"CATCH{  \n"
+				+"}CATCH  \n"
+				+"CATCH{  \n"
+				+"}CATCH  \n"
+				+"}METHOD \n"
+				+"}CLASS  \n"
+				+"********\n";// @formatter:on
+
+		String tokens = parseWithJ7Parser(file, false);
+		assertEquals(expected, tokens);
+	}
+
+	@Test
+	public void compArray() throws IOException {
+		compareWithParser15(new File(srcTestResources, "ArrayTest.java"));
+	}
+
+	@Test
+	public void compSimpleClass() throws IOException {
+		compareWithParser15(new File(srcTestResources, "SimpleClass.java"));
+	}
+
+	@Test
+	public void compEnum() {
+		compareWithParser15(new File(srcTestResources, "EnumTest.java"));
+	}
+
+	@Test
+	public void compGeneric() {
+		compareWithParser15(new File(srcTestResources, "GenericPocket.java"));
+	}
+
+	@Test
+	public void compInnerClass() {
+		compareWithParser15(new File(srcTestResources, "InnerClass.java"));
+	}
+
+	@Test
+	public void compAnonymousClass() {
+		compareWithParser15(new File(srcTestResources, "AnonymousClass.java"));
+	}
+
+	@Test
+	public void compAnnotations_Usage() {
+		compareWithParser15(new File(srcTestResources, "AnnotationText.java"));
+	}
+
+	@Test
+	public void compAnnotations_PackageUsage() {
+		compareWithParser15(new File(srcTestResources, "package-info.java"));
+	}
+
+	@Test
+	public void compAnnotations_Definition() {
+		compareWithParser15(new File(srcTestResources, "OptimizeAnnotation.java"));
+	}
+
+	@Test
+	public void j7Generics() throws IOException {
+		File file = new File(srcTestResources, "J7Generics.java");
+		String expected = ""// @formatter:off
+				+ "CLASS{  \n"
+				+ "VOID    \n"
+				+ "METHOD{ \n"
+				+ "GENERIC \n"
+				+ "VARDEF  \n"
+				+ "ASSIGN  \n"
+				+ "GENERIC \n"
+				+ "NEWCLASS\n"
+				+ "}METHOD \n"
+				+ "}CLASS  \n"
+				+ "********\n"; // @formatter:on
+		String tokens = parseWithJ7Parser(file, false);
+		assertEquals(expected, tokens);
+	}
+
+	@Test
+	public void assureBackwardsCompatibility2() throws IOException {
+		compareWithParser15(new File(srcTestResources, "ExceptionTwo.java"));
+	}
+
+	@Test
+	public void assureBackwardsCompatibility3() throws IOException {
+		compareWithParser15(new File(srcTestResources, "ExceptionThree.java"));
+	}
+
+	@Test
+	public void assureBackwardsCompatibility4() throws IOException {
+		compareWithParser15(new File(srcTestResources, "Kalender.java"));
+	}
+
+	/**
+	 * Compare results (token sequence) with Java 1.5 parser (without method
+	 * separators ; if you know why they exist, PLEASE tell us or document at
+	 * https://svn.ipd.kit.edu/trac/jplag/wiki/Server/Frontends/Java-1.5)
+	 * 
+	 * @param javaFile
+	 * @throws IOException
+	 */
+	private void compareWithParser15(File javaFile) {
+		if (!javaFile.exists()) {
+			fail("Test not implemented - cannot find file >" + javaFile + "<");
+		}
+		String newTokens = parseWithJ7Parser(javaFile, true);
+		String oldTokens = parseWithJ5Parser(javaFile);
+		// compare token sequence?
+		Assert.assertEquals(oldTokens, newTokens);
+	}
+
+	private String parseWithJ5Parser(File javaFile) {
+
+		// parse with old parser
+		jplag.java15.Parser oldParser = new jplag.java15.Parser(false);
+		oldParser.setProgram(new StrippedProgram());
+		jplag.Structure oldStruct = oldParser.parse(javaFile.getParentFile(), new String[] { javaFile.getName() });
+
+		String oldTokens = buildTokenString(oldStruct, true);
+		return oldTokens;
+	}
+
+	/**
+	 * assumes that the token types have not changed from java 1.5 to Java 1.7
+	 * (meaning the integer values are the same but Java 1.7 has more than Java
+	 * 1.5)
+	 * 
+	 * @see jplag.java17.JavaToken
+	 * 
+	 * @param oldStruct
+	 * @param withDetails
+	 * @return
+	 */
+	private String buildTokenString(jplag.Structure oldStruct, boolean withDetails) {
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < oldStruct.size(); i++) {
+			sb.append(jplag.java17.JavaToken.type2string(oldStruct.tokens[i].type));
+			if (withDetails) {
+				sb.append(" L:" + oldStruct.tokens[i].getLine()  
+				+ " C:" + oldStruct.tokens[i].getLine()
+				+ " l:" + oldStruct.tokens[i].getLine());
+			}
+			sb.append("\n");
+		}
+
+		String oldTokens = sb.toString();
+		return oldTokens;
+	}
+
+	private String parseWithJ7Parser(File javaFile, boolean withDetails) {
+		// parse with new parser
+		jplag.java17.Parser newParser = new Parser();
+		newParser.setProgram(new StrippedProgram());
+		jplag.Structure newStruct = newParser.parse(javaFile.getParentFile(), new String[] { javaFile.getName() });
+
+		String newTokens = buildTokenString(newStruct, withDetails);
+		return newTokens;
+	}
+}

+ 22 - 0
jplag.frontend.java-1.7/src/test/resources/AnnotationText.java

@@ -0,0 +1,22 @@
+package foo;
+
+@SuppressWarnings("unused")
+public class AnnotationText {
+
+	@SuppressWarnings("unused")
+	public AnnotationText() {
+	}
+
+	@SuppressWarnings("unused")
+	public int foo = 5;
+
+	@SuppressWarnings("unused")
+	public void bla() {
+		@SuppressWarnings("unused")
+		int i = 9;
+	}
+
+	public void param(@SuppressWarnings("unused") int i) {
+	}
+
+}

+ 15 - 0
jplag.frontend.java-1.7/src/test/resources/AnonymousClass.java

@@ -0,0 +1,15 @@
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+
+public class AnonymousClass {
+	public static void main(String[] args) {
+		JButton b = new JButton();
+		b.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+			}
+		});
+	}
+
+}

+ 15 - 0
jplag.frontend.java-1.7/src/test/resources/ArrayTest.java

@@ -0,0 +1,15 @@
+public class ArrayTest {
+	public int[] intArray;
+	public int[][] intIntArray;
+	public Object[] objectArray;
+	public String[] stringArray;
+
+	public int[] intArray2 = new int[] { 1, 2 };
+	public int[][] intIntArray2 = new int[][] { { 1, 2 }, { 3, 4 } };
+	public Object[] objectArray2 = new Object[] { "1", "2" };
+	public String[] stringArray2 = new String[] { "a", "b" };
+
+	public int[] intArray3 = { 1, 2 };
+	public Object[] objectArray3 = { "ffo", "bas" };
+	public String[] stringArray3 = { "a", "b" };
+}

+ 0 - 0
jplag.frontend.java-1.7/src/test/resources/EmptyFile.java


+ 5 - 0
jplag.frontend.java-1.7/src/test/resources/EmptyFileOneComment.java

@@ -0,0 +1,5 @@
+/*
+public class EmptyFileOneComment {
+
+}
+*/

+ 2 - 0
jplag.frontend.java-1.7/src/test/resources/EmptyFileOnlyComments.java

@@ -0,0 +1,2 @@
+// stupid file
+// but that happens

+ 27 - 0
jplag.frontend.java-1.7/src/test/resources/EnumTest.java

@@ -0,0 +1,27 @@
+package de.jbb;
+ 
+public enum Land {
+ 
+  DEUTSCHLAND ("Berlin", 82169000, 357104.07),
+  RUSSLAND ("Moskau", 142400000, 17075400),
+  USA ("Washington D. C.", 304482526, 9826630),
+  FRANKREICH ("Paris", 64473140, 672352);
+ 
+  private int einwohner;
+  private final double flaeche;
+  private final String hauptstadt;
+ 
+  private Land(String hauptstadt, int einwohner, double flaeche) {
+    this.hauptstadt = hauptstadt;
+    this.einwohner = einwohner;
+    this.flaeche = flaeche;
+  }
+ 
+  public int getEinwohnerProQKM() {
+    return (int)(this.einwohner / this.flaeche);
+  }
+ 
+  public void setEinwohner(int einwohner) { this.einwohner = einwohner; }
+ 
+  public String getHauptstadt() { return this.hauptstadt; }
+}

+ 7 - 0
jplag.frontend.java-1.7/src/test/resources/ExceptionOne.java

@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class ExceptionOne extends Exception {
+	public void foo() {
+		System.out.println("foo");
+	}
+}

+ 5 - 0
jplag.frontend.java-1.7/src/test/resources/ExceptionThree.java

@@ -0,0 +1,5 @@
+public class ExceptionThree extends Exception {
+	static {
+		System.out.println("bla");
+	}
+}

+ 7 - 0
jplag.frontend.java-1.7/src/test/resources/ExceptionTwo.java

@@ -0,0 +1,7 @@
+
+public class ExceptionTwo extends Exception {
+	public static boolean foo() {
+		System.out.println("foo");
+		return false;
+	}
+}

+ 31 - 0
jplag.frontend.java-1.7/src/test/resources/GenericPocket.java

@@ -0,0 +1,31 @@
+
+public class GenericPocket<T> {
+	private T value;
+
+	public GenericPocket() {
+	}
+
+	public GenericPocket(T value) {
+		this.value = value;
+	}
+
+	public void set(T value) {
+		this.value = value;
+	}
+
+	public T get() {
+		return value;
+	}
+
+	public boolean isEmpty() {
+		return value != null;
+	}
+
+	public void empty() {
+		value = null;
+	}
+
+	public void main(String[] args) {
+		GenericPocket<String> pocket = new GenericPocket<String>();
+	}
+}

+ 24 - 0
jplag.frontend.java-1.7/src/test/resources/IfElsifElse.java

@@ -0,0 +1,24 @@
+public class IfElsifElse {
+	public static void main(String[] args) {
+		if (true) {
+		}
+
+		if (false) {
+		} else {
+		}
+
+		if (false) {
+		} else if (false) {
+		} else {
+		}
+
+		if (false) {
+		} else if (false) {
+		} else {
+		}
+		if (false) {
+		} else if (false) {
+		} else if (false) {
+		}
+	}
+}

+ 21 - 0
jplag.frontend.java-1.7/src/test/resources/InnerClass.java

@@ -0,0 +1,21 @@
+
+public class InnerClass {
+	public void foo() {
+	}
+
+	public class Bar {
+		public void bar() {
+		}
+	}
+	
+	public class Bar {
+		public class BBar {}
+		private class BFoo {}
+	}
+
+	private class BarFoo {
+		public void barFoo() {
+		}
+	}
+
+}

+ 5 - 0
jplag.frontend.java-1.7/src/test/resources/J7Generics.java

@@ -0,0 +1,5 @@
+public class J7Generics {
+	public static void main(String[] args) {
+		GenericPocket<String> pocketNew = new GenericPocket<>();
+	}
+}

+ 13 - 0
jplag.frontend.java-1.7/src/test/resources/J7StringSwitch.java

@@ -0,0 +1,13 @@
+public class J7StringSwitch {					// CLASS{
+	private void stringSwitch(String foo) {		// VOID, METHOD{
+		switch (foo) {							// SWITCH{
+		case "new":								// CASE
+			break;								// BREAK
+		case "exec":							// CASE
+		case "pend":							// CASE
+			break;								// BREAK
+		default:								// CASE
+			break;								// BREAK
+		}										// }SWITCH
+	}											// }METHOD
+}												// }CLASS

+ 43 - 0
jplag.frontend.java-1.7/src/test/resources/J7TryCatch.java

@@ -0,0 +1,43 @@
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+
+public class J7TryCatch {
+	
+	public void simpleTry() {
+		try {
+		} catch (Exception e) {
+		} finally {
+		}
+	}
+	
+	public void tryWithResource(FileOutputStream fos) {
+		try (DataOutputStream dos = new DataOutputStream(fos)) {
+			dos.writeUTF("Java 7 Block Buster");
+		} catch (IOException e) {
+		}
+	}
+	
+	public void tryWithResources() {
+		try (FileOutputStream fos = new FileOutputStream("movies.txt"); DataOutputStream dos = new DataOutputStream(fos)) {
+			dos.writeUTF("Java 7 Block Buster");
+		} catch (IOException e) {
+		}
+	}
+	
+	public void newMultiCatch() {
+		try {
+			methodThatThrowsThreeExceptions();
+		} catch (ExceptionOne | ExceptionTwo | ExceptionThree e) {
+		}
+	}
+
+	public void newMultiMultiCatch() {
+		try {
+			methodThatThrowsThreeExceptions();
+		} catch (ExceptionOne e) {
+		} catch (ExceptionTwo | ExceptionThree e) {
+		}
+	}
+}

+ 112 - 0
jplag.frontend.java-1.7/src/test/resources/Java7FeatureTest.java

@@ -0,0 +1,112 @@
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class Java7FeatureTest {
+
+	int thousand = 1_000;
+	int million = 1_000_000;
+
+	int foo = 1234_5678;
+	long l = 1_2_3_4__5_6_7_8L;
+	int binary = 0b0001_0010_0100_1000;
+
+	int mask = 0b1010_1010_1010;
+	long big = 9_223_783_036_967_937L;
+	long creditCardNumber = 1234_5678_9012_3456L;
+	long socialSecurityNumber = 999_99_9999L;
+	float pi = 3.14_15F;
+	long hexBytes = 0xFF_EC_DE_5E;
+	long hexWords = 0xCAFE_BFFE;
+
+	public static void diamondOperator() {
+		// old
+		Map<String, List<Object>> tradesOld = new TreeMap<String, List<Object>>();
+
+		// new
+		Map<String, List<Object>> trades = new TreeMap<>();
+	}
+
+	private void stringSwitch(String foo) {
+
+		// old
+		if (foo.equalsIgnoreCase("new")) {
+		} else if (foo.equalsIgnoreCase("exec")) {
+		} else if (foo.equalsIgnoreCase("pend")) {
+		}
+
+		// new
+		switch (foo) {
+		case "new":
+			break;
+		case "exec":
+			break;
+		case "pend":
+			break;
+		default:
+			break;
+		}
+	}
+
+	public void oldTry() {
+		FileOutputStream fos = null;
+		DataOutputStream dos = null;
+		try {
+			fos = new FileOutputStream("movies.txt");
+			dos = new DataOutputStream(fos);
+			dos.writeUTF("Java 7 Block Buster");
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				fos.close();
+				dos.close();
+			} catch (IOException e) {
+			}
+		}
+	}
+
+	public void newTry() {
+		try (FileOutputStream fos = new FileOutputStream("movies.txt"); DataOutputStream dos = new DataOutputStream(fos)) {
+			dos.writeUTF("Java 7 Block Buster");
+		} catch (IOException e) {
+		}
+	}
+
+	public void oldMultiCatch() {
+		try {
+			methodThatThrowsThreeExceptions();
+		} catch (ExceptionOne e) {
+		} catch (ExceptionTwo e) {
+		} catch (ExceptionThree e) {
+		}
+	}
+
+	public void newMultiCatch() {
+		try {
+			methodThatThrowsThreeExceptions();
+		} catch (ExceptionOne | ExceptionTwo | ExceptionThree e) {
+		}
+	}
+
+	public void newMultiMultiCatch() {
+		try {
+			methodThatThrowsThreeExceptions();
+		} catch (ExceptionOne e) {
+		} catch (ExceptionTwo | ExceptionThree e) {
+		}
+	}
+
+	private void methodThatThrowsThreeExceptions() throws ExceptionOne, ExceptionTwo, ExceptionThree {
+	}
+
+	public void foo(String bar) throws ExceptionOne, ExceptionTwo {
+		try {
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+}

+ 32 - 0
jplag.frontend.java-1.7/src/test/resources/Kalender.java

@@ -0,0 +1,32 @@
+package myCal;
+public class Kalender {
+	public int anzahlTage(Monat m, int jahr) {
+
+		if (jahr == 0) {
+			throw new IllegalArgumentException(
+					"Es gibt kein Jahr null in der traditionellen christlichen Zeitrechnung");
+		}
+
+		if (m.equals(Monat.Februar) && istSschaltjahr(jahr)) {
+			return 29;
+		} else if (m.equals(Monat.Februar)) {
+			return 28;
+		}
+
+		if (m.equals(Monat.Januar) || m.equals(Monat.Maerz)
+				|| m.equals(Monat.Mai) || m.equals(Monat.Juli)
+				|| m.equals(Monat.August) || m.equals(Monat.Oktober)
+				|| m.equals(Monat.Dezember)) {
+			return 31;
+		}
+
+		return 30;
+	}
+
+	private boolean istSschaltjahr(int jahr) {
+		if ((jahr % 4 == 0 && jahr % 100 != 0) || jahr % 400 == 0) {
+			return true;
+		}
+		return false;
+	}
+}

+ 31 - 0
jplag.frontend.java-1.7/src/test/resources/OptimizeAnnotation.java

@@ -0,0 +1,31 @@
+package foo;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Target;
+
+public @interface OptimizeAnnotation {
+	String value();
+
+	String assignedTo();
+
+	String assignedToDefault() default "";
+
+	String[] assignedToMany();
+
+	String[] assignedToNone();
+
+	int priority();
+
+	enum Priority {
+		LOW, NORM, HIGH;
+	}
+
+	Priority prio();
+
+}

+ 13 - 0
jplag.frontend.java-1.7/src/test/resources/SimpleClass.java

@@ -0,0 +1,13 @@
+import java.lang.*;
+import java.awt.*;
+
+public class SimpleClass {
+	public SimpleClass() {
+	}
+
+	public SimpleClass(int i) {
+	}
+
+	public SimpleClass(String a) {
+	}
+}

+ 2 - 0
jplag.frontend.java-1.7/src/test/resources/package-info.java

@@ -0,0 +1,2 @@
+@SuppressWarnings("unused")
+package foo;