/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.dom;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import junit.framework.Test;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.*;

@SuppressWarnings("rawtypes")
public class ASTConverterBugsTest extends ConverterTestSetup {

public void setUpSuite() throws Exception {
//	PROJECT_SETUP = true; // do not copy Converter* directories
	super.setUpSuite();
//	setUpJCLClasspathVariables("1.5");
	waitUntilIndexesReady();
}

public ASTConverterBugsTest(String name) {
	super(name);
}

public static Test suite() {
	return buildModelTestSuite(ASTConverterBugsTest.class);
}

protected void checkParameterAnnotations(String message, String expected, IMethodBinding methodBinding) {
	ITypeBinding[] parameterTypes = methodBinding.getParameterTypes();
	int size = parameterTypes == null ? 0 : parameterTypes.length;
	StringBuffer buffer = new StringBuffer();
	for (int i=0; i<size; i++) {
		buffer.append("----- param ");
		buffer.append(i+1);
		buffer.append("-----\n");
		IAnnotationBinding[] bindings= methodBinding.getParameterAnnotations(i);
		int length = bindings.length;
		for (int j=0; j<length; j++) {
			buffer.append(bindings[j].getKey());
			buffer.append('\n');
		}
	}
	assertEquals(message, expected, buffer.toString());
}

public ASTNode runConversion(ICompilationUnit unit, boolean resolveBindings) {
	return runConversion(this.testLevel, unit, resolveBindings);
}

public ASTNode runConversion(ICompilationUnit unit, int position, boolean resolveBindings) {
	return runConversion(this.testLevel, unit, position, resolveBindings);
}

public ASTNode runConversion(IClassFile classFile, int position, boolean resolveBindings) {
	return runConversion(this.testLevel, classFile, position, resolveBindings);
}

public ASTNode runConversion(char[] source, String unitName, IJavaProject project) {
	return runConversion(this.testLevel, source, unitName, project);
}

public ASTNode runConversion(char[] source, String unitName, IJavaProject project, boolean resolveBindings) {
	return runConversion(this.testLevel, source, unitName, project, resolveBindings);
}

public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map<String, String> options, boolean resolveBindings) {
	return runConversion(this.testLevel, source, unitName, project, options, resolveBindings);
}
public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map<String, String> options) {
	return runConversion(this.testLevel, source, unitName, project, options);
}

public ASTNode runConversion(
		ICompilationUnit unit,
		boolean resolveBindings,
		boolean statementsRecovery,
		boolean bindingsRecovery) {
	ASTParser parser = createASTParser();
	parser.setSource(unit);
	parser.setResolveBindings(resolveBindings);
	parser.setStatementsRecovery(statementsRecovery);
	parser.setBindingsRecovery(bindingsRecovery);
	parser.setWorkingCopyOwner(this.wcOwner);
	return parser.createAST(null);
}

protected void resolveASTs(ICompilationUnit[] cus, String[] bindingKeys, ASTRequestor requestor, IJavaProject project, WorkingCopyOwner owner) {
	ASTParser parser = createASTParser();
	parser.setResolveBindings(true);
	parser.setProject(project);
	parser.setWorkingCopyOwner(owner);
	parser.createASTs(cus, bindingKeys,  requestor, null);
}

/**
 * @bug 186410: [dom] StackOverflowError due to endless superclass bindings hierarchy
 * @test Ensures that the superclass of "java.lang.Object" class is null even when it's a recovered binding
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=186410"
 */
public void testBug186410() throws CoreException, IOException {
	try {
		createJavaProject("P", new String[] { "" }, new String[0], "");
			createFile("P/A.java",
				"public class A {\n" +
				"	void method(){}\n" +
				"}"
			);
		ICompilationUnit cuA = getCompilationUnit("P/A.java");
		CompilationUnit unitA = (CompilationUnit) runConversion(cuA, true, false, true);
		AbstractTypeDeclaration typeA = (AbstractTypeDeclaration) unitA.types().get(0);
		ITypeBinding objectType = typeA.resolveBinding().getSuperclass();
		assertEquals("Unexpected superclass", "Object", objectType.getName());
		ITypeBinding objectSuperclass = objectType.getSuperclass();
		assertNull("java.lang.Object should  not have any superclass", objectSuperclass);
	} finally {
		deleteProject("P");
	}
}

public void testBug186410b() throws CoreException, IOException {
	try {
		createJavaProject("P", new String[] { "" }, new String[0], "");
			createFile("P/A.java",
				"public class A {\n" +
				"	Object field;\n" +
				"}"
			);
		ICompilationUnit cuA = getCompilationUnit("P/A.java");
		CompilationUnit unitA = (CompilationUnit) runConversion(cuA, true, false, true);
		AbstractTypeDeclaration type = (AbstractTypeDeclaration) unitA.types().get(0);
		FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(0);
		Type fieldType = field.getType();
		ITypeBinding typeBinding = fieldType.resolveBinding();
		ITypeBinding objectType = typeBinding.createArrayType(2).getElementType();
		assertEquals("Unexpected superclass", "Object", objectType.getName());
		ITypeBinding objectSuperclass = objectType.getSuperclass();
		assertNull("java.lang.Object should  not have any superclass", objectSuperclass);
	} finally {
		deleteProject("P");
	}
}

/**
 * @bug 209150: [dom] Recovered type binding for "java.lang.Object" information are not complete
 * @test Ensures that getPackage() and getQualifiedName() works properly for the "java.lang.Object" recovered binding
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=209150"
 */
public void testBug209150a() throws CoreException, IOException {
	try {
		createJavaProject("P", new String[] { "" }, new String[0], "");
			createFile("P/A.java",
				"public class A {\n" +
				"	void method(){}\n" +
				"}"
			);
		ICompilationUnit cuA = getCompilationUnit("P/A.java");
		CompilationUnit unitA = (CompilationUnit) runConversion(cuA, true, false, true);
		AbstractTypeDeclaration typeA = (AbstractTypeDeclaration) unitA.types().get(0);
		ITypeBinding objectType = typeA.resolveBinding().getSuperclass();
		assertTrue("'java.lang.Object' should be recovered!", objectType.isRecovered());
		assertEquals("Unexpected package for recovered 'java.lang.Object'", "java.lang", objectType.getPackage().getName());
		assertEquals("Unexpected qualified name for recovered 'java.lang.Object'",
		    "java.lang.Object",
		    objectType.getQualifiedName());
	} finally {
		deleteProject("P");
	}
}

public void testBug209150b() throws CoreException, IOException {
	try {
		createJavaProject("P", new String[] { "" }, new String[0], "");
			createFile("P/A.java",
				"public class A {\n" +
				"	Object field;\n" +
				"}"
			);
		ICompilationUnit cuA = getCompilationUnit("P/A.java");
		CompilationUnit unitA = (CompilationUnit) runConversion(cuA, true, false, true);
		AbstractTypeDeclaration type = (AbstractTypeDeclaration) unitA.types().get(0);
		FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(0);
		Type fieldType = field.getType();
		ITypeBinding typeBinding = fieldType.resolveBinding();
		ITypeBinding arrayType = typeBinding.createArrayType(2);
		assertTrue("'java.lang.Object' should be recovered!", arrayType.isRecovered());
		assertNull("Unexpected package for recovered 'array of java.lang.Object'", arrayType.getPackage());
		assertEquals("Unexpected qualified name for recovered 'java.lang.Object'",
		    "java.lang.Object[][]",
		    arrayType.getQualifiedName());
	} finally {
		deleteProject("P");
	}
}

public void testBug209150c() throws CoreException, IOException {
	try {
		createJavaProject("P", new String[] { "" }, new String[0], "");
			createFile("P/A.java",
				"public class A {\n" +
				"	Object[] array;\n" +
				"}"
			);
		ICompilationUnit cuA = getCompilationUnit("P/A.java");
		CompilationUnit unitA = (CompilationUnit) runConversion(cuA, true, false, true);
		AbstractTypeDeclaration type = (AbstractTypeDeclaration) unitA.types().get(0);
		FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(0);
		Type fieldType = field.getType();
		ITypeBinding arrayType = fieldType.resolveBinding();
		assertTrue("'java.lang.Object' should be recovered!", arrayType.isRecovered());
		assertNull("Unexpected package for recovered 'array of java.lang.Object'", arrayType.getPackage());
		assertEquals("Unexpected qualified name for recovered 'java.lang.Object'",
		    "java.lang.Object[]",
		    arrayType.getQualifiedName());
	} finally {
		deleteProject("P");
	}
}

/**
 * @bug 212100: [dom] Can't create binding to inner class
 * @test Verify that the binding is well created for an inner class
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=212100"
 */
public void testBug212100a() throws JavaModelException {
	this.workingCopies = new ICompilationUnit[1];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
	String contents =
		"public class X {\n" +
		"	public class Y {\n" +
		"      void foo() {}\n" +
		"   }\n" +
		"}";
	this.workingCopies[0].getBuffer().setContents(contents);
	this.workingCopies[0].save(null, true);
	final IBinding[] bindings = new IBinding[4];
	final String key = "Ljava/lang/Object;"; // this will make the test fail
//	final String key = "LX;"; // this would make the test pass

	resolveASTs(this.workingCopies,
			new String[] { key },
			new ASTRequestor() {
				public void acceptBinding(String bindingKey, IBinding binding) {
					if (key.equals(bindingKey)) {
						bindings[0] = binding;
						IBinding[] temp = createBindings(new String[] {"LX;", "LX$Y;", "[LX$Y;"});
						for (int i = 0; i < temp.length; ++i) {
							bindings[i + 1] = temp[i];
						}
					}
				}
			},
			getJavaProject("Converter15"),
			null);
	assertNotNull("Binding for java.lang.Object should not be null", bindings[0]);
	assertNotNull("Binding for X should not be null", bindings[1]);
	assertNotNull("Binding for X.Y should not be null", bindings[2]);
	assertNotNull("Binding for X.Y[] should not be null", bindings[3]);
}
public void testBug212100b() throws JavaModelException {
	this.workingCopies = new ICompilationUnit[2];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
	String contents =
		"public class X {\n" +
		"	public class Y {\n" +
		"      void foo() {}\n" +
		"   }\n" +
		"}";
	this.workingCopies[0].getBuffer().setContents(contents);
	this.workingCopies[0].save(null, true);

	this.workingCopies[1] = getWorkingCopy("/Converter15/src/Z.java", true/*resolve*/);
	String contentsZ =
		"public class Z {\n" +
		"	public class W {\n" +
		"      void bar() {}\n" +
		"   }\n" +
		"}";
	this.workingCopies[1].getBuffer().setContents(contentsZ);
	this.workingCopies[1].save(null, true);

	final String keyX = "LX;";
	final String keyXY = "LX$Y;";
	final String keyZ = "LZ;";
	final String keyZW = "LZ$W;";

	resolveASTs(this.workingCopies,
			new String[] { keyX, keyZ },
			new ASTRequestor() {
				public void acceptBinding(String bindingKey, IBinding binding) {
					IBinding[] bindings = createBindings(new String[] {
							keyX, keyXY, keyZ, keyZW
					});
					assertNotNull("When accepting " + bindingKey + ", Binding for X should not be null", bindings[0]);
					assertNotNull("When accepting " + bindingKey + ", Binding for X.Y should not be null", bindings[1]);
					assertNotNull("When accepting " + bindingKey + ", Binding for Z should not be null", bindings[2]);
					assertNotNull("When accepting " + bindingKey + ", Binding for Z.W should not be null", bindings[3]);
				}
			},
			getJavaProject("Converter15"),
			null);
}

/**
 * @bug 212834: [dom] IMethodBinding.getParameterAnnotations does not return annotations
 * @test Ensures that the method binding get the parameter annotations even on method invocation
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=212834"
 */
public void testBug212834() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[3];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Baz.java",
		"public @interface Baz {\n" +
		"}\n"
	);
	this.workingCopies[1] = getWorkingCopy("/Converter15/src/C.java",
		"public class C {\n" +
		"public C(D d) {\n" +
		"	foo(5);\n" +
		"	d.bar(7);\n" +
		"}\n" +
		"@Baz\n" +
		"public void foo(@Baz int x) { }\n" +
		"\n" +
		"}"
	);
	this.workingCopies[2] = getWorkingCopy("/Converter15/src/D.java",
		"public class D {\n" +
		"@Baz\n" +
		"public void bar(@Baz int y) { }\n" +
		"\n" +
		"}"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[1], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	MethodInvocation methodInvocation = (MethodInvocation) ((ExpressionStatement) methodDeclaration.getBody().statements().get(1)).getExpression();
	IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
	assertBindingsEqual(methodInvocation+" has invalid parameter annotations!",
		"@LBaz;",
		methodBinding.getParameterAnnotations(0)
	);
}

/**
 * @bug 212857: [dom] AST has wrong source range after parameter with array-valued annotation
 * @test Ensures that the method body has the right source range even when there's braces in its header
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=212857"
 */
public void testBug212857() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	String source = "package xy;\n" +
		"public class C {\n" +
		"	void m(@SuppressWarnings({\"unused\", \"bla\"}) int arg) {\n" +
		"		int local;\n" +
		"	}\n" +
		"}\n";
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/xy/C.java", source);
	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkSourceRange(methodDeclaration.getBody(),
		"{\n" +
		"		int local;\n" +
		"	}",
		source
	);
}
public void testBug212857a() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	String source = "package xy;\n" +
	"public class C {\n" +
	"	@SuppressWarnings({\"unused\", \"bla\"}) void m() {\n" +
	"		int local;\n" +
	"	}\n" +
	"}\n";
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/xy/C.java", source);
	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkSourceRange(methodDeclaration.getBody(),
		"{\n" +
		"		int local;\n" +
		"	}",
		source
	);
}
// tests with recovery
public void testBug212857b() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	String source = "package test;\n" +
	"public class X {\n" +
	"	void m() \n" +
	"		if (arg == 0) {}\n" +
	"	}\n" +
	"}\n";
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/test/X.java", source);
	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkSourceRange(methodDeclaration.getBody(),
		" \n" +
		"		if (arg == 0) {}\n" +
		"	}",
		source
	);
}
public void testBug212857c() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	String source = "package test;\n" +
	"public class X {\n" +
	"	void m() \n" +
	"	}\n" +
	"}\n";
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/test/X.java", source);
	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkSourceRange(methodDeclaration.getBody(),
		" \n" +
		"	}",
		source
	);
}
public void testBug212857d() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	String source = "package test;\n" +
	"public class X {\n" +
	"	void m(String str) \n" +
	"		if (arg == 0) {}\n" +
	"	}\n" +
	"}\n";
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/test/X.java", source);
	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkSourceRange(methodDeclaration.getBody(),
		" \n" +
		"		if (arg == 0) {}\n" +
		"	}",
		source
	);
}
public void testBug212857e() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	String source = "package test;\n" +
	"public class X {\n" +
	"	void m(Object obj, int x) \n" +
	"	}\n" +
	"}\n";
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/test/X.java", source);
	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkSourceRange(methodDeclaration.getBody(),
		" \n" +
		"	}",
		source
	);
}

/**
 * @bug 213509: [dom] IMethodBinding.getParameterAnnotations returns annotations for wrong parameter
 * @test Ensures that all parameter annotations of a the method binding are correctly  returned
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=213509"
 */
public void testBug213509() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
		"public class Test {\n" +
		"	void m(@Foo @Bar @Annot String str, @Bar @Foo Object obj, @Annot int x) {}\n" +
		"}\n" +
		"@interface Foo {}\n" +
		"@interface Bar {}\n" +
		"@interface Annot {}\n"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkParameterAnnotations(methodDeclaration+" has invalid parameter annotations!",
		"----- param 1-----\n" +
		"@LTest~Foo;\n" +
		"@LTest~Bar;\n" +
		"@LTest~Annot;\n" +
		"----- param 2-----\n" +
		"@LTest~Bar;\n" +
		"@LTest~Foo;\n" +
		"----- param 3-----\n" +
		"@LTest~Annot;\n",
		methodDeclaration.resolveBinding()
	);
}
public void testBug213509_invocation() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[2];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
		"public class Test {\n" +
		"	void m(@Foo @Bar @Annot String str, @Bar @Foo Object obj, @Annot int x) {}\n" +
		"}\n" +
		"@interface Foo {}\n" +
		"@interface Bar {}\n" +
		"@interface Annot {}\n"
	);
	this.workingCopies[1] = getWorkingCopy("/Converter15/src/X.java",
		"public class X {\n" +
		"public X(Test test) {\n" +
		"	test.m(\"\", null, 7);\n" +
		"}\n" +
		"}"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[1], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	MethodInvocation methodInvocation = (MethodInvocation) ((ExpressionStatement) methodDeclaration.getBody().statements().get(0)).getExpression();
	checkParameterAnnotations(methodInvocation+" has invalid parameter annotations!",
		"----- param 1-----\n" +
		"@LTest~Foo;\n" +
		"@LTest~Bar;\n" +
		"@LTest~Annot;\n" +
		"----- param 2-----\n" +
		"@LTest~Bar;\n" +
		"@LTest~Foo;\n" +
		"----- param 3-----\n" +
		"@LTest~Annot;\n",
		methodInvocation.resolveMethodBinding()
	);
}

/**
 * @bug 214002: [dom] NPE in MethodBinding.getParameterAnnotations()
 * @test Ensures that no NPE occurs when not all method parameters have annotations
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=214002"
 */
public void testBug214002() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
		"public class Test {\n" +
		"	void m(String str, @Bar @Foo Object obj, @Annot int x) {}\n" +
		"}\n" +
		"@interface Foo {}\n" +
		"@interface Bar {}\n" +
		"@interface Annot {}\n"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkParameterAnnotations(methodDeclaration+" has invalid parameter annotations!",
		"----- param 1-----\n" +
		"----- param 2-----\n" +
		"@LTest~Bar;\n" +
		"@LTest~Foo;\n" +
		"----- param 3-----\n" +
		"@LTest~Annot;\n",
		methodDeclaration.resolveBinding()
	);
}
public void testBug214002b() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
		"public class Test {\n" +
		"	void m(@Annot String str, Object obj, @Bar @Foo int x) {}\n" +
		"}\n" +
		"@interface Foo {}\n" +
		"@interface Bar {}\n" +
		"@interface Annot {}\n"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkParameterAnnotations(methodDeclaration+" has invalid parameter annotations!",
		"----- param 1-----\n" +
		"@LTest~Annot;\n" +
		"----- param 2-----\n" +
		"----- param 3-----\n" +
		"@LTest~Bar;\n" +
		"@LTest~Foo;\n",
		methodDeclaration.resolveBinding()
	);
}
	/**
	 * @bug 212434: [dom] IllegalArgumentException during AST Creation
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=212434"
	 */
	public void testBug212434a() throws CoreException, IOException {
		try {
			createJavaProject("P", new String[] {""}, new String[0], "");
			createFile("P/A.java",
					"public class A {\n"+
					"\n"+
					"	public void foo() {\n"+
					"		new Object() { \n"+
					"			public void bar() { \n"+
					"				if (true) {\n"+
					"					final\n"+
					"				}\n"+
					"			}\n"+
					"\n"+
					"		};  \n"+
					"\n"+
					"		if (false) {\n"+
					"			Object var = new Object() {\n"+
					"				void toto() {\n"+
					"					\n"+
					"				}\n"+
					"			};\n"+
					"		}\n"+
					"	}\n"+
					"}"
			);
			ICompilationUnit cuA = getCompilationUnit("P/A.java");
			try {
				runConversion(getJLS3(), cuA, true, true, true);
			} catch(IllegalArgumentException e) {
				assertTrue("Unexpected IllegalArgumentException", false);
			}
		} finally {
			deleteProject("P");
		}
	}
/**
 * @bug 214647: [dom] NPE in MethodBinding.getParameterAnnotations(..)
 * @test Ensures that no NPE occurs when parameters have no annotation
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=214647"
 */
public void testBug214647() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
		"public class Test {\n" +
		"	void m(String str) {}\n" +
		"}\n"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkParameterAnnotations(methodDeclaration+" has invalid parameter annotations!",
		"----- param 1-----\n",
		methodDeclaration.resolveBinding()
	);
}
public void testBug214647b() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[1];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
		"public class Test {\n" +
		"	void m(String str, Object o, int x) {}\n" +
		"}\n"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[0], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	checkParameterAnnotations(methodDeclaration+" has invalid parameter annotations!",
		"----- param 1-----\n" +
		"----- param 2-----\n" +
		"----- param 3-----\n",
		methodDeclaration.resolveBinding()
	);
}

/**
 * @bug 215759: DOM AST regression tests should be improved
 * @test these tests test the new DOM AST test framework
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=215759"
 */
public void testBug215759a() throws CoreException {
	this.workingCopies = new ICompilationUnit[1];

	this.workingCopies[0] = getWorkingCopy(
			"/Converter/src/p/Y.java",
			"package p;\n" +
			"public class  Y {\n" +
			"}",
			true/*resolve*/);

	ASTResult result = this.buildMarkedAST(
			"/Converter/src/p/X.java",
			"package p;\n" +
			"public class X extends Y {\n" +
			"	/**\n" +
			"	 * blabla1\n" +
			"	 * @param [*1*]string[*1*] blabla2\n" +
			"	 */\n" +
			"	protected [*2*]String[*2*] foo(String string) {\n" +
			"		return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" +
			"	}\n" +
			"	/*comment*/[*4*]protected void bar() {}[*4*]\n" +
			"	#\n" +
			"}");

	assertASTResult(
			"===== AST =====\n" +
			"package p;\n" +
			"public class X extends Y {\n" +
			"  /** \n" +
			" * blabla1\n" +
			" * @param [*1*]string[*1*] blabla2\n" +
			" */\n" +
			"  protected [*2*]String[*2*] foo(  String string){\n" +
			"    return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" +
			"  }\n" +
			"  [*4*]protected void bar(){\n" +
			"  }[*4*]\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:SIMPLE_NAME,[66,6],,,[VARIABLE,Lp/X;.foo(Ljava/lang/String;)Ljava/lang/String;#string#0#0,]\n" +
			"2:SIMPLE_TYPE,[97,6],,,[TYPE,Ljava/lang/String;,]\n" +
			"2:SIMPLE_NAME,[97,6],,,[TYPE,Ljava/lang/String;,]\n" +
			"3:PARENTHESIZED_EXPRESSION,[134,18],,,[N/A]\n" +
			"4:METHOD_DECLARATION,[176,23],,,[METHOD,Lp/X;.bar()V,]\n" +
			"===== Problems =====\n" +
			"1. ERROR in /Converter/src/p/X.java (at line 11)\n" +
			"	#\n" +
			"	^\n" +
			"Syntax error on token \"Invalid Character\", delete this token\n",
			result);
}

public void testBug215759b() throws CoreException {
	this.workingCopies = new ICompilationUnit[1];

	this.workingCopies[0] = getWorkingCopy(
			"/Converter/src/p/Y.java",
			"package p;\n" +
			"public class  Y {\n" +
			"}",
			true/*resolve*/);

	ASTResult result = this.buildMarkedAST(
			"/Converter/src/p/X.java",
			"package p;\n" +
			"public class X extends Y {\n" +
			"	/**\n" +
			"	 * blabla1\n" +
			"	 * @param [*1*]string[*1*] blabla2\n" +
			"	 */\n" +
			"	protected [*2*]String[*2*] foo(String string) {\n" +
			"		return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" +
			"	}\n" +
			"	/*comment*/[*4*]protected void bar() {}[*4*]\n" +
			"	[*5*]/**@deprecated*/protected void bar2() {}[*5*]\n" +
			"}");

	assertASTResult(
			"===== AST =====\n" +
			"package p;\n" +
			"public class X extends Y {\n" +
			"  /** \n" +
			" * blabla1\n" +
			" * @param [*1*]string[*1*] blabla2\n" +
			" */\n" +
			"  protected [*2*]String[*2*] foo(  String string){\n" +
			"    return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" +
			"  }\n" +
			"  [*4*]protected void bar(){\n" +
			"  }[*4*]\n" +
			"  [*5*]/** \n" +
			" * @deprecated\n" +
			" */\n" +
			"  protected void bar2(){\n" +
			"  }[*5*]\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:SIMPLE_NAME,[66,6],,,[VARIABLE,Lp/X;.foo(Ljava/lang/String;)Ljava/lang/String;#string#0#0,]\n" +
			"2:SIMPLE_TYPE,[97,6],,,[TYPE,Ljava/lang/String;,]\n" +
			"2:SIMPLE_NAME,[97,6],,,[TYPE,Ljava/lang/String;,]\n" +
			"3:PARENTHESIZED_EXPRESSION,[134,18],,,[N/A]\n" +
			"4:METHOD_DECLARATION,[176,23],[165,34],,[METHOD,Lp/X;.bar()V,]\n" +
			"5:METHOD_DECLARATION,[201,40],,,[METHOD,Lp/X;.bar2()V,DEPRECATED]\n" +
			"===== Problems =====\n" +
			"No problem",
			result);
}
/**
 * @bug 218824: [DOM/AST] incorrect code leads to IllegalArgumentException during AST creation
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=218824"
 */
public void testBug218824a() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void takeParam(int i) {\n"+
			"                // do something\n"+
			"        }\n"+
			"\n"+
			"        void test() {\n"+
			"                char c = 'a';\n"+
			"                   public void takeParam(int i) {\n"+
			"                             // do something\n"+
			"                           }\n"+
			"\n"+
			"                           void test() {\n"+
			"                             char c = 'a';\n"+
			"                            takeParam((int) c);\n"+
			"                           }[*1*]takeParam([*1*](int) c);\n"+
			"        }\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" +
			"package a;\n" +
			"public class X {\n" +
			"  public void takeParam(  int i){\n" +
			"  }\n" +
			"  void test(){\n" +
			"    char c=\'a\';\n" +
			"    public void takeParam;\n" +
			"    int i;\n" +
			"    new test(){\n" +
			"      char c=\'a\';\n" +
			"{\n" +
			"        takeParam((int)c);\n" +
			"      }\n" +
			"      [*1*]void takeParam(){\n" +
			"      }[*1*]\n" +
			"    }\n" +
			";\n" +
			"  }\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:METHOD_DECLARATION,[447,10],,MALFORMED,[null]\n" +
			"===== Problems =====\n" +
			"1. ERROR in /Converter15/src/a/X.java (at line 9)\n" +
			"	public void takeParam(int i) {\n" +
			"	            ^^^^^^^^^\n" +
			"void is an invalid type for the variable takeParam\n" +
			"2. ERROR in /Converter15/src/a/X.java (at line 9)\n" +
			"	public void takeParam(int i) {\n" +
			"	                     ^\n" +
			"Syntax error on token \"(\", ; expected\n" +
			"3. ERROR in /Converter15/src/a/X.java (at line 9)\n" +
			"	public void takeParam(int i) {\n" +
			"	                           ^\n" +
			"Syntax error on token \")\", ; expected\n" +
			"4. ERROR in /Converter15/src/a/X.java (at line 13)\n" +
			"	void test() {\n" +
			"	^^^^\n" +
			"Syntax error on token \"void\", new expected\n" +
			"5. ERROR in /Converter15/src/a/X.java (at line 13)\n" +
			"	void test() {\n" +
			"	     ^^^^\n" +
			"test cannot be resolved to a type\n" +
			"6. ERROR in /Converter15/src/a/X.java (at line 14)\n" +
			"	char c = \'a\';\n" +
			"	            ^\n" +
			"Syntax error on token \";\", { expected after this token\n" +
			"7. ERROR in /Converter15/src/a/X.java (at line 16)\n" +
			"	}takeParam((int) c);\n" +
			"	^\n" +
			"Syntax error, insert \"}\" to complete ClassBody\n" +
			"8. ERROR in /Converter15/src/a/X.java (at line 16)\n" +
			"	}takeParam((int) c);\n" +
			"	^\n" +
			"Syntax error, insert \";\" to complete Statement\n" + 
			"9. ERROR in /Converter15/src/a/X.java (at line 16)\n" + 
			"	}takeParam((int) c);\n" + 
			"	 ^^^^^^^^^^\n" + 
			"Return type for the method is missing\n",
			result);
}
/**
 * @bug 215137: [AST]Some malformed MethodDeclaration, their Block is null, but they actually have Block
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=215137"
 */
public void testBug215137a() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void foo() [*1*]{\n"+
			"                System.out.println(\"hello);\n"+
			"        }[*1*]\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" +
			"package a;\n" +
			"public class X {\n" +
			"  public void foo()[*1*]{\n" +
			"  }[*1*]\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:BLOCK,[54,55],,RECOVERED,[N/A]\n" +
			"===== Problems =====\n" +
			"1. ERROR in /Converter15/src/a/X.java (at line 4)\n" +
			"	System.out.println(\"hello);\n" +
			"	                   ^^^^^^^^\n" +
			"String literal is not properly closed by a double-quote\n",
			result);
}
public void testBug215137b() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void foo() [*1*]{\n"+
			"                System.out.println('a);\n"+
			"        }[*1*]\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" +
			"package a;\n" +
			"public class X {\n" +
			"  public void foo()[*1*]{\n" +
			"  }[*1*]\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:BLOCK,[54,51],,RECOVERED,[N/A]\n" +
			"===== Problems =====\n" +
			"1. ERROR in /Converter15/src/a/X.java (at line 4)\n" +
			"	System.out.println(\'a);\n" +
			"	                   ^^\n" +
			"Invalid character constant\n",
			result);
}
public void testBug215137c() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void foo() [*1*]{\n"+
			"                System.out.println(''a);\n"+
			"        }[*1*]\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" +
			"package a;\n" +
			"public class X {\n" +
			"  public void foo()[*1*]{\n" +
			"  }[*1*]\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:BLOCK,[54,52],,RECOVERED,[N/A]\n" +
			"===== Problems =====\n" +
			"1. ERROR in /Converter15/src/a/X.java (at line 4)\n" +
			"	System.out.println(\'\'a);\n" +
			"	                   ^^\n" +
			"Invalid character constant\n",
			result);
}
public void testBug215137d() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void foo() [*1*]{\n"+
			"                7eSystem.out.println();\n"+
			"        }[*1*]\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" +
			"package a;\n" +
			"public class X {\n" +
			"  public void foo()[*1*]{\n" +
			"  }[*1*]\n" +
			"}\n" +
			"\n" +
			"===== Details =====\n" +
			"1:BLOCK,[54,51],,RECOVERED,[N/A]\n" +
			"===== Problems =====\n" +
			"1. ERROR in /Converter15/src/a/X.java (at line 4)\n" +
			"	7eSystem.out.println();\n" +
			"	^^^\n" +
			"Invalid float literal number\n",
			result);
}
/**
 * @bug 223838: [dom] AnnotationBinding.isRecovered() always return false
 * @test That the annotation binding is well flagged as recovered when the annotation is an unknown type
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=223838"
 */
public void testBug223838() throws JavaModelException {
	String contents =
		"package b223838;\n" +
		"@Deprecated\n" +
		"@Invalid\n" +
		"public class Test {\n" +
		"}\n";
	ICompilationUnit workingCopy = getWorkingCopy(
			"/Converter15/src/b223838/Test.java",
			contents,
			true/*resolve*/
		);
	ASTNode node = buildAST(contents, workingCopy, false, false, true);
	CompilationUnit unit = (CompilationUnit) node;
	List types = unit.types();
	TypeDeclaration type = (TypeDeclaration) types.get(0);
	ITypeBinding typeBinding = type.resolveBinding();
	IAnnotationBinding[] annotations = typeBinding.getAnnotations();
	assertTrue("Expected recovered annotation binding!", annotations[1].isRecovered());
}
/**
 * @bug 223838: [dom] AnnotationBinding.isRecovered() always return false
 * @test That the annotation binding is not reported when the recovery is off
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=223838"
 */
public void testBug223838a() throws JavaModelException {
	String contents =
		"package b223838;\n" +
		"@Deprecated\n" +
		"@Invalid\n" +
		"public class Test {\n" +
		"}\n";
	ICompilationUnit workingCopy = getWorkingCopy(
			"/Converter15/src/b223838/Test.java",
			contents,
			true/*resolve*/
		);
	ASTNode node = buildAST(contents, workingCopy, false, false, false);
	CompilationUnit unit = (CompilationUnit) node;
	List types = unit.types();
	TypeDeclaration type = (TypeDeclaration) types.get(0);
	ITypeBinding typeBinding = type.resolveBinding();
	IAnnotationBinding[] annotations = typeBinding.getAnnotations();
	assertEquals("Got more than one annotation binding", 1, annotations.length);
}

/**
 * @bug 226357: NPE in MethodBinding.getParameterAnnotations() if some, but not all parameters are annotated
 * @test Verify that NPE does no longer occur on the given test case
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=226357"
 */
public void testBug226357() throws CoreException, IOException {
	this.workingCopies = new ICompilationUnit[2];
	this.workingCopies[0] = getWorkingCopy("/Converter15/src/ParameterSubsetAnnotated.java",
		"public class ParameterSubsetAnnotated {\n" +
		"        public @interface NonZero { }\n" +
		"        public static int safeDiv(int a, @NonZero int b) {\n" +
		"                return a / b;\n" +
		"        }\n" +
		"}"
	);
	this.workingCopies[1] = getWorkingCopy("/Converter15/src/ParameterSubsetClient.java",
		"public class ParameterSubsetClient {\n" +
		"\n" +
		"        public void client() {\n" +
		"                ParameterSubsetAnnotated.safeDiv(5, 0);\n" +
		"        }\n" +
		"\n" +
		"}\n"
	);

	CompilationUnit unit = (CompilationUnit) runConversion(this.workingCopies[1], true/*bindings*/, false/*no statement recovery*/, true/*bindings recovery*/);
	MethodDeclaration methodDeclaration = (MethodDeclaration) getASTNode(unit, 0, 0);
	ExpressionStatement statement = (ExpressionStatement) methodDeclaration.getBody().statements().get(0);
	MethodInvocation methodInvocation = (MethodInvocation) statement.getExpression();
	checkParameterAnnotations(methodDeclaration+" has invalid parameter annotations!",
		"----- param 1-----\n" +
		"----- param 2-----\n" +
		"@LParameterSubsetAnnotated$NonZero;\n",
		methodInvocation.resolveMethodBinding()
	);
}

public void testBug274898a() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void foo() {\n"+
			"                [*1*]Object o = new [*1*][*2*]new Object(){}[*2*]; \n"+
			"        }\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"  public void foo(){\n" + 
			"    [*1*]Object o;[*1*]\n" + 
			"    [*2*]new Object(){\n" + 
			"    }\n" + 
			";[*2*]\n" + 
			"  }\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:VARIABLE_DECLARATION_STATEMENT,[72,15],,,[N/A]\n" + 
			"2:EXPRESSION_STATEMENT,[87,14],,,[N/A]\n" + 
			"2:CLASS_INSTANCE_CREATION,[87,14],,RECOVERED,[N/A]\n" + 
			"===== Problems =====\n" + 
			"1. ERROR in /Converter15/src/a/X.java (at line 4)\n" + 
			"	Object o = new new Object(){}; \n" + 
			"	               ^^^\n" + 
			"Syntax error on token \"new\", delete this token\n",
			result);
}
public void testBug274898b() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n"+
			"        public void foo() {\n"+
			"                [*1*]Object o = new # [*1*][*2*]new Object(){}[*2*]; \n"+
			"        }\n"+
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"  public void foo(){\n" + 
			"    [*1*]Object o;[*1*]\n" + 
			"    [*2*]new Object(){\n" + 
			"    }\n" + 
			";[*2*]\n" + 
			"  }\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:VARIABLE_DECLARATION_STATEMENT,[72,17],,,[N/A]\n" + 
			"2:EXPRESSION_STATEMENT,[89,14],,,[N/A]\n" + 
			"2:CLASS_INSTANCE_CREATION,[89,14],,,[N/A]\n" + 
			"===== Problems =====\n" + 
			"1. ERROR in /Converter15/src/a/X.java (at line 4)\n" + 
			"	Object o = new # new Object(){}; \n" + 
			"	               ^^^^^\n" + 
			"Syntax error on tokens, delete these tokens\n",
			result);
}

public void testBug277204a() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n" +
			"	{\n" +
			"        class Local {\n" +
			"                [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]  \n" +
			"        }\n" +
			"	}\n" +
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"{\n" + 
			"class Local {\n" + 
			"      [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]\n" + 
			"    }\n" + 
			"  }\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:FIELD_DECLARATION,[69,16],,,[N/A]\n" + 
			"2:VARIABLE_DECLARATION_FRAGMENT,[76,1],,,[VARIABLE,La/X$45$Local;.x)Ljava/lang/Object;,]\n" + 
			"2:SIMPLE_NAME,[76,1],,,[VARIABLE,La/X$45$Local;.x)Ljava/lang/Object;,]\n" + 
			"3:VARIABLE_DECLARATION_FRAGMENT,[79,5],,,[VARIABLE,La/X$45$Local;.Local)Ljava/lang/Object;,]\n" + 
			"3:SIMPLE_NAME,[79,5],,,[VARIABLE,La/X$45$Local;.Local)Ljava/lang/Object;,]\n" + 
			"===== Problems =====\n" + 
			"No problem",
			result);
}
public void testBug277204b() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n" +
			"	{\n" +
			"        class Local {\n" +
			"                [*1*]Object [*2*]x[*2*], [*3*]Local[*3*]  \n" +
			"        [*1*]}\n" +
			"	}\n" +
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"{\n" + 
			"class Local {\n" + 
			"      [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]\n" + 
			"    }\n" + 
			"  }\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:FIELD_DECLARATION,[69,26],,MALFORMED,[N/A]\n" + 
			"2:VARIABLE_DECLARATION_FRAGMENT,[76,1],,,[VARIABLE,La/X$45$Local;.x)Ljava/lang/Object;,]\n" + 
			"2:SIMPLE_NAME,[76,1],,,[VARIABLE,La/X$45$Local;.x)Ljava/lang/Object;,]\n" + 
			"3:VARIABLE_DECLARATION_FRAGMENT,[79,5],,,[VARIABLE,La/X$45$Local;.Local)Ljava/lang/Object;,]\n" + 
			"3:SIMPLE_NAME,[79,5],,,[VARIABLE,La/X$45$Local;.Local)Ljava/lang/Object;,]\n" + 
			"===== Problems =====\n" + 
			"1. ERROR in /Converter15/src/a/X.java (at line 5)\n" + 
			"	Object x, Local  \n" + 
			"	          ^^^^^\n" + 
			"Syntax error, insert \";\" to complete ClassBodyDeclarations\n",
			result);
}
public void testBug277204c() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n" +
			"    [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]  \n" +
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"  [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:FIELD_DECLARATION,[32,16],,,[N/A]\n" + 
			"2:VARIABLE_DECLARATION_FRAGMENT,[39,1],,,[VARIABLE,La/X;.x)Ljava/lang/Object;,]\n" + 
			"2:SIMPLE_NAME,[39,1],,,[VARIABLE,La/X;.x)Ljava/lang/Object;,]\n" + 
			"3:VARIABLE_DECLARATION_FRAGMENT,[42,5],,,[VARIABLE,La/X;.Local)Ljava/lang/Object;,]\n" + 
			"3:SIMPLE_NAME,[42,5],,,[VARIABLE,La/X;.Local)Ljava/lang/Object;,]\n" + 
			"===== Problems =====\n" + 
			"No problem",
			result);
}
public void testBug277204d() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n" +
			"    [*1*]Object [*2*]x[*2*], [*3*]Local[*3*][*1*]  \n" +
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"  [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:FIELD_DECLARATION,[32,15],,MALFORMED|RECOVERED,[N/A]\n" + 
			"2:VARIABLE_DECLARATION_FRAGMENT,[39,1],,,[VARIABLE,La/X;.x)Ljava/lang/Object;,]\n" + 
			"2:SIMPLE_NAME,[39,1],,,[VARIABLE,La/X;.x)Ljava/lang/Object;,]\n" + 
			"3:VARIABLE_DECLARATION_FRAGMENT,[42,5],,,[VARIABLE,La/X;.Local)Ljava/lang/Object;,]\n" + 
			"3:SIMPLE_NAME,[42,5],,,[VARIABLE,La/X;.Local)Ljava/lang/Object;,]\n" + 
			"===== Problems =====\n" + 
			"1. ERROR in /Converter15/src/a/X.java (at line 3)\n" + 
			"	Object x, Local  \n" + 
			"	          ^^^^^\n" + 
			"Syntax error, insert \";\" to complete ClassBodyDeclarations\n",
			result);
}
public void testBug277204e() throws JavaModelException {
	ASTResult result = this.buildMarkedAST(
			"/Converter15/src/a/X.java",
			"package a;\n" +
			"public class X {\n" +
			"	{\n" +
			"        class Local {\n" +
			"                [*1*]Object [*2*]x[*2*],\n" +
			"                [*3*]Local[*3*]  \n" +
			"        [*1*]}\n" +
			"	}\n" +
			"}\n");

	assertASTResult(
			"===== AST =====\n" + 
			"package a;\n" + 
			"public class X {\n" + 
			"{\n" + 
			"class Local {\n" + 
			"      [*1*]Object [*2*]x[*2*], [*3*]Local[*3*];[*1*]\n" + 
			"    }\n" + 
			"  }\n" + 
			"}\n" + 
			"\n" + 
			"===== Details =====\n" + 
			"1:FIELD_DECLARATION,[69,42],,MALFORMED,[N/A]\n" + 
			"2:VARIABLE_DECLARATION_FRAGMENT,[76,1],,,[VARIABLE,La/X$45$Local;.x)Ljava/lang/Object;,]\n" + 
			"2:SIMPLE_NAME,[76,1],,,[VARIABLE,La/X$45$Local;.x)Ljava/lang/Object;,]\n" + 
			"3:VARIABLE_DECLARATION_FRAGMENT,[95,5],,,[VARIABLE,La/X$45$Local;.Local)Ljava/lang/Object;,]\n" + 
			"3:SIMPLE_NAME,[95,5],,,[VARIABLE,La/X$45$Local;.Local)Ljava/lang/Object;,]\n" + 
			"===== Problems =====\n" + 
			"1. ERROR in /Converter15/src/a/X.java (at line 6)\n" + 
			"	Local  \n" + 
			"	^^^^^\n" + 
			"Syntax error, insert \";\" to complete ClassBodyDeclarations\n",
			result);
}
}
