/*******************************************************************************
 * Copyright (c) 2000, 2009 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.model;


import java.io.File;
import java.io.IOException;
import java.util.Hashtable;

import junit.framework.Test;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CompilationParticipant;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.compiler.ReconcileContext;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;

public class ReconcilerTests extends ModifyingResourceTests {

	protected ICompilationUnit workingCopy;
	protected ProblemRequestor problemRequestor;

	/* A problem requestor that auto-cancels on first problem */
	class CancelingProblemRequestor extends ProblemRequestor {
		IProgressMonitor progressMonitor = new IProgressMonitor() {
			boolean isCanceled = false;
			public void beginTask(String name, int totalWork) {}
			public void done() {}
			public void internalWorked(double work) {}
			public boolean isCanceled() {
				return this.isCanceled;
			}
			public void setCanceled(boolean value) {
				this.isCanceled = value;
			}
			public void setTaskName(String name) {}
			public void subTask(String name) {}
			public void worked(int work) {}
		};

		boolean isCanceling = false;
		public void acceptProblem(IProblem problem) {
			if (this.isCanceling) this.progressMonitor.setCanceled(true); // auto-cancel on first problem
			super.acceptProblem(problem);
		}
	}

	class ReconcileParticipant extends CompilationParticipant {
		IJavaElementDelta delta;
		org.eclipse.jdt.core.dom.CompilationUnit ast;
		ReconcileParticipant() {
			TestCompilationParticipant.PARTICIPANT = this;
		}
		public boolean isActive(IJavaProject project) {
			return true;
		}
		public void reconcile(ReconcileContext context) {
			this.delta = context.getDelta();
			try {
				this.ast = context.getAST3();
			} catch (JavaModelException e) {
				assertNull("Unexpected exception", e);
			}
		}
	}
/**
 */
public ReconcilerTests(String name) {
	super(name);
}
// Use this static initializer to specify subset for tests
// All specified tests which do not belong to the class are skipped...
static {
//	JavaModelManager.VERBOSE = true;
//	org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
//	TESTS_PREFIX = "testIgnoreIfBetterNonAccessibleRule";
//	TESTS_NAMES = new String[] { "testIgnoreMethodBodies1", "testIgnoreMethodBodies2" };
//	TESTS_NUMBERS = new int[] { 118823 };
//	TESTS_RANGE = new int[] { 16, -1 };
}
public static Test suite() {
	return buildModelTestSuite(ReconcilerTests.class);
}
protected void assertProblems(String message, String expected) {
	assertProblems(message, expected, this.problemRequestor);
}
protected void assertProblemsInclude(String message, String expected) {
	String actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(this.problemRequestor.problems.toString());
	String independantExpectedString = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(expected);
	if (actual.indexOf(independantExpectedString) == -1){
	 	System.out.println(org.eclipse.jdt.core.tests.util.Util.displayString(actual, this.tabs));
		assertEquals(
			message,
			independantExpectedString,
			actual);
	}
}
// Expect no error as soon as indexing is finished
protected void assertNoProblem(char[] source, ICompilationUnit unit) throws InterruptedException, JavaModelException {
	IndexManager indexManager = JavaModelManager.getIndexManager();
	if (this.problemRequestor.problemCount > 0) {
		// If errors then wait for indexes to finish
		while (indexManager.awaitingJobsCount() > 0) {
			Thread.sleep(100);
		}
		// Reconcile again to see if error goes away
		this.problemRequestor.initialize(source);
		unit.getBuffer().setContents(source); // need to set contents again to be sure that following reconcile will be really done
		unit.reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		if (this.problemRequestor.problemCount > 0) {
			assertEquals("Working copy should NOT have any problem!", "", this.problemRequestor.problems.toString());
		}
	}
}
protected void addClasspathEntries(IClasspathEntry[] entries, boolean enableForbiddenReferences) throws JavaModelException {
	IJavaProject project = getJavaProject("Reconciler");
	IClasspathEntry[] oldClasspath = project.getRawClasspath();
	int oldLength = oldClasspath.length;
	int length = entries.length;
	IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+length];
	System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
	System.arraycopy(entries, 0, newClasspath, oldLength, length);
	project.setRawClasspath(newClasspath, null);

	if (enableForbiddenReferences) {
		project.setOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
	}
}
protected void removeClasspathEntries(IClasspathEntry[] entries) throws JavaModelException {
	IJavaProject project = getJavaProject("Reconciler");
	IClasspathEntry[] oldClasspath = project.getRawClasspath();
	int oldLength = oldClasspath.length;
	int length = entries.length;
	IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength-length];
	System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength-length);
	project.setRawClasspath(newClasspath, null);
}
/**
 * Setup for the next test.
 */
public void setUp() throws Exception {
	super.setUp();
	this.problemRequestor =  new ProblemRequestor();
	this.wcOwner = new WorkingCopyOwner() {
		public IProblemRequestor getProblemRequestor(ICompilationUnit unit) {
			return ReconcilerTests.this.problemRequestor;
		}
	};
	this.workingCopy = getCompilationUnit("Reconciler/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
	this.problemRequestor.initialize(this.workingCopy.getSource().toCharArray());
	startDeltas();
}
public void setUpSuite() throws Exception {
	super.setUpSuite();

	// Create project with 1.4 compliance
	IJavaProject project14 = createJavaProject("Reconciler", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
	createFolder("/Reconciler/src/p1");
	createFolder("/Reconciler/src/p2");
	createFile(
		"/Reconciler/src/p1/X.java",
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
	project14.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.IGNORE);
	project14.setOption(JavaCore.COMPILER_PB_INVALID_JAVADOC, JavaCore.WARNING);

	// Create project with 1.5 compliance
	IJavaProject project15 = createJavaProject("Reconciler15", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5");
	addLibrary(
		project15,
		"lib15.jar",
		"lib15src.zip",
		new String[] {
			"java/util/List.java",
			"package java.util;\n" +
			"public class List<T> {\n" +
			"}",
			"java/util/Stack.java",
			"package java.util;\n" +
			"public class Stack<T> {\n" +
			"}",
			"java/util/Map.java",
			"package java.util;\n" +
			"public interface Map<K,V> {\n" +
			"}",
			"java/lang/annotation/Annotation.java",
			"package java.lang.annotation;\n" +
			"public interface Annotation {\n" +
			"}",
			"java/lang/Deprecated.java",
			"package java.lang;\n" +
			"public @interface Deprecated {\n" +
			"}",
			"java/lang/SuppressWarnings.java",
			"package java.lang;\n" +
			"public @interface SuppressWarnings {\n" +
			"   String[] value();\n" +
			"}"
		},
		JavaCore.VERSION_1_5
	);
	project15.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.IGNORE);
	project15.setOption(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE, JavaCore.IGNORE);
}
private void setUp15WorkingCopy() throws JavaModelException {
	setUp15WorkingCopy("Reconciler15/src/p1/X.java", this.wcOwner);
}
private void setUp15WorkingCopy(String path, WorkingCopyOwner owner) throws JavaModelException {
	String contents = this.workingCopy.getSource();
	setUpWorkingCopy(path, contents, owner);
}
private void setUpWorkingCopy(String path, String contents) throws JavaModelException {
	setUpWorkingCopy(path, contents, this.wcOwner);
}
private void setUpWorkingCopy(String path, String contents, WorkingCopyOwner owner) throws JavaModelException {
	this.workingCopy.discardWorkingCopy();
	this.workingCopy = getCompilationUnit(path).getWorkingCopy(owner, null);
	assertEquals("Invalid problem requestor!", this.problemRequestor, this.wcOwner.getProblemRequestor(this.workingCopy));
	setWorkingCopyContents(contents);
	this.workingCopy.makeConsistent(null);
}
void setWorkingCopyContents(String contents) throws JavaModelException {
	this.workingCopy.getBuffer().setContents(contents);
	this.problemRequestor.initialize(contents.toCharArray());
}
/**
 * Cleanup after the previous test.
 */
public void tearDown() throws Exception {
	TestCompilationParticipant.PARTICIPANT = null;
	if (this.workingCopy != null) {
		this.workingCopy.discardWorkingCopy();
	}
	stopDeltas();
	super.tearDown();
}
public void tearDownSuite() throws Exception {
	deleteProject("Reconciler");
	deleteProject("Reconciler15");
	super.tearDownSuite();
}
/*
 * Ensures that no problem is created for a reference to a type that is included in a prereq project.
 */
public void testAccessRestriction() throws CoreException {
	try {
		createJavaProject("P1", new String[] {"src"}, new String[] {"JCL_LIB"}, null, null, new String[0], null, null, new boolean[0], "bin", null, new String[][] {{"**/X.java"}}, null, "1.4");
		createFolder("/P1/src/p");
		createFile("/P1/src/p/X.java", "package p; public class X {}");

		createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin");
		setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}");
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
/*
 * Ensures that no problem is created for a reference to a binary type that is included in a prereq project.
 * (regression test for bug 82542 Internal error during AST creation)
 */
public void testAccessRestriction2() throws CoreException, IOException {
	try {
		IJavaProject project = createJavaProject("P1");
		addLibrary(
			project,
			"lib.jar",
			"libsrc.zip",
			new String[] {
				"p/X.java",
				"package p;\n" +
				"public class X {\n" +
				"}",
			},
			null/*no non-Java resources*/,
			new String[] {
				"**/*"
			},
			null, 
			"1.4"
		);
		createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin");
		setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}");
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
/*
 * Ensures that no problem is created for a reference to a type that is included and not exported in a prereq project
 * but with combineAccessRestriction flag set to false.
 */
public void testAccessRestriction3() throws CoreException {
	try {
		createJavaProject("P1");
		createFolder("/P1/p");
		createFile("/P1/p/X.java", "package p; public class X {}");

		createJavaProject("P2", new String[] {}, new String[] {}, null, null, new String[] {"/P1"}, null, null, new boolean[] {true}, "", null, null, null, "1.4");

		createJavaProject("P3", new String[] {"src"}, new String[] {"JCL_LIB"}, null, null, new String[] {"/P2"}, null, new String[][] {new String[] {"**/X"}}, false/*don't combine access restrictions*/, new boolean[] {true}, "bin", null, null, null, "1.4", false/*don't import*/);
		setUpWorkingCopy("/P3/src/Y.java", "public class Y extends p.X {}");
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteProjects(new String[] {"P1", "P2", "P3" });
	}
}
/*
 * Ensures that a problem is created for a reference to a type that is included and not exported in a prereq project
 * but with combineAccessRestriction flag set to true.
 */
public void testAccessRestriction4() throws CoreException {
	try {
		createJavaProject("P1");
		createFolder("/P1/p");
		createFile("/P1/p/X.java", "package p; public class X {}");

		createJavaProject("P2", new String[] {}, new String[] {}, null, null, new String[] {"/P1"}, null, null, new boolean[] {true}, "", null, null, null, "1.4");

		createJavaProject("P3", new String[] {"src"}, new String[] {"JCL_LIB"}, null, null, new String[] {"/P2"}, null, new String[][] {new String[] {"**/X"}}, true/*combine access restrictions*/, new boolean[] {true}, "bin", null, null, null, "1.4", false/*don't import*/);
		setUpWorkingCopy("/P3/src/Y.java", "public class Y extends p.X {}");
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /P3/src/Y.java (at line 1)\n" +
			"	public class Y extends p.X {}\n" +
			"	                       ^^^\n" +
			"Access restriction: The type X is not accessible due to restriction on required project P1\n" +
			"----------\n"
		);
	} finally {
		deleteProjects(new String[] {"P1", "P2", "P3" });
	}
}
/*
 * Ensures that a problem is created for a reference to a type that is no longer accessible in a prereq project.
 * (regression test for bug 91498 Reconcile still sees old access rules)
 */
public void testAccessRestriction5() throws CoreException {
	try {
		createJavaProject("P1");
		createFolder("/P1/p");
		createFile("/P1/p/X.java", "package p; public class X {}");
		IJavaProject p2 = createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		IClasspathEntry[] classpath = p2.getRawClasspath();
		int length = classpath.length;
		System.arraycopy(classpath, 0, classpath = new IClasspathEntry[length+1], 0, length);
		classpath[length] = createSourceEntry("P2", "/P1", "+**/p/|-**/*");
		p2.setRawClasspath(classpath, null);
		setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}");
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);

		// remove accessible rule
		System.arraycopy(classpath, 0, classpath = new IClasspathEntry[length+1], 0, length);
		classpath[length] = createSourceEntry("P2", "/P1", "-**/*");
		p2.setRawClasspath(classpath, null);
		this.problemRequestor.initialize(this.workingCopy.getSource().toCharArray());
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /P2/src/Y.java (at line 1)\n" +
			"	public class Y extends p.X {}\n" +
			"	                       ^^^\n" +
			"Access restriction: The type X is not accessible due to restriction on required project P1\n" +
			"----------\n"
		);

	} finally {
		deleteProjects(new String[] {"P1", "P2"});
	}
}
/**
 * Ensures that the reconciler handles duplicate members correctly.
 */
public void testAddDuplicateMember() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()#2[+]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents, updating the structure of this reconciler's compilation
 * unit, and fires the Java element delta for the structural changes
 * of the addition of a field and a constructor.
 */
public void testAddFieldAndConstructor() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  int i;\n" +
		"  X(int i) {\n" +
		"    this.i = i;\n" +
		"  }\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	X(int)[+]: {}\n" +
		"	i[+]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents, updating the structure of this reconciler's compilation
 * unit, and fires the Java element delta for the structural changes
 * of the addition of a field and a constructor.
 */
public void testAddImports() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"import java.lang.reflect.*;\n" +
		"import java.util.Vector;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"<import container>[*]: {CHILDREN | FINE GRAINED}\n" +
		"	import java.lang.reflect.*[+]: {}\n" +
		"	import java.util.Vector[+]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents, updating the structure of this reconciler's compilation
 * unit, and fires the Java element delta for the structural changes
 * of the addition of a method.
 */
public void testAddMethod1() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	bar()[+]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents,updating the structure of this reconciler's compilation
 * unit, and fires the Java element delta for the structural changes
 * of the addition of a portion of a new method.
 */
public void testAddPartialMethod1() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void some()\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	some()[+]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents,updating the structure of this reconciler's compilation
 * unit, and fires the Java element delta for the structural changes
 * of the addition of a portion of a new method.  Ensures that when a
 * second part is added to the new method no structural changes are recognized.
 */
public void testAddPartialMethod1and2() throws JavaModelException {
	// Add partial method before foo
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void some()\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

	// Add { on partial method
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void some() {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
	);
}
/*
 * Ensures that the delta is correct when adding an annotation
 */
public void testAnnotations1() throws JavaModelException {
	setUp15WorkingCopy();
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  @MyAnnot\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {ANNOTATIONS}\n" +
		"		@MyAnnot[+]: {}"
	);
}
/*
 * Ensures that the delta is correct when removing an annotation
 */
public void testAnnotations2() throws JavaModelException {
	setUp15WorkingCopy();
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  @MyAnnot\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {ANNOTATIONS}\n" +
		"		@MyAnnot[-]: {}"
	);
}
/*
 * Ensures that the delta is correct when changing an annotation
 */
public void testAnnotations3() throws JavaModelException {
	setUp15WorkingCopy();
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  @MyAnnot(x=1)\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  @MyAnnot(y=1)\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {ANNOTATIONS}\n" +
		"		@MyAnnot[*]: {CONTENT}"
	);
}
/*
 * Ensures that the delta is correct when changing an annotation
 */
public void testAnnotations4() throws JavaModelException {
	setUp15WorkingCopy();
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  @MyAnnot(x=1)\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  @MyAnnot(x=2)\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {ANNOTATIONS}\n" +
		"		@MyAnnot[*]: {CONTENT}"
	);
}
/*
 * Ensures that no error is reported if an annotation type's cu starts with a slash
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=214450 )
 */
public void testAnnotations5() throws JavaModelException {
	ICompilationUnit annotation = null;
	try {
		setUp15WorkingCopy();
		annotation = getWorkingCopy(
			"Reconciler15/src/p1/MyAnnot2.java",
			"/* test */\n" +
			"package p1;\n" +
			"public @interface MyAnnot2 {\n" +
			"  String bar();\n" +
			"}",
			this.wcOwner);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X {\n" +
			"  @MyAnnot2(bar=\"a\")\n" +
			"  public void foo() {\n" +
			"  }\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (annotation != null)
			annotation.discardWorkingCopy();
	}
}
/*
 * Ensures that the AST broadcasted during a reconcile operation is correct.
 * (case of a working copy being reconciled with changes, creating AST and no problem detection)
 */
public void testBroadcastAST1() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(AST.JLS3, false/*don't force problem detection*/, null/*primary owner*/, null/*no progress*/);
	assertASTNodeEquals(
		"Unexpected ast",
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"}\n",
		this.deltaListener.getCompilationUnitAST(this.workingCopy));
}
/*
 * Ensures that the AST broadcasted during a reconcile operation is correct.
 * (case of a working copy being reconciled with NO changes, creating AST and forcing problem detection)
 */
public void testBroadcastAST2() throws JavaModelException {
	this.workingCopy.reconcile(AST.JLS3, true/*force problem detection*/, null/*primary owner*/, null/*no progress*/);
	assertASTNodeEquals(
		"Unexpected ast",
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo(){\n" +
		"  }\n" +
		"}\n",
		this.deltaListener.getCompilationUnitAST(this.workingCopy));
}
/*
 * Ensures that no AST is broadcasted during a reconcile operation if the working copy being reconciled
 * has NO changes and NO problem detection is requested)
 */
public void testBroadcastAST3() throws JavaModelException {
	this.workingCopy.reconcile(AST.JLS3, false/*don't force problem detection*/, null/*primary owner*/, null/*no progress*/);
	assertASTNodeEquals(
		"Unexpected ast",
		"null",
		this.deltaListener.getCompilationUnitAST(this.workingCopy));
}
/*
 * Ensures that the AST broadcasted during a reconcile operation is correct.
 * (case of a working copy being reconciled twice in a batch operation)
 */
public void testBroadcastAST4() throws CoreException {
	JavaCore.run(
		new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				ReconcilerTests.this.workingCopy.reconcile(AST.JLS3, true/*force problem detection*/, null/*primary owner*/, monitor);
				setWorkingCopyContents(
					"package p1;\n" +
					"import p2.*;\n" +
					"public class X {\n" +
					"}");
				ReconcilerTests.this.workingCopy.reconcile(AST.JLS3, false/*don't force problem detection*/, null/*primary owner*/, monitor);
			}
		},
		null/*no progress*/);
	assertASTNodeEquals(
		"Unexpected ast",
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"}\n",
		this.deltaListener.getCompilationUnitAST(this.workingCopy));
}
/*
 * Ensures that the AST broadcasted doesn't have a type root that is caching its contents
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=222213 )
 */
public void testBroadcastAST5() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(AST.JLS3, false/*don't force problem detection*/, null/*primary owner*/, null/*no progress*/);
	org.eclipse.jdt.core.dom.CompilationUnit compilationUnit = this.deltaListener.getCompilationUnitAST(this.workingCopy);
	String newContents =
		"package p1;\n" +
		"public class X {\n" +
		"}";
	setWorkingCopyContents(newContents);
	org.eclipse.jdt.internal.compiler.env.ICompilationUnit compilerCU = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnit.getTypeRoot();
	assertSourceEquals("Unexpected contents", newContents, new String(compilerCU.getContents()));
}
/*
 * Ensures that reconciling a subclass doesn't close the buffer while resolving its superclass.
 * (regression test for bug 62854 refactoring does not trigger reconcile)
 */
public void testBufferOpenAfterReconcile() throws CoreException {
 	try {
		createFile(
			"/Reconciler/src/p1/Super.java",
			"package p1;\n" +
			"public class Super {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"import p2.*;\n" +
			"public class X extends Super {\n" +
			"  public void foo() {\n" +
			"  }\n" +
			"}");
		IBuffer buffer = this.workingCopy.getBuffer();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
		assertTrue("Buffer should still be open", !buffer.isClosed());
	} finally {
		deleteFile("/Reconciler/src/p1/Super.java");
	}
}
/*
 * Ensures that reconciling with a closed buffer reports an error
 * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=138882 )
 */
public void testBufferClosed1() throws CoreException {
	this.wcOwner = new WorkingCopyOwner() {
		public IBuffer createBuffer(ICompilationUnit copy) {
			return new TestBuffer(copy);
		}
		public IProblemRequestor getProblemRequestor(ICompilationUnit unit) {
			return ReconcilerTests.this.problemRequestor;
		}
	};
	setUpWorkingCopy(
		"Reconciler/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"  void foo(String s) {\n" +
		"  }\n" +
		"}"
	);

	// simulate buffer being closed
	((TestBuffer) this.workingCopy.getBuffer()).contents = null;

	this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
	assertProblemsInclude(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 1)\n" +
		"	package p1;\n" +
		"	^\n" +
		"Cannot read the source from /Reconciler/src/p1/X.java due to internal exception java.io.IOException:Buffer is closed\n" +
		"----------\n"
	);
}
/*
 * Ensures that reconciling with a closed buffer reports an error
 * (regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=138882 )
 */
public void testBufferClosed2() throws CoreException {
	this.wcOwner = new WorkingCopyOwner() {
		public IBuffer createBuffer(ICompilationUnit copy) {
			return new TestBuffer(copy);
		}
		public IProblemRequestor getProblemRequestor(ICompilationUnit unit) {
			return ReconcilerTests.this.problemRequestor;
		}
	};
	setUpWorkingCopy(
		"Reconciler/src/p1/X.java",
		"package p1;\n" +
		"public class X {\n" +
		"  void foo(String s) {\n" +
		"  }\n" +
		"}"
	);
	// make the working copy not consistent
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"}"
	);

	// simulate buffer being closed
	((TestBuffer) this.workingCopy.getBuffer()).contents = null;

	this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
	assertProblemsInclude(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 1)\n" +
		"	package p1;\n" +
		"	^\n" +
		"Cannot read the source from /Reconciler/src/p1/X.java due to internal exception java.io.IOException:Buffer is closed\n" +
		"----------\n"
	);
}
/**
 * Ensure an OperationCanceledException is correcly thrown when progress monitor is canceled
 * @deprecated using deprecated code
 */
public void testCancel() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"  void foo(String s) {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	// count the number of time isCanceled() is called when converting this source unit
	CancelCounter counter = new CancelCounter();
	this.workingCopy.reconcile(AST.JLS2, true, null, counter);

	// throw an OperatonCanceledException at each point isCanceled() is called
	for (int i = 0; i < counter.count; i++) {
		boolean gotException = false;
		try {
			this.workingCopy.reconcile(AST.JLS2, true, null, new Canceler(i));
		} catch (OperationCanceledException e) {
			gotException = true;
		}
		assertTrue("Should get an OperationCanceledException (" + i + ")", gotException);
	}

	// last should not throw an OperationCanceledException
	this.workingCopy.reconcile(AST.JLS2, true, null, new Canceler(counter.count));
}
/**
 * Ensures that the delta is correct when adding a category
 */
public void testCategories1() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  /**\n" +
		"   * @category cat1\n" +
		"   */\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {CATEGORIES}"
	);
}
/**
 * Ensures that the delta is correct when removing a category
 */
public void testCategories2() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  /**\n" +
		"   * @category cat1\n" +
		"   */\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {CATEGORIES}"
	);
}
/**
 * Ensures that the delta is correct when changing a category
 */
public void testCategories3() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  /**\n" +
		"   * @category cat1\n" +
		"   */\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  /**\n" +
		"   * @category cat2\n" +
		"   */\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {CATEGORIES}"
	);
}
/*
 * Ensures that the delta is correct when adding a category to a second field
 * (regression test for bug 125675 @category not reflected in outliner in live fashion)
 */
public void testCategories4() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  /**\n" +
		"   * @category cat1\n" +
		"   */\n" +
		"  int f1;\n" +
		"  int f2;\n" +
		"}"
	);
	this.workingCopy.makeConsistent(null);

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  /**\n" +
		"   * @category cat1\n" +
		"   */\n" +
		"  int f1;\n" +
		"  /**\n" +
		"   * @category cat2\n" +
		"   */\n" +
		"  int f2;\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	f2[*]: {CATEGORIES}"
	);
}
/*
 * Ensures that changing the source level to make a type valid doesn't report an error any longer
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568 )
 */
public void testChangeSourceLevel1() throws Exception {
	try {
		IJavaProject p = createJavaProject("P1", new String[] {"src"}, new String[] {"JCL15_LIB", "/P1/lib.jar"}, "bin", "1.5");
		Util.createJar(new String[] {
				"p/enum/X.java",
				"package p.enum;\n" +
				"public class X{\n" +
				"}"
			},
			p.getProject().getLocation().append("lib.jar").toOSString(),
			"1.3");
		refresh(p);
		setUpWorkingCopy(
			"/P1/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"  p.enum.X field;\n" +
			"}");
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		/* At this point, the following error is reported:
		"----------\n" +
		"1. ERROR in /P1/src/p1/X.java (at line 3)\n" +
		"	p.enum.X field;\n" +
		"	  ^^^^\n" +
		"Syntax error on token \"enum\", Identifier expected\n" +
		"----------\n"
		*/

		this.problemRequestor.reset();
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. WARNING in /P1/src/p1/X.java (at line 3)\n" +
			"	p.enum.X field;\n" +
			"	  ^^^^\n" +
			"\'enum\' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on\n" +
			"----------\n"
		);
	} finally {
		deleteProject("P1");
	}
}
/*
 * Ensures that changing the source level to make a type valid doesn't report an error any longer
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568 )
 */
public void testChangeSourceLevel2() throws Exception {
	Hashtable defaultOptions = null;
	try {
		defaultOptions = JavaCore.getOptions();
		Hashtable newOptions = new Hashtable();
		newOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		JavaCore.setOptions(newOptions);
		IJavaProject p = createJavaProject("P1", new String[] {"src"}, new String[] {"JCL15_LIB", "/P1/lib.jar"}, "bin");
		Util.createJar(new String[] {
				"p/enum/X.java",
				"package p.enum;\n" +
				"public class X{\n" +
				"}"
			},
			p.getProject().getLocation().append("lib.jar").toOSString(),
			"1.3");
		refresh(p);
		setUpWorkingCopy(
			"/P1/src/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"  p.enum.X field;\n" +
			"}");
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		/* At this point, the following error is reported:
		"----------\n" +
		"1. ERROR in /P1/src/p1/X.java (at line 3)\n" +
		"	p.enum.X field;\n" +
		"	  ^^^^\n" +
		"Syntax error on token \"enum\", Identifier expected\n" +
		"----------\n"
		*/

		this.problemRequestor.reset();
		newOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
		JavaCore.setOptions(newOptions);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. WARNING in /P1/src/p1/X.java (at line 3)\n" +
			"	p.enum.X field;\n" +
			"	  ^^^^\n" +
			"\'enum\' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on\n" +
			"----------\n"
		);
	} finally {
		deleteProject("P1");
		if (defaultOptions != null)
			JavaCore.setOptions(defaultOptions);
	}
}
/*
 * Ensures that changing a binary folder used as class folder in 2 projects doesn't cause the old binary to be seen
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=210746 )
 */
public void testChangeClassFolder() throws CoreException {
	try {
		createJavaProject("P1", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		createFolder("/P1/src/p");
		createFile(
			"/P1/src/p/X.java",
			"package p;\n" +
			"public class X {\n" +
			"}"
		);
		getProject("P1").build(IncrementalProjectBuilder.FULL_BUILD, null);
		createJavaProject("P2", new String[0], new String[] {"/P1/bin"}, "bin");
		createJavaProject("P3", new String[] {"src"}, new String[] {"JCL_LIB", "/P1/bin"}, "bin");
		setUpWorkingCopy(
			"/P3/src/q/Y.java",
			"package q;\n" +
			"import p.X;\n" +
			"public class Y {\n" +
			"  void foo(X x) {\n" +
			"  }\n"+
			"}"
		);
		editFile(
			"/P1/src/p/X.java",
			"package p;\n" +
			"public class X {\n" +
			"  public void bar() {\n" +
			"  }\n" +
			"}"
		);
		getProject("P1").build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
		setWorkingCopyContents(
			"package q;\n" +
			"import p.X;\n" +
			"public class Y {\n" +
			"  void foo(X x) {\n" +
			"    x.bar();\n" +
			"  }\n"+
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteProjects(new String[] {"P1", "P2", "P3"});
	}
}
/*
 * Ensures that changing and external jar and refreshing takes the change into account
 * (regression test for bug 134110 [regression] Does not pick-up interface changes from classes in the build path)
 */
public void testChangeExternalJar() throws CoreException, IOException {
	IJavaProject project = getJavaProject("Reconciler");
	String jarPath = getExternalPath() + "lib.jar";
	try {
		createJar(new String[] {
			"p/Y.java",
			"package p;\n" +
			"public class Y {\n" +
			"  public void foo() {\n" +
			"  }\n" +
			"}"
		}, jarPath);
		addLibraryEntry(project, jarPath, false);

		// force Y.class file to be cached during resolution
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.Y {\n" +
			"  public void bar() {\n" +
			"    foo();\n" +
			"  }\n" +
			"}");
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

		// change jar and refresh
		createJar(new String[] {
			"p/Y.java",
			"package p;\n" +
			"public class Y {\n" +
			"  public void foo(String s) {\n" +
			"  }\n" +
			"}"
		}, jarPath);
		getJavaModel().refreshExternalArchives(null,null);

		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.Y {\n" +
			"  public void bar() {\n" +
			"    foo(\"a\");\n" +
			"  }\n" +
			"}");
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntry(project, new Path(jarPath));
		deleteResource(new File(jarPath));
	}
}
/**
 * @bug 162621: [model][delta] Validation errors do not clear after replacing jar file
 * @test Ensures that changing an internal jar and refreshing takes the change into account
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=162621"
 */
public void testChangeInternalJar() throws CoreException, IOException {
	IJavaProject project = getJavaProject("Reconciler");
	String jarName = "b162621.jar";
	try {
		String[] pathAndContents = new String[] {
			"test/before/Foo.java",
			"package test.before;\n" +
			"public class Foo {\n" +
			"}\n"
		};
		addLibrary(project, jarName, "b162621_src.zip", pathAndContents, JavaCore.VERSION_1_4);

		// Wait a little bit to be sure file system is aware of zip file creation
		try {
			Thread.sleep(1000);
		}
		catch (InterruptedException ie) {
			// skip
		}

		// Set working copy content with no error
		setUpWorkingCopy("/Reconciler/src/test/Test.java",
			"package test;\n" +
			"import test.before.Foo;\n" +
			"public class Test {\n" +
			"	Foo f;\n" +
			"}\n"
		);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);

		// Update working copy with Jar expected changes
		String contents = "package test;\n" +
			"import test.after.Foo;\n" +
			"public class Test {\n" +
			"	Foo f;\n" +
			"}\n";
		setWorkingCopyContents(contents);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
		assertProblems(
			"Wrong expected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/test/Test.java (at line 2)\n" +
			"	import test.after.Foo;\n" +
			"	       ^^^^^^^^^^\n" +
			"The import test.after cannot be resolved\n" +
			"----------\n" +
			"2. ERROR in /Reconciler/src/test/Test.java (at line 4)\n" +
			"	Foo f;\n" +
			"	^^^\n" +
			"Foo cannot be resolved to a type\n" +
			"----------\n"
		);

		// change jar and refresh
		String projectLocation = project.getProject().getLocation().toOSString();
		String jarPath = projectLocation + File.separator + jarName;
		createJar(new String[] {
			"test/after/Foo.java",
			"package test.after;\n" +
			"public class Foo {\n" +
			"}\n"
		}, jarPath);
		project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);

		try {
			Thread.sleep(1000);
		}
		catch (InterruptedException ie) {
			// skip
		}

		// Verify that error is gone
		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntry(project, new Path(jarName));
		deleteResource(new File(jarName));
	}
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents,updating the structure of this reconciler's compilation
 * unit, and fires the Java element deltas for the structural changes
 * of a method's type parameter change.
 */
public void testChangeMethodTypeParameters() throws JavaModelException {
	setUp15WorkingCopy();
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public <T> void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {CONTENT}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents,updating the structure of this reconciler's compilation
 * unit, and fires the Java element deltas for the structural changes
 * of a type's type parameter change.
 */
public void testChangeTypeTypeParameters() throws JavaModelException {
	setUp15WorkingCopy();
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X <T> {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CONTENT}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents,updating the structure of this reconciler's compilation
 * unit, and fires the Java element deltas for the structural changes
 * of a method visibility change.
 */
public void testChangeMethodVisibility() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  private void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {MODIFIERS CHANGED}"
	);
}
/**
 * Ensures that the correct delta is reported when closing the working copy and modifying its buffer.
 */
public void testCloseWorkingCopy() throws JavaModelException {
	IBuffer buffer = this.workingCopy.getBuffer();
	this.workingCopy.close();
	buffer.setContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	bar()[+]: {}"
	);
}

/**
 * Ensures that a reference to a constant with type mismatch doesn't show an error.
 * (regression test for bug 17104 Compiler does not complain but "Quick Fix" ??? complains)
 */
public void testConstantReference() throws CoreException {
	try {
		createFile(
			"/Reconciler/src/p1/OS.java",
			"package p1;\n" +
			"public class OS {\n" +
			"	public static final int CONST = 23 * 1024;\n" +
			"}");
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X {\n" +
			"	public short c;\n" +
			"	public static void main(String[] arguments) {\n" +
			"		short c = 1;\n" +
			"		switch (c) {\n" +
			"			case OS.CONST: return;\n" +
			"		}\n" +
			"	}\n" +
			"}");
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteFile("/Reconciler/src/p1/OS.java");
	}
}
/*
 * Ensures that the source type converter doesn't throw an OutOfMemoryError if converting a generic type with a primitive type array as argument
 * (regression test for bug 135296 opening a special java file results in an "out of memory" message)
 */
public void testConvertPrimitiveTypeArrayTypeArgument() throws CoreException {
	ICompilationUnit otherCopy = null;
	try {
		otherCopy = getWorkingCopy(
			"Reconciler15/src/Y.java",
			"public class Y {\n" +
			"  void foo(Z<int[]> z) {}\n" +
			"}\n" +
			"class Z<E> {\n" +
			"}",
			this.wcOwner
		);
		setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner);
		setWorkingCopyContents(
			"public class X {\n" +
			"  void bar(Y y) {\n" +
			"    y.foo(new Z<int[]>());\n" +
			"  }\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (otherCopy != null)
			otherCopy.discardWorkingCopy();
	}
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents, updating the structure of this reconciler's compilation
 * unit, and fires the Java element deltas for the structural changes
 * of a method being deleted.
 */
public void testDeleteMethod1() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[-]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents, updating the structure of this reconciler's compilation
 * unit, and fires the Java element deltas for the structural changes
 * of two methods being deleted.
 */
public void testDeleteTwoMethods() throws JavaModelException {
	// create 2 methods
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

	// delete the 2 methods
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	bar()[-]: {}\n" +
		"	foo()[-]: {}"
	);
}
/*
 * Ensures that excluded part of prereq project are not visible
 */
public void testExcludePartOfAnotherProject1() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "-**/internal/"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P");
		createFolder("/P/p/internal");
		createFile(
			"/P/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.internal.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" +
			"	public class X extends p.internal.Y {\n" +
			"	                       ^^^^^^^^^^^^\n" +
			"Access restriction: The type Y is not accessible due to restriction on required project P\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProject("P");
	}
}
/*
 * Ensures that packages that are not in excluded part of prereq project are visible
 */
public void testExcludePartOfAnotherProject2() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "-**/internal/"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P");
		createFolder("/P/p/api");
		createFile(
			"/P/p/api/Y.java",
			"package p.api;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.api.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProject("P");
	}
}
/*
 * Ensures that an external working copy can be reconciled with no error.
 */
public void testExternal1() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	this.problemRequestor =  new ProblemRequestor();
	IClasspathEntry[] classpath = new IClasspathEntry[] {JavaCore.newLibraryEntry(getExternalJCLPath(), null, null)};
	this.workingCopy = newExternalWorkingCopy("External.java", classpath, this.problemRequestor,
		"public class External {\n"+
		"	String foo(){\n"+
		"		return \"\";\n" +
		"	}\n"+
		"}\n"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null/*no owner*/, null);

	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"----------\n"
	);
}

/*
 * Ensures that an external working copy with a container classpath entry can be reconciled with no exception.
 * (regression test for bug 148970 Exceptions opening external Java file)
 */
public void testExternal2() throws CoreException {
	class LogListener implements ILogListener {
    	IStatus loggedStatus;
        public void logging(IStatus status, String plugin) {
            this.loggedStatus = status;
        }
	}
	LogListener listener = new LogListener();
	try {
		Platform.addLogListener(listener);
		this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
		this.workingCopy = null;
		this.problemRequestor =  new ProblemRequestor();
		ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {" ", getExternalJCLPathString()}));
		IClasspathEntry[] classpath = new IClasspathEntry[] {
			JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"))
		};
		this.workingCopy = newExternalWorkingCopy("External.java", classpath, this.problemRequestor,
			"public class External {\n"+
			"	String foo(){\n"+
			"		return \"\";\n" +
			"	}\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null/*no owner*/, null);
		assertEquals("Should not get any exception in log", null, listener.loggedStatus);
	} finally {
		Platform.removeLogListener(listener);
	}
}

/*
 * Ensures that an error is detected after refreshing external archives used by
 * an external working copy.
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=216772 )
 */
public void testExternal3() throws Exception {
	try {
		this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
		this.workingCopy = null;
		this.problemRequestor =  new ProblemRequestor();
		createJar(new String[] {
			"p/Lib.java",
			"package p;\n" +
			"public class Lib {\n" +
			"}"
		}, getExternalResourcePath("lib.jar"));
		IClasspathEntry[] classpath = new IClasspathEntry[] {
			JavaCore.newLibraryEntry(getExternalJCLPath(), null, null),
			JavaCore.newLibraryEntry(new Path(getExternalResourcePath("lib.jar")), null, null)
		};
		this.workingCopy = newExternalWorkingCopy("External.java", classpath, this.problemRequestor,
			"public class External {\n"+
			"	p.Lib field;\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null/*no owner*/, null);

		createJar(new String[] {
			"p/Lib2.java",
			"package p;\n" +
			"public class Lib2 {\n" +
			"}"
		}, getExternalResourcePath("lib.jar"));
		getJavaModel().refreshExternalArchives(null, null);
		this.problemRequestor.reset();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null/*no owner*/, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in / /External.java\n" +
			"p.Lib cannot be resolved to a type\n" +
			"----------\n"
		);
	} finally {
		deleteExternalResource("lib.jar");
	}
}

/*
 * Ensures that included part of prereq project are visible
 */
public void testIncludePartOfAnotherProject1() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "+**/api/"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P");
		createFolder("/P/p/api");
		createFile(
			"/P/p/api/Y.java",
			"package p.api;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.api.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProject("P");
	}
}
/*
 * Ensures that packages that are not in included part of prereq project are not visible
 */
public void testIncludePartOfAnotherProject2() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P", "+**/api/|-**"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P");
		createFolder("/P/p/internal");
		createFile(
			"/P/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.internal.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" +
			"	public class X extends p.internal.Y {\n" +
			"	                       ^^^^^^^^^^^^\n" +
			"Access restriction: The type Y is not accessible due to restriction on required project P\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProject("P");
	}
}
/**
 * Start with no imports, add an import, and then append to the import name.
 */
public void testGrowImports() throws JavaModelException {
	// no imports
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

	// add an import
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"<import container>[+]: {}"
	);

	// append to import name
	clearDeltas();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2\n" +
		"public class X {\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"<import container>[*]: {CHILDREN | FINE GRAINED}\n" +
		"	import p2[+]: {}\n" +
		"	import p[-]: {}"
	);
}
/*
 * Ensures that a type matching a ignore-if-better non-accessible rule is further found when accessible
 * on another classpath entry.
 * (regression test for bug 98127 Access restrictions started showing up after switching to bundle)
 */
public void testIgnoreIfBetterNonAccessibleRule1() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/", "/P2", "+**/internal/Y"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P1");
		createFolder("/P1/p/internal");
		createFile(
			"/P1/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		createJavaProject("P2");
		createFolder("/P2/p/internal");
		createFile(
			"/P2/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.internal.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProjects(new String[] {"P1", "P2"});
	}
}
/*
 * Ensures that a type matching a ignore-if-better non-accessible rule is further found when accessible
 * on another classpath entry.
 * (regression test for bug 98127 Access restrictions started showing up after switching to bundle)
 */
public void testIgnoreIfBetterNonAccessibleRule2() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/", "/P2", "~**/internal/Y"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P1");
		createFolder("/P1/p/internal");
		createFile(
			"/P1/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		createJavaProject("P2");
		createFolder("/P2/p/internal");
		createFile(
			"/P2/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.internal.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. WARNING in /Reconciler/src/p1/X.java (at line 2)\n" +
			"	public class X extends p.internal.Y {\n" +
			"	                       ^^^^^^^^^^^^\n" +
			"Discouraged access: The type Y is not accessible due to restriction on required project P2\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProjects(new String[] {"P1", "P2"});
	}
}
/*
 * Ensures that a type matching a ignore-if-better non-accessible rule is further found non-accessible
 * on another classpath entry.
 * (regression test for bug 98127 Access restrictions started showing up after switching to bundle)
 */
public void testIgnoreIfBetterNonAccessibleRule3() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/", "/P2", "-**/internal/Y"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P1");
		createFolder("/P1/p/internal");
		createFile(
			"/P1/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		createJavaProject("P2");
		createFolder("/P2/p/internal");
		createFile(
			"/P2/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.internal.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" +
			"	public class X extends p.internal.Y {\n" +
			"	                       ^^^^^^^^^^^^\n" +
			"Access restriction: The type Y is not accessible due to restriction on required project P1\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProjects(new String[] {"P1", "P2"});
	}
}
/*
 * Ensures that a type matching a ignore-if-better non-accessible rule is found non-accessible
 * if no other classpath entry matches it.
 * (regression test for bug 98127 Access restrictions started showing up after switching to bundle)
 */
public void testIgnoreIfBetterNonAccessibleRule4() throws CoreException {
	IClasspathEntry[] newEntries = createClasspath("Reconciler", new String[] {"/P1", "?**/internal/"});
	try {
		addClasspathEntries(newEntries, true);
		createJavaProject("P1");
		createFolder("/P1/p/internal");
		createFile(
			"/P1/p/internal/Y.java",
			"package p.internal;\n" +
			"public class Y {\n" +
			"}"
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X extends p.internal.Y {\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p1/X.java (at line 2)\n" +
			"	public class X extends p.internal.Y {\n" +
			"	                       ^^^^^^^^^^^^\n" +
			"Access restriction: The type Y is not accessible due to restriction on required project P1\n" +
			"----------\n"
		);
	} finally {
		removeClasspathEntries(newEntries);
		deleteProjects(new String[] {"P1"});
	}
}
/**
 * Introduces a syntax error in the modifiers of a method.
 */
public void testMethodWithError01() throws CoreException {
	// Introduce syntax error
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public.void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta after syntax error",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {MODIFIERS CHANGED}"
	);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" +
		"	public.void foo() {\n" +
		"	      ^\n" +
		"Syntax error on token \".\", delete this token\n" +
		"----------\n"
	);

	// Fix the syntax error
	clearDeltas();
	String contents =
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}";
	setWorkingCopyContents(contents);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta after fixing syntax error",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {MODIFIERS CHANGED}"
	);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. WARNING in /Reconciler/src/p1/X.java (at line 2)\n" +
		"	import p2.*;\n" +
		"	       ^^\n" +
		"The import p2 is never used\n" +
		"----------\n"
	);
}
/**
 * Test reconcile force flag
 */
public void testMethodWithError02() throws CoreException {
	String contents =
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public.void foo() {\n" +
		"  }\n" +
		"}";
	setWorkingCopyContents(contents);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

	// use force flag to refresh problems
	this.problemRequestor.initialize(contents.toCharArray());
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" +
		"	public.void foo() {\n" +
		"	      ^\n" +
		"Syntax error on token \".\", delete this token\n" +
		"----------\n"
	);
}

/**
 * Test reconcile force flag off
 */
public void testMethodWithError03() throws CoreException {
	String contents =
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public.void foo() {\n" +
		"  }\n" +
		"}";
	setWorkingCopyContents(contents);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

	// reconcile with force flag turned off
	this.problemRequestor.initialize(contents.toCharArray());
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertProblems(
		"Unexpected problems",
		""
	);
}
/**
 * Test reconcile force flag + cancel
 */
public void testMethodWithError04() throws CoreException {

	CancelingProblemRequestor myPbRequestor = new CancelingProblemRequestor();

	this.workingCopy.discardWorkingCopy();
	ICompilationUnit x = getCompilationUnit("Reconciler", "src", "p1", "X.java");
	this.problemRequestor = myPbRequestor;
	this.workingCopy = x.getWorkingCopy(this.wcOwner, null);

	String contents =
		"package p1;\n" +
		"public class X {\n" +
		"	Zork f;	\n"+
		"	void foo(Zork z){\n"+
		"	}\n"+
		"}	\n";
	setWorkingCopyContents(contents);

	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);

	// use force flag to refresh problems
	myPbRequestor.isCanceling = true;
	myPbRequestor.initialize(contents.toCharArray());
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, myPbRequestor.progressMonitor);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 3)\n" +
		"	Zork f;	\n" +
		"	^^^^\n" +
		"Zork cannot be resolved to a type\n" +
		"----------\n"
	);
}

/**
 * Test reconcile force flag off
 */
public void testMethodWithError05() throws CoreException {
	try {
		createFolder("/Reconciler/src/tests");
		String contents =
			"package tests;	\n"+
			"abstract class AbstractSearchableSource extends AbstractSource implements SearchableSource {	\n"+
			"	abstract int indexOfImpl(long value);	\n"+
			"	public final int indexOf(long value) {	\n"+
			"		return indexOfImpl(value);	\n"+
			"	}	\n"+
			"}	\n";
		createFile(
			"/Reconciler/src/tests/AbstractSearchableSource.java",
			contents);

		createFile(
			"/Reconciler/src/tests/Source.java",
			"package tests;	\n"+
			"interface Source {	\n"+
			"	long getValue(int index);	\n"+
			"	int size();	\n"+
			"}	\n");

		createFile(
			"/Reconciler/src/tests/AbstractSource.java",
			"package tests;	\n"+
			"abstract class AbstractSource implements Source {	\n"+
			"	AbstractSource() {	\n"+
			"	}	\n"+
			"	void invalidate() {	\n"+
			"	}	\n"+
			"	abstract long getValueImpl(int index);	\n"+
			"	abstract int sizeImpl();	\n"+
			"	public final long getValue(int index) {	\n"+
			"		return 0;	\n"+
			"	}	\n"+
			"	public final int size() {	\n"+
			"		return 0;	\n"+
			"	}	\n"+
			"}	\n");

		createFile(
			"/Reconciler/src/tests/SearchableSource.java",
			"package tests;	\n"+
			"interface SearchableSource extends Source {	\n"+
			"	int indexOf(long value);	\n"+
			"}	\n");

		ICompilationUnit compilationUnit = getCompilationUnit("Reconciler", "src", "tests", "AbstractSearchableSource.java");
		ProblemRequestor pbReq =  new ProblemRequestor();
		WorkingCopyOwner owner = newWorkingCopyOwner(pbReq);
		ICompilationUnit wc = compilationUnit.getWorkingCopy(owner, null);
		pbReq.initialize(contents.toCharArray());
		startDeltas();
		wc.reconcile(ICompilationUnit.NO_AST, true, null, null);
		String actual = pbReq.problems.toString();
		String expected =
			"----------\n" +
			"----------\n";
		if (!expected.equals(actual)){
		 	System.out.println(Util.displayString(actual, 2));
		}
		assertEquals(
			"unexpected errors",
			expected,
			actual);
	} finally {
		deleteFile("/Reconciler/src/tests/AbstractSearchableSource.java");
		deleteFile("/Reconciler/src/tests/SearchableSource.java");
		deleteFile("/Reconciler/src/tests/Source.java");
		deleteFile("/Reconciler/src/tests/AbstractSource.java");
		deleteFolder("/Reconciler/src/tests");
	}
}
/*
 * Test that the creation of a working copy detects errors
 * (regression test for bug 33757 Problem not detected when opening a working copy)
 */
public void testMethodWithError06() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	try {
		String contents =
			"package p1;\n" +
			"public class Y {\n" +
			"  public.void foo() {\n" +
			"  }\n" +
			"}";
		createFile(
			"/Reconciler/src/p1/Y.java",
			contents
		);
		this.problemRequestor =  new ProblemRequestor();
		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy = getCompilationUnit("Reconciler/src/p1/Y.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p1/Y.java (at line 3)\n" +
			"	public.void foo() {\n" +
			"	      ^\n" +
			"Syntax error on token \".\", delete this token\n" +
			"----------\n"
		);
	} finally {
		deleteFile("/Reconciler/src/p1/Y.java");
	}
}
/*
 * Test that the opening of a working copy detects errors
 * (regression test for bug 33757 Problem not detected when opening a working copy)
 */
public void testMethodWithError07() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	try {
		String contents =
			"package p1;\n" +
			"public class Y {\n" +
			"  public.void foo() {\n" +
			"  }\n" +
			"}";
		createFile(
			"/Reconciler/src/p1/Y.java",
			contents
		);
		this.problemRequestor =  new ProblemRequestor();
		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy = getCompilationUnit("Reconciler/src/p1/Y.java").getWorkingCopy(this.wcOwner, null);

		// Close working copy
		JavaModelManager.getJavaModelManager().removeInfoAndChildren((CompilationUnit)this.workingCopy); // use a back door as working copies cannot be closed

		// Reopen should detect syntax error
		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy.open(null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p1/Y.java (at line 3)\n" +
			"	public.void foo() {\n" +
			"	      ^\n" +
			"Syntax error on token \".\", delete this token\n" +
			"----------\n"
		);
	} finally {
		deleteFile("/Reconciler/src/p1/Y.java");
	}
}
/*
 * Test that the units with similar names aren't presenting each other errors
 * (regression test for bug 39475)
 */
public void testMethodWithError08() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	try {
		createFile(
			"/Reconciler/src/p1/X01.java",
			"package p1;\n" +
			"public abstract class X01 {\n" +
			"	public abstract void bar();	\n"+
			"  public abstract void foo(Zork z); \n"+
			"}"
		);
		String contents =
			"package p2;\n" +
			"public class X01 extends p1.X01 {\n" +
			"	public void bar(){}	\n"+
			"}";
		createFile(
			"/Reconciler/src/p2/X01.java",
			contents
		);
		this.problemRequestor =  new ProblemRequestor();
		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy = getCompilationUnit("Reconciler/src/p2/X01.java").getWorkingCopy(this.wcOwner, null);

		// Close working copy
		JavaModelManager.getJavaModelManager().removeInfoAndChildren((CompilationUnit)this.workingCopy); // use a back door as working copies cannot be closed

		// Reopen should detect syntax error
		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy.open(null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler/src/p2/X01.java (at line 2)\n" +
			"	public class X01 extends p1.X01 {\n" +
			"	             ^^^\n" +
			"The type X01 must implement the inherited abstract method X01.foo(Zork)\n" +
			"----------\n"
		);
	} finally {
		deleteFile("/Reconciler/src/p1/X01.java");
		deleteFile("/Reconciler/src/p2/X01.java");
	}
}
/*
 * Scenario of reconciling using a working copy owner
 */
public void testMethodWithError09() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		workingCopy1 = getCompilationUnit("/Reconciler/src/p1/X1.java").getWorkingCopy(this.wcOwner, null);
		workingCopy1.getBuffer().setContents(
			"package p1;\n" +
			"public abstract class X1 {\n" +
			"	public abstract void bar();	\n"+
			"}"
		);
		workingCopy1.makeConsistent(null);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler/src/p/X.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package p;\n" +
			"public class X extends p1.X1 {\n" +
			"	public void bar(){}	\n"+
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n" // shouldn't report problem against p.X
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
	}
}
/*
 * Scenario of reconciling using a working copy owner  (68557)
 */
public void testMethodWithError10() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		createFolder("/Reconciler15/src/test/cheetah");
		workingCopy1 = getCompilationUnit("/Reconciler15/src/test/cheetah/NestedGenerics.java").getWorkingCopy(this.wcOwner, null);
		workingCopy1.getBuffer().setContents(
			"package test.cheetah;\n"+
			"import java.util.List;\n"+
			"import java.util.Stack;\n"+
			"public class NestedGenerics {\n"+
			"    Stack< List<Object>> stack = new Stack< List<Object> >();\n"+
			"}\n"
		);
		workingCopy1.makeConsistent(null);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler15/src/test/cheetah/NestedGenericsTest.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package test.cheetah;\n"+
			"import java.util.Stack;\n"+
			"public class NestedGenericsTest {\n"+
			"    void test() {  \n"+
			"        Stack s = new NestedGenerics().stack;  \n"+
			"    }\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
		deleteFolder("/Reconciler15/src/test");
	}
}
/*
 * Scenario of reconciling using a working copy owner (68557)
 */
public void testMethodWithError11() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		createFolder("/Reconciler15/src/test/cheetah");
		workingCopy1 = getCompilationUnit("/Reconciler15/src/test/cheetah/NestedGenerics.java").getWorkingCopy(this.wcOwner, null);
		workingCopy1.getBuffer().setContents(
			"package test.cheetah;\n"+
			"import java.util.*;\n"+
			"public class NestedGenerics {\n"+
			"    Map<List<Object>,String> map = null;\n"+
			"    Stack<List<Object>> stack2 = null;\n"+
			"    Map<List<Object>,List<Object>> map3 = null;\n"+
			"}\n"
		);
		workingCopy1.makeConsistent(null);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler15/src/test/cheetah/NestedGenericsTest.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package test.cheetah;\n"+
			"import java.util.*;\n"+
			"public class NestedGenericsTest {\n"+
			"    void test() {  \n"+
			"        Map m = new NestedGenerics().map;  \n"+
			"		 Stack s2 = new NestedGenerics().stack2;    \n"+
			"        Map m3 = new NestedGenerics().map3;    \n"+
			"    }\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
		deleteFolder("/Reconciler15/src/test");
	}
}
/*
 * Scenario of reconciling using a working copy owner (68557 variation with wildcards)
 */
public void testMethodWithError12() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		createFolder("/Reconciler15/src/test/cheetah");
		workingCopy1 = getCompilationUnit("/Reconciler15/src/test/cheetah/NestedGenerics.java").getWorkingCopy(this.wcOwner, null);
		workingCopy1.getBuffer().setContents(
			"package test.cheetah;\n"+
			"import java.util.*;\n"+
			"public class NestedGenerics {\n"+
			"    Map<List<?>,? super String> map = null;\n"+
			"    Stack<List<? extends Object>> stack2 = null;\n"+
			"    Map<List<Object[]>,List<Object>[]> map3 = null;\n"+
			"}\n"
		);
		workingCopy1.makeConsistent(null);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler15/src/test/cheetah/NestedGenericsTest.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package test.cheetah;\n"+
			"import java.util.*;\n"+
			"public class NestedGenericsTest {\n"+
			"    void test() {  \n"+
			"        Map m = new NestedGenerics().map;  \n"+
			"		 Stack s2 = new NestedGenerics().stack2;    \n"+
			"        Map m3 = new NestedGenerics().map3;    \n"+
			"    }\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
		deleteFolder("/Reconciler15/src/test");
	}
}
/*
 * Scenario of reconciling using a working copy owner (68730)
 */
public void testMethodWithError13() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	this.problemRequestor =  null;
	try {
		workingCopy1 = getCompilationUnit("/Reconciler15/src/test/X.java").getWorkingCopy(this.wcOwner, null);
		createFolder("/Reconciler15/src/test");
		workingCopy1.getBuffer().setContents(
			"package test;\n"+
			"public class X <T extends String, U> {\n"+
			"	<Y1> void bar(Y1[] y) {}\n"+
			"	void bar2(Y<E3[]>[] ye[]) {}\n"+
			"    void foo(java.util.Map<Object[],String>.MapEntry<p.K<T>[],? super q.r.V8> m){}\n"+
			"    Class<? extends Object> getClass0() {}\n"+
			"    <E extends String> void pair (X<? extends E, U> e, T t){}\n"+
			"}\n"
		);
		workingCopy1.makeConsistent(null);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler15/src/test/Y.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package test;\n"+
			"public class Y {\n"+
			"	void foo(){\n"+
			"		X someX = new X();\n"+
			"		someX.bar(null);\n"+
			"	}\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
		"----------\n" +
		"1. WARNING in /Reconciler15/src/test/Y.java (at line 5)\n" +
		"	someX.bar(null);\n" +
		"	^^^^^^^^^^^^^^^\n" +
		"Type safety: The method bar(Object[]) belongs to the raw type X. References to generic type X<T,U> should be parameterized\n" +
		"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
		deleteFolder("/Reconciler15/src/test");
	}
}
/*
 * Scenario of reconciling using a working copy owner (66424)
 */
public void testMethodWithError14() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		workingCopy1 = getCompilationUnit("/Reconciler15/src/test/X.java").getWorkingCopy(this.wcOwner, null);
		createFolder("/Reconciler15/src/test");
		workingCopy1.getBuffer().setContents(
			"package test;\n"+
			"public class X <T> {\n"+
			"	<U> void bar(U u) {}\n"+
			"}\n"
		);
		workingCopy1.makeConsistent(null);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler15/src/test/Y.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package test;\n"+
			"public class Y {\n"+
			"	void foo(){\n"+
			"		X someX = new X();\n"+
			"		someX.bar();\n"+
			"	}\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler15/src/test/Y.java (at line 5)\n" +
			"	someX.bar();\n" +
			"	      ^^^\n" +
			"The method bar(Object) in the type X is not applicable for the arguments ()\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
		deleteFolder("/Reconciler15/src/test");
	}
}
/**
 * Ensures that the reconciler handles member move correctly.
 */
public void testMoveMember() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	clearDeltas();

	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}");
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	bar()[*]: {REORDERED}\n" +
		"	foo()[*]: {REORDERED}"
	);
}
/**
 * Ensures that the reconciler does nothing when the source
 * to reconcile with is the same as the current contents.
 */
public void testNoChanges1() throws JavaModelException {
	setWorkingCopyContents(this.workingCopy.getSource());
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
	);
}
/**
 * Ensures that the reconciler does nothing when the source
 * to reconcile with has the same structure as the current contents.
 */
public void testNoChanges2() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"    System.out.println()\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
	);
}
/*
 * Ensures that the problem requestor is not called when the source
 * to reconcile is the same as the current contents,
 * no ast is requested, no problem is requested and problem requestor is not active.
 * (regression test for bug 179258 simple reconcile starts problem finder - main thread waiting)
 *
 */
public void testNoChanges3() throws JavaModelException {
	setWorkingCopyContents(this.workingCopy.getSource());
	this.problemRequestor.isActive = false;
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertProblems("Unexpected problems", "");
}
/*
 * Ensures that using a non-generic method with no parameter and with a raw receiver type doesn't create a type safety warning
 * (regression test for bug 105756 [1.5][model] Incorrect warning on using raw types)
 */
public void testRawUsage() throws CoreException {
	ICompilationUnit otherCopy = null;
	try {
		otherCopy = getWorkingCopy(
			"Reconciler15/src/Generic105756.java",
			"public class Generic105756<T> {\n" +
			"  void foo() {}\n" +
			"}",
			this.wcOwner
		);
		setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner);
		setWorkingCopyContents(
			"public class X {\n" +
			"  void bar(Generic105756 g) {\n" +
			"    g.foo();\n" +
			"  }\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (otherCopy != null)
			otherCopy.discardWorkingCopy();
	}
}
/*
 * Ensures that a reconcile participant is notified when a working copy is reconciled.
 */
public void testReconcileParticipant01() throws CoreException {
	ReconcileParticipant participant = new ReconcileParticipant();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"    System.out.println()\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertDeltas(
		"Unexpected participant delta",
		"[Working copy] X.java[*]: {CHILDREN | FINE GRAINED}\n" +
		"	X[*]: {CHILDREN | FINE GRAINED}\n" +
		"		bar()[+]: {}\n" +
		"		foo()[-]: {}",
		participant.delta
	);
}
/*
 * Ensures that a reconcile participant is not notified if not participating.
 */
public void testReconcileParticipant02() throws CoreException {
	ReconcileParticipant participant = new ReconcileParticipant(){
		public boolean isActive(IJavaProject project) {
			return false;
		}
	};
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"    System.out.println()\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertDeltas(
		"Unexpected participant delta",
		"<null>",
		participant.delta
	);
}
/*
 * Ensures that a reconcile participant is notified with the correct AST.
 */
public void testReconcileParticipant03() throws CoreException {
	ReconcileParticipant participant = new ReconcileParticipant();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"    System.out.println()\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertASTNodeEquals(
		"Unexpected participant ast",
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar(){\n" +
		"  }\n" +
		"}\n",
		participant.ast
	);
}
/*
 * Ensures that the same AST as the one a reconcile participant requested is reported.
 */
public void testReconcileParticipant04() throws CoreException {
	ReconcileParticipant participant = new ReconcileParticipant();
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"    System.out.println()\n" +
		"  }\n" +
		"}"
	);
	org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(AST.JLS3, false, null, null);
	assertSame(
		"Unexpected participant ast",
		participant.ast,
		ast
	);
}
/*
 * Ensures that a participant can fix an error during reconcile.
 */
public void testReconcileParticipant05() throws CoreException {
	new ReconcileParticipant() {
		public void reconcile(ReconcileContext context) {
			try {
				setWorkingCopyContents(
					"package p1;\n" +
					"public class X {\n" +
					"  public void bar() {\n" +
					"  }\n" +
					"}"
				);
				context.resetAST();
			} catch (JavaModelException e) {
				e.printStackTrace();
			}
		}
	};
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"    toString()\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"----------\n"
	);
}
/*
 * Ensures that a participant can introduce an error during reconcile.
 */
public void testReconcileParticipant06() throws CoreException {
	new ReconcileParticipant() {
		public void reconcile(ReconcileContext context) {
			try {
				setWorkingCopyContents(
					"package p1;\n" +
					"public class X {\n" +
					"  public void bar() {\n" +
					"    toString()\n" +
					"  }\n" +
					"}"
				);
				context.resetAST();
			} catch (JavaModelException e) {
				e.printStackTrace();
			}
		}
	};
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" +
		"	toString()\n" +
		"	         ^\n" +
		"Syntax error, insert \";\" to complete BlockStatements\n" +
		"----------\n"
	);
}
/*
 * Ensures that a reconcile participant is NOT notified when a working copy is reconciled
 * in a project with insufficient source level.
 * (regression test for bug 125291 Enable conditional loading of APT)
 */
public void testReconcileParticipant07() throws CoreException {
	IJavaProject project = this.workingCopy.getJavaProject();
	String originalSourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
	try {
		project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_1);
		ReconcileParticipant participant = new ReconcileParticipant();
		setWorkingCopyContents(
			"package p1;\n" +
			"import p2.*;\n" +
			"public class X {\n" +
			"  public void bar() {\n" +
			"    System.out.println()\n" +
			"  }\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertDeltas(
			"Unexpected participant delta",
			"<null>",
			participant.delta
		);
	} finally {
		project.setOption(JavaCore.COMPILER_SOURCE, originalSourceLevel);
	}
}
/*
 * Ensures that a problem reporting session is not started during reconcile if a participant reports an error
 * and if the working copy is already consistent and the forceProblemDetection flag is false.
 * (regression test for bug 154170 Printing warnings breaks in-editor quick fixes)
 */
public void testReconcileParticipant08() throws CoreException {
	// set working copy contents and ensure it is consistent
	String contents =
		"package p1;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}";
	setWorkingCopyContents(contents);
	this.workingCopy.makeConsistent(null);
	this.problemRequestor.initialize(contents.toCharArray());

	// reconcile with a participant adding a list of problems
	new ReconcileParticipant() {
		public void reconcile(ReconcileContext context) {
			context.putProblems("test.marker", new CategorizedProblem[] {});
		}
	};
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertProblems(
		"Unexpected problems",
		""
	);
}
/*
 * Ensures that a reconcile participant is not notified when a working copy is reconciled
 * and it was consistent and forcing problem detection is off
 * (regression test for 177319 Annotation Processing (APT) affects eclipse speed)
 */
public void testReconcileParticipant09() throws CoreException {
	this.workingCopy.makeConsistent(null);
	new ReconcileParticipant() {
		public void reconcile(ReconcileContext context) {
			assertTrue("Participant should not be notified of a reconcile", false);
		}
	};
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false/*don't force problem detection*/, null, null);
}

/*
 * Ensures that a reconcile participant is notified when a working copy is reconciled
 * and it was consistent and forcing problem detection is on
 */
public void testReconcileParticipant10() throws CoreException {
	this.workingCopy.makeConsistent(null);
	final boolean[] participantReconciled = new boolean[1];
	new ReconcileParticipant() {
		public void reconcile(ReconcileContext context) {
			participantReconciled[0] = true;
		}
	};
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
	assertTrue(
		"Participant should have been notified",
		participantReconciled[0]
	);
}

/*
 * Ensures that the delta is still correct if a participant resets the ast during reconcile
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=210310)
 */
public void testReconcileParticipant11() throws CoreException {
	new ReconcileParticipant() {
		public void reconcile(ReconcileContext context) {
			context.resetAST();
		}
	};
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  private void foo() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(AST.JLS3, true/*force problem detection*/, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	foo()[*]: {MODIFIERS CHANGED}"
	);
}

/*
 * Ensures that a misbehaving reconcile participant doesn't interfere with a reconcile operation
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=248680 )
 */
public void testReconcileParticipant12() throws CoreException {
	try {
		TestCompilationParticipant.failToInstantiate = true;
		simulateExitRestart();
		this.workingCopy = getCompilationUnit("Reconciler/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		setWorkingCopyContents(
			"package p1;\n" +
			"import p2.*;\n" +
			"public class X {\n" +
			"  public void bar() {\n" +
			"    System.out.println()\n" +
			"  }\n" +
			"}"
		);
		startDeltas();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertWorkingCopyDeltas(
			"Unexpected participant delta",
			"X[*]: {CHILDREN | FINE GRAINED}\n" + 
			"	bar()[+]: {}\n" + 
			"	foo()[-]: {}"
		);
	} finally {
		stopDeltas();
		TestCompilationParticipant.failToInstantiate = false;
	}
}

	/*
 * Ensures that errors are fixed if renaming the .classpath file causes the missing type to be visible.
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=207890)
 */
public void testRenameClasspathFile() throws CoreException {
	ICompilationUnit copy = null;
	try {
		createJavaProject("P1");
		deleteFile("/P1/.classpath");
		createFile(
			"/P1/.classpath2",
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
			"<classpath>\n" +
			"    <classpathentry kind=\"src\" path=\"src1\"/>\n" +
			"	<classpathentry kind=\"var\" path=\"JCL_LIB\"/>\n" +
			"	<classpathentry kind=\"output\" path=\"bin\"/>\n" +
			"</classpath>"
		);
		createFolder("/P1/src1/p1");
		createFile(
			"/P1/src1/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin");
		createFolder("/P2/src/p2");
		copy = getWorkingCopy(
			"/P2/src/p2/Y.java",
			"package p2;\n" +
			"import p1.X;\n" +
			"public class Y extends X {\n" +
			"}",
			true/*compute problems*/
		);
		moveFile("/P1/.classpath2", "/P1/.classpath");
		this.problemRequestor.reset();
		copy.reconcile(ICompilationUnit.NO_AST, true/*for pb detection*/, null/*default owner*/, null/*no progress*/);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (copy != null)
			copy.discardWorkingCopy();
		deleteProject("P1");
		deleteProject("P2");
	}
}

/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents, updating the structure of this reconciler's compilation
 * unit, and fires the Java element deltas for the structural changes
 * of a renaming a method; the original method deleted and the new method added structurally.
 */
public void testRenameMethod1() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar() {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	bar()[+]: {}\n" +
		"	foo()[-]: {}"
	);
}
/**
 * Ensures that the reconciler reconciles the new contents with the current
 * contents,updating the structure of this reconciler's compilation
 * unit, and fires the Java element delta for the structural changes
 * of the addition of a portion of a new method.
 */
public void testRenameWithSyntaxError() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;\n" +
		"public class X {\n" +
		"  public void bar( {\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Unexpected delta",
		"X[*]: {CHILDREN | FINE GRAINED}\n" +
		"	bar()[+]: {}\n" +
		"	foo()[-]: {}"
	);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" +
		"	public void bar( {\n" +
		"	               ^\n" +
		"Syntax error, insert \")\" to complete MethodDeclaration\n" +
		"----------\n"
	);
}
/*
 * Ensure that warning are suppressed by an @SuppressWarnings annotation.
 */
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=95056
public void testSuppressWarnings1() throws JavaModelException {
	ICompilationUnit otherCopy = null;
	try {
		otherCopy = getWorkingCopy(
			"/Reconciler15/src/X.java",
	        "@Deprecated\n" +
	        "public class X {\n" +
	        "   void foo(){}\n" +
	        "}\n",
			this.wcOwner
		);
		setUp15WorkingCopy("/Reconciler15/src/Y.java", this.wcOwner);
		setWorkingCopyContents(
	        "public class Y extends X {\n" +
	        "  @SuppressWarnings(\"all\")\n" +
	        "   void foo(){ super.foo(); }\n" +
	        "   Zork z;\n" +
	        "}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. WARNING in /Reconciler15/src/Y.java (at line 1)\n" +
			"	public class Y extends X {\n" +
			"	                       ^\n" +
			"The type X is deprecated\n" +
			"----------\n" +
			"2. ERROR in /Reconciler15/src/Y.java (at line 4)\n" +
			"	Zork z;\n" +
			"	^^^^\n" +
			"Zork cannot be resolved to a type\n" +
			"----------\n");
	} finally {
		if (otherCopy != null)
			otherCopy.discardWorkingCopy();
	}
}
/*
 * Ensure that warning are suppressed by an @SuppressWarning annotation.
 */
public void testSuppressWarnings2() throws JavaModelException {
	ICompilationUnit otherCopy = null;
	try {
		otherCopy = getWorkingCopy(
			"/Reconciler15/src/java/util/List.java",
			"package java.util;\n" +
	        "public interface List<E> {\n" +
	        "}\n",
			this.wcOwner
		);
		setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner);
		setWorkingCopyContents(
            "import java.util.List;\n" +
            "\n" +
            "public class X {\n" +
            "    void foo(List list) {\n" +
            "        List<String> ls1 = list;\n" +
            "    }\n" +
            "    @SuppressWarnings(\"unchecked\")\n" +
            "    void bar(List list) {\n" +
            "        List<String> ls2 = list;\n" +
            "    }\n" +
            "   Zork z;\n" +
            "}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. WARNING in /Reconciler15/src/X.java (at line 5)\n" +
			"	List<String> ls1 = list;\n" +
			"	                   ^^^^\n" +
			"Type safety: The expression of type List needs unchecked conversion to conform to List<String>\n" +
			"----------\n" +
			"2. ERROR in /Reconciler15/src/X.java (at line 11)\n" +
			"	Zork z;\n" +
			"	^^^^\n" +
			"Zork cannot be resolved to a type\n" +
			"----------\n"
		);
	} finally {
		if (otherCopy != null)
			otherCopy.discardWorkingCopy();
	}
}
/*
 * Ensure that warning are suppressed by an @SuppressWarning annotation.
 */
public void testSuppressWarnings3() throws JavaModelException {
	ICompilationUnit otherCopy = null;
	try {
		otherCopy = getWorkingCopy(
			"/Reconciler15/src/java/util/HashMap.java",
			"package java.util;\n" +
	        "public class HashMap implements Map {\n" +
	        "}\n",
			this.wcOwner
		);
		setUp15WorkingCopy("/Reconciler15/src/X.java", this.wcOwner);
		setWorkingCopyContents(
			"import java.util.*;\n" +
			"@SuppressWarnings(\"unchecked\")\n" +
			"public class X {\n" +
			"	void foo() {\n" +
			"		Map<String, String>[] map = new HashMap[10];\n" +
			"	}\n" +
            "   Zork z;\n" +
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. ERROR in /Reconciler15/src/X.java (at line 7)\n" +
			"	Zork z;\n" +
			"	^^^^\n" +
			"Zork cannot be resolved to a type\n" +
			"----------\n"
		);
	} finally {
		if (otherCopy != null)
			otherCopy.discardWorkingCopy();
	}
}
/*
 * Ensure that warning are suppressed by an @SuppressWarnings annotation.
 */
public void testSuppressWarnings4() throws JavaModelException {
	ICompilationUnit otherCopy = null;
	try {
		otherCopy = getWorkingCopy(
			"/Reconciler15/src/X.java",
	        "/** @deprecated */\n" +
	        "public class X {\n" +
	        "   void foo(){}\n" +
	        "}\n",
			this.wcOwner
		);
		setUp15WorkingCopy("/Reconciler15/src/Y.java", this.wcOwner);
		setWorkingCopyContents(
	        "public class Y extends X {\n" +
	        "  @SuppressWarnings(\"all\")\n" +
	        "   void foo(){ super.foo(); }\n" +
	        "   Zork z;\n" +
	        "}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"1. WARNING in /Reconciler15/src/Y.java (at line 1)\n" +
			"	public class Y extends X {\n" +
			"	                       ^\n" +
			"The type X is deprecated\n" +
			"----------\n" +
			"2. ERROR in /Reconciler15/src/Y.java (at line 4)\n" +
			"	Zork z;\n" +
			"	^^^^\n" +
			"Zork cannot be resolved to a type\n" +
			"----------\n");
	} finally {
		if (otherCopy != null)
			otherCopy.discardWorkingCopy();
	}
}
/**
 * Ensure that an unhandled exception is detected.
 */
public void testUnhandledException() throws JavaModelException {
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"    throw new Exception();\n" +
		"  }\n" +
		"}"
	);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"1. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" +
		"	throw new Exception();\n" +
		"	^^^^^^^^^^^^^^^^^^^^^^\n" +
		"Unhandled exception type Exception\n" +
		"----------\n"
	);
}
/**
 * Check that forcing a make consistent action is leading the next reconcile to not notice changes.
 */
public void testMakeConsistentFoolingReconciler() throws JavaModelException {
	setWorkingCopyContents("");
	this.workingCopy.makeConsistent(null);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
	assertWorkingCopyDeltas(
		"Should have got NO delta",
		""
	);
}
/**
 * Test bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=60689
 * AST on reconcile: AST without Javadoc comments created
 * @deprecated using deprecated code
 */
public void testBug60689() throws JavaModelException {
	setWorkingCopyContents("public class X {\n" +
		"	/**\n" +
		"	 * Returns the length of the string representing the number of \n" +
		"	 * indents in the given string <code>line</code>. Returns \n" +
		"	 * <code>-1<code> if the line isn't prefixed with an indent of\n" +
		"	 * the given number of indents. \n" +
		"	 */\n" +
		"	public static int computeIndentLength(String line, int numberOfIndents, int tabWidth) {\n" +
		"		return 0;\n" +
		"}"
	);
	org.eclipse.jdt.core.dom.CompilationUnit testCU = this.workingCopy.reconcile(AST.JLS2, true, null, null);
	assertNotNull("We should have a comment!", testCU.getCommentList());
	assertEquals("We should have 1 comment!", 1, testCU.getCommentList().size());
	testCU = this.workingCopy.reconcile(AST.JLS2, true, null, null);
	assertNotNull("We should have a comment!", testCU.getCommentList());
	assertEquals("We should have one comment!", 1, testCU.getCommentList().size());
}
/*
 * Ensures that a working copy in a 1.4 project that references a 1.5 project can be reconciled without error.
 * (regression test for bug 98434 A non-1.5 project with 1.5 projects in the classpath does not show methods with generics)
 */
public void testTwoProjectsWithDifferentCompliances() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	try {
		createJavaProject("P1", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5");
		createFolder("/P1/p");
		createFile(
			"/P1/p/X.java",
			"package p;\n" +
			"public class X {\n" +
			"  void foo(Class<String> c) {\n" +
			"  }\n" +
			"}"
		);

		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "", "1.4");
		createFolder("/P2/p");
		this.workingCopy = getWorkingCopy("/P2/p/Y.java", "", this.wcOwner);
		setWorkingCopyContents(
			"package p;\n" +
			"public class Y {\n" +
			"  void bar(Class c) {\n" +
			"    new X().foo(c);\n" +
			"  }\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force pb detection*/, this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteProjects(new String[] {"P1", "P2"});
	}
}
/*
 * Ensures that a method that has a type parameter with bound can be overriden in another working copy.
 * (regression test for bug 76780 [model] return type not recognized correctly on some generic methods)
 */
public void testTypeParameterWithBound() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		workingCopy1 = getWorkingCopy(
			"/Reconciler15/src/test/I.java",
			"package test;\n"+
			"public interface I {\n"+
			"	<T extends I> void foo(T t);\n"+
			"}\n",
			this.wcOwner
		);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getWorkingCopy("Reconciler15/src/test/X.java", "", this.wcOwner);
		setWorkingCopyContents(
			"package test;\n"+
			"public class X implements I {\n"+
			"	public <T extends I> void foo(T t) {\n"+
			"	}\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
	}
}
/*
 * Ensures that a method that has a type parameter starting with $ can be reconciled against.
 * (regression test for bug 91709 [1.5][model] Quick Fix Error but no Problem Reported)
 */
public void testTypeParameterStartingWithDollar() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		workingCopy1 = getWorkingCopy(
			"/Reconciler15/src/test/Y.java",
			"package test;\n"+
			"public class Y<$T> {\n"+
			"	void foo($T t);\n"+
			"}\n",
			this.wcOwner
		);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getWorkingCopy("Reconciler15/src/test/X.java", "", this.wcOwner);
		setWorkingCopyContents(
			"package test;\n"+
			"public class X {\n"+
			"	public void bar() {\n"+
			"    new Y<String>().foo(\"\");\n" +
			"	}\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
	}
}
/*
 * Ensures that a working copy with a type with a dollar name can be reconciled without errors.
 * (regression test for bug 117121 Can't create class called A$B in eclipse)
 */
public void testTypeWithDollarName() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	try {
		String contents =
			"package p1;\n" +
			"public class Y$Z {\n" +
			"}";
		createFile(
			"/Reconciler/src/p1/Y$Z.java",
			contents
		);
		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getCompilationUnit("Reconciler/src/p1/Y$Z.java").getWorkingCopy(this.wcOwner, null);

		this.problemRequestor.initialize(contents.toCharArray());
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		deleteFile("/Reconciler/src/p1/Y$Z.java");
	}
}
/*
 * Ensures that a working copy with a type with a dollar name can be reconciled against without errors.
 * (regression test for bug 125301 Handling of classes with $ in class name.)
 */
public void testTypeWithDollarName2() throws CoreException {
	ICompilationUnit workingCopy2 = null;
	try {
		WorkingCopyOwner owner = this.workingCopy.getOwner();
		workingCopy2 = getWorkingCopy(
			"/Reconciler/src/p1/Y$Z.java",
			"package p1;\n" +
			"public class Y$Z {\n" +
			"}",
			owner
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X {\n" +
			"  Y$Z field;\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, owner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy2 != null)
			workingCopy2.discardWorkingCopy();
	}
}
/*
 * Ensures that a working copy with a type with a dollar name can be reconciled against without errors.
 * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=232803 )
 */
public void testTypeWithDollarName3() throws CoreException {
	ICompilationUnit workingCopy2 = null;
	try {
		WorkingCopyOwner owner = this.workingCopy.getOwner();
		workingCopy2 = getWorkingCopy(
			"/Reconciler/src/p1/Cl$ss.java",
			"package p1;\n" +
			"public interface Cl$ss {\n" +
			"        public void test(Cl$ss c);\n" +
			"        public void foo();\n" +
			"}",
			owner
		);
		setWorkingCopyContents(
			"package p1;\n" +
			"public class X {\n" +
			"        void m(Cl$ss c2) {\n" +
			"                c2.test(c2);\n" +
			"                c2.foo();\n" +
			"        }\n" +
			"}"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, owner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy2 != null)
			workingCopy2.discardWorkingCopy();
	}
}
/*
 * Ensures that a varargs method can be referenced from another working copy.
 */
public void testVarargs() throws CoreException {
	this.workingCopy.discardWorkingCopy(); // don't use the one created in setUp()
	this.workingCopy = null;
	ICompilationUnit workingCopy1 = null;
	try {
		workingCopy1 = getWorkingCopy(
			"/Reconciler15/src/test/X.java",
			"package test;\n"+
			"public class X {\n"+
			"	void bar(String ... args) {}\n"+
			"}\n",
			this.wcOwner
		);

		this.problemRequestor =  new ProblemRequestor();
		this.workingCopy = getWorkingCopy("Reconciler15/src/test/Y.java", "", this.wcOwner);
		setWorkingCopyContents(
			"package test;\n"+
			"public class Y {\n"+
			"	void foo(){\n"+
			"		X someX = new X();\n"+
			"		someX.bar(\"a\", \"b\");\n"+
			"	}\n"+
			"}\n"
		);
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, this.wcOwner, null);

		assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
		);
	} finally {
		if (workingCopy1 != null) {
			workingCopy1.discardWorkingCopy();
		}
	}
}

/**
 * Bug 114338:[javadoc] Reconciler reports wrong javadoc warning (missing return type)
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=114338"
 *
 */
public void testBug114338() throws CoreException {
	// Set initial CU content
	setWorkingCopyContents(
		"package p1;\n" +
		"public class X {\n" +
		"	/**\n" +
		"	 * @return a\n" +
		"	 */\n" +
		"	boolean get() {\n" +
		"		return false;\n" +
		"	}\n" +
		"}");
	this.workingCopy.reconcile(AST.JLS3, true, this.wcOwner, null);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"----------\n"
	);

	// Modify content
	String contents =
		"package p1;\n" +
		"public class X {\n" +
		"	/**\n" +
		"	 * @return boolean\n" +
		"	 */\n" +
		"	boolean get() {\n" +
		"		return false;\n" +
		"	}\n" +
		"}";
	setWorkingCopyContents(contents);
	this.workingCopy.reconcile(AST.JLS3, true, this.wcOwner, null);
	assertProblems(
		"Unexpected problems",
		"----------\n" +
		"----------\n"
	);
}

/**
 * Bug 36032:[plan] JavaProject.findType() fails to find second type in source file
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=36032"
 */
public void testBug36032a() throws CoreException, InterruptedException {
	try {
		// Resources creation
		createJavaProject("P", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		String source =
			"public class Test {\n" +
			"	public static void main(String[] args) {\n" +
			"		new SFoo().foo();\n" +
			"	}\n" +
			"}\n";
		this.createFile(
			"/P/Foo.java",
			"class SFoo { void foo() {} }\n"
		);
		this.createFile(
			"/P/Test.java",
			source
		);

		// Get compilation unit and reconcile it
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopy = getCompilationUnit("/P/Test.java").getWorkingCopy(this.wcOwner, null);
		this.workingCopy.getBuffer().setContents(source);
		this.workingCopy.reconcile(AST.JLS3, true, null, null);
		assertNoProblem(sourceChars, this.workingCopy);

		// Add new secondary type
		this.createFile(
			"/P/Bar.java",
			"class SBar{ void bar() {} }\n"
		);
		source =
			"public class Test {\n" +
			"	public static void main(String[] args) {\n" +
			"		new SFoo().foo();\n" +
			"		new SBar().bar();\n" +
			"	}\n" +
			"}\n";

		// Reconcile with modified source
		sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopy.getBuffer().setContents(source);
		this.workingCopy.reconcile(AST.JLS3, true, null, null);
		assertNoProblem(sourceChars, this.workingCopy);
	} finally {
		deleteProject("P");
	}
}
public void testBug36032b() throws CoreException, InterruptedException {
	try {
		// Resources creation
		createJavaProject("P", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		String source =
			"public class Test {\n" +
			"	public static void main(String[] args) {\n" +
			"		new SFoo().foo();\n" +
			"		new SBar().bar();\n" +
			"	}\n" +
			"}\n";
		createFile(
			"/P/Foo.java",
			"class SFoo { void foo() {} }\n"
		);
		createFile(
			"/P/Test.java",
			source
		);
		createFile(
			"/P/Bar.java",
			"class SBar{ void bar() {} }\n"
		);

		// Get compilation unit and reconcile it
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopy = getCompilationUnit("/P/Test.java").getWorkingCopy(this.wcOwner, null);
		this.workingCopy.getBuffer().setContents(source);
		this.workingCopy.reconcile(AST.JLS3, true, null, null);
		assertNoProblem(sourceChars, this.workingCopy);

		// Delete secondary type => should get a problem
		waitUntilIndexesReady();
		deleteFile("/P/Bar.java");
		this.problemRequestor.initialize(source.toCharArray());
		this.workingCopy.reconcile(AST.JLS3, true, null, null);
		assertEquals("Working copy should not find secondary type 'Bar'!", 1, this.problemRequestor.problemCount);
		assertProblems("Working copy should have problem!",
			"----------\n" +
			"1. ERROR in /P/Test.java (at line 4)\n" +
			"	new SBar().bar();\n" +
			"	    ^^^^\n" +
			"SBar cannot be resolved to a type\n" +
			"----------\n"
		);

		// Fix the problem
		source =
			"public class Test {\n" +
			"	public static void main(String[] args) {\n" +
			"		new SFoo().foo();\n" +
			"	}\n" +
			"}\n";
		sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopy.getBuffer().setContents(source);
		this.workingCopy.reconcile(AST.JLS3, true, null, null);
		assertNoProblem(sourceChars, this.workingCopy);
	} finally {
		deleteProject("P");
	}
}
// Secondary types used through multiple projects
public void testBug36032c() throws CoreException, InterruptedException {
	try {
		// Create first project
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		createFolder("/P1/test");
		createFile(
			"/P1/test/Foo.java",
			"package test;\n" +
			"class Secondary{ void foo() {} }\n"
		);
		createFile(
			"/P1/test/Test1.java",
			"package test;\n" +
			"public class Test1 {\n" +
			"	public static void main(String[] args) {\n" +
			"		new Secondary().foo();\n" +
			"	}\n" +
			"}\n"
		);

		// Create second project
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin");
		String source =
			"package test;\n" +
			"public class Test2 {\n" +
			"	public static void main(String[] args) {\n" +
			"		new Secondary().foo();\n" +
			"	}\n" +
			"}\n";
		createFolder("/P2/test");
		createFile(
			"/P2/test/Test2.java",
			source
		);

		// Get compilation unit and reconcile it => expect no error
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopy = getCompilationUnit("/P2/test/Test2.java").getWorkingCopy(this.wcOwner, null);
		this.workingCopy.getBuffer().setContents(source);
		this.workingCopy.reconcile(AST.JLS3, true, null, null);
		assertNoProblem(sourceChars, this.workingCopy);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
/**
 * Bug 118823: [model] Secondary types cache not reset while removing _all_ secondary types from CU
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=118823"
 */
public void testBug118823() throws CoreException, InterruptedException, IOException {
	try {
		// Resources creation
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		String source = "class Test {}\n";
		createFile(
			"/P1/Test.java",
			source
		);
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin");
		String source2 =
			"class A {\n" +
			"	Secondary s;\n" +
			"}\n";
		createFile(
			"/P2/A.java",
			source2
		);
		waitUntilIndexesReady();
		this.workingCopies = new ICompilationUnit[2];

		// Get first working copy and verify that there's no error
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/P1/Test.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourceChars, this.workingCopies[0]);

		// Get second working copy and verify that there's one error (missing secondary type)
		this.problemRequestor.initialize(source2.toCharArray());
		this.workingCopies[1] = getCompilationUnit("/P2/A.java").getWorkingCopy(this.wcOwner, null);
		assertEquals("Working copy should not find secondary type 'Secondary'!", 1, this.problemRequestor.problemCount);
		assertProblems("Working copy should have problem!",
			"----------\n" +
			"1. ERROR in /P2/A.java (at line 2)\n" +
			"	Secondary s;\n" +
			"	^^^^^^^^^\n" +
			"Secondary cannot be resolved to a type\n" +
			"----------\n"
		);

		// Delete file and recreate it with secondary
		final String source1 =
			"public class Test {}\n" +
			"class Secondary{}\n";
		getWorkspace().run(
			new IWorkspaceRunnable() {
				public void run(IProgressMonitor monitor) throws CoreException {
					deleteFile("/P1/Test.java");
					createFile(
						"/P1/Test.java",
						source1
					);
				}
			},
			null
		);

		// Get first working copy and verify that there's still no error
		sourceChars = source1.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0].getBuffer().setContents(source1);
		this.workingCopies[0].reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		assertNoProblem(sourceChars, this.workingCopies[0]);

		// Get second working copy and verify that there's any longer error
		sourceChars = source2.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[1].getBuffer().setContents(source2);
		this.workingCopies[1].reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		assertNoProblem(sourceChars, this.workingCopies[1]);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
public void testBug118823b() throws CoreException, InterruptedException {
	try {
		// Resources creation
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		String source1 = "class Test {}\n";
		createFile(
			"/P1/Test.java",
			source1
		);
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin");
		String source2 =
			"class A {\n" +
			"	Secondary s;\n" +
			"}\n";
		createFile(
			"/P2/A.java",
			source2
		);
		waitUntilIndexesReady();
		this.workingCopies = new ICompilationUnit[2];

		// Get first working copy and verify that there's no error
		char[] sourceChars = source1.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/P1/Test.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourceChars, this.workingCopies[0]);

		// Get second working copy and verify that there's one error (missing secondary type)
		this.problemRequestor.initialize(source2.toCharArray());
		this.workingCopies[1] = getCompilationUnit("/P2/A.java").getWorkingCopy(this.wcOwner, null);
		assertEquals("Working copy should not find secondary type 'Secondary'!", 1, this.problemRequestor.problemCount);
		assertProblems("Working copy should have problem!",
			"----------\n" +
			"1. ERROR in /P2/A.java (at line 2)\n" +
			"	Secondary s;\n" +
			"	^^^^^^^^^\n" +
			"Secondary cannot be resolved to a type\n" +
			"----------\n"
		);

		// Modify first working copy and verify that there's still no error
		source1 =
			"public class Test {}\n" +
			"class Secondary{}\n";
		sourceChars = source1.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0].getBuffer().setContents(source1);
		this.workingCopies[0].reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		this.workingCopies[0].commitWorkingCopy(true, null);
		assertNoProblem(sourceChars, this.workingCopies[0]);

		// Get second working copy and verify that there's any longer error
		sourceChars = source2.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[1].getBuffer().setContents(source2);
		this.workingCopies[1].reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		assertNoProblem(sourceChars, this.workingCopies[1]);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
public void testBug118823c() throws CoreException, InterruptedException {
	try {
		// Resources creation
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		String source1 = "class Test {}\n";
		createFile(
			"/P1/Test.java",
			source1
		);
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin");
		String source2 =
			"class A {\n" +
			"	Secondary s;\n" +
			"}\n";
		createFile(
			"/P2/A.java",
			source2
		);
		waitUntilIndexesReady();
		this.workingCopies = new ICompilationUnit[2];

		// Get first working copy and verify that there's no error
		char[] sourceChars = source1.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/P1/Test.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourceChars, this.workingCopies[0]);

		// Get second working copy and verify that there's one error (missing secondary type)
		this.problemRequestor.initialize(source2.toCharArray());
		this.workingCopies[1] = getCompilationUnit("/P2/A.java").getWorkingCopy(this.wcOwner, null);
		assertEquals("Working copy should not find secondary type 'Secondary'!", 1, this.problemRequestor.problemCount);
		assertProblems("Working copy should have problem!",
			"----------\n" +
			"1. ERROR in /P2/A.java (at line 2)\n" +
			"	Secondary s;\n" +
			"	^^^^^^^^^\n" +
			"Secondary cannot be resolved to a type\n" +
			"----------\n"
		);

		// Delete file and recreate it with secondary
		deleteFile("/P1/Test.java");
		source1 =
			"public class Test {}\n" +
			"class Secondary{}\n";
		createFile(
			"/P1/Test.java",
			source1
		);

		// Get first working copy and verify that there's still no error
		sourceChars = source1.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0].getBuffer().setContents(source1);
		this.workingCopies[0].reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		this.workingCopies[0].commitWorkingCopy(true, null);
		assertNoProblem(sourceChars, this.workingCopies[0]);

		// Get second working copy and verify that there's any longer error
		sourceChars = source2.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[1].getBuffer().setContents(source2);
		this.workingCopies[1].reconcile(AST.JLS3,
			true, // force problem detection to see errors if any
			null,	// do not use working copy owner to not use working copies in name lookup
			null);
		assertNoProblem(sourceChars, this.workingCopies[1]);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=107931
// won't be fixed; this test watches the current behavior in case we change
// our mind
public void test1001() throws CoreException, InterruptedException, IOException {
	try {
		// Resources creation
		String sources[] = new String[3];
		char[] sourcesAsCharArrays[] = new char[3][];
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		sources[0] = "class X {}\n";
		createFile(
			"/P1/X.java",
			sources[0]
		);
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin");
		sources[1] =
			"interface I {\n" +
			"  void foo();\n" +
			"  void bar(X p);\n" +
			"}\n";
		createFile(
			"/P2/I.java",
			sources[1]
		);
		createJavaProject("P3", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P2" }, "bin");
		sources[2] =
			"class Y implements I {\n" +
			"  // public void foo() { }\n" +
			"  // public void bar(X p) { }\n" +
			"}\n";
		createFile(
			"/P3/Y.java",
			sources[2]
		);
		for (int i = 0 ; i < sources.length ; i++) {
			sourcesAsCharArrays[i] = sources[i].toCharArray();
		}
		waitUntilIndexesReady();
		this.workingCopies = new ICompilationUnit[3];

		// Get first working copy and verify that there's no error
		this.problemRequestor.initialize(sourcesAsCharArrays[0]);
		this.workingCopies[0] = getCompilationUnit("/P1/X.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourcesAsCharArrays[0], this.workingCopies[0]);

		// Get second working copy and verify that there's no error
		this.problemRequestor.initialize(sourcesAsCharArrays[1]);
		this.workingCopies[1] = getCompilationUnit("/P2/I.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourcesAsCharArrays[1], this.workingCopies[1]);

		// Get third working copy and verify that all expected errors are here
		this.problemRequestor.initialize(sourcesAsCharArrays[2]);
		this.workingCopies[2] = getCompilationUnit("/P3/Y.java").getWorkingCopy(this.wcOwner, null);
		assertProblems("Working copy should have problems:",
				"----------\n" +
				"1. ERROR in /P3/Y.java (at line 1)\n" +
				"	class Y implements I {\n" +
				"	      ^\n" +
				"The type Y must implement the inherited abstract method I.bar(X)\n" +
				"----------\n" +
				"2. ERROR in /P3/Y.java (at line 1)\n" +
				"	class Y implements I {\n" +
				"	      ^\n" +
				"The type Y must implement the inherited abstract method I.foo()\n" +
				"----------\n");
	} finally {
		deleteProject("P1");
		deleteProject("P2");
		deleteProject("P3");
	}
}

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=107931
// variant: having all needed projects on the classpath solves the issue
public void test1002() throws CoreException, InterruptedException, IOException {
	try {
		// Resources creation
		String sources[] = new String[3];
		char[] sourcesAsCharArrays[] = new char[3][];
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		sources[0] = "class X {}\n";
		createFile(
			"/P1/X.java",
			sources[0]
		);
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" }, "bin");
		sources[1] =
			"interface I {\n" +
			"  void foo();\n" +
			"  void bar(X p);\n" +
			"}\n";
		createFile(
			"/P2/I.java",
			sources[1]
		);
		createJavaProject("P3", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P1" /* compare with test1001 */, "/P2" }, "bin");
		sources[2] =
			"class Y implements I {\n" +
			"  // public void foo() { }\n" +
			"  // public void bar(X p) { }\n" +
			"}\n";
		createFile(
			"/P3/Y.java",
			sources[2]
		);
		for (int i = 0 ; i < sources.length ; i++) {
			sourcesAsCharArrays[i] = sources[i].toCharArray();
		}
		waitUntilIndexesReady();
		this.workingCopies = new ICompilationUnit[3];

		// Get first working copy and verify that there's no error
		this.problemRequestor.initialize(sourcesAsCharArrays[0]);
		this.workingCopies[0] = getCompilationUnit("/P1/X.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourcesAsCharArrays[0], this.workingCopies[0]);

		// Get second working copy and verify that there's no error
		this.problemRequestor.initialize(sourcesAsCharArrays[1]);
		this.workingCopies[1] = getCompilationUnit("/P2/I.java").getWorkingCopy(this.wcOwner, null);
		assertNoProblem(sourcesAsCharArrays[1], this.workingCopies[1]);

		// Get third working copy and verify that all expected errors are here
		this.problemRequestor.initialize(sourcesAsCharArrays[2]);
		this.workingCopies[2] = getCompilationUnit("/P3/Y.java").getWorkingCopy(this.wcOwner, null);
		assertProblems("Working copy should have problems:",
			"----------\n" +
			"1. ERROR in /P3/Y.java (at line 1)\n" +
			"	class Y implements I {\n" +
			"	      ^\n" +
			"The type Y must implement the inherited abstract method I.bar(X)\n" +
			"----------\n" +
			"2. ERROR in /P3/Y.java (at line 1)\n" +
			"	class Y implements I {\n" +
			"	      ^\n" +
			"The type Y must implement the inherited abstract method I.foo()\n" +
			"----------\n"
		);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
		deleteProject("P3");
	}
}
/*
 * Ensure that fallthrough diagnostics are silenced by $FALL-THROUGH$ comments
 */
public void testFallthroughDiagnosis() throws CoreException, InterruptedException {
	try {
		// Resources creation
		IJavaProject p1 = createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, "bin");
		p1.setOption(JavaCore.COMPILER_PB_FALLTHROUGH_CASE, JavaCore.ERROR);
		String source = 
			"public class X {\n" + 
			"	void foo(int i) {\n" + 
			"		switch(i) {\n" + 
			"		case 0:\n" + 
			"			i ++;\n" + 
			"			// $FALL-THROUGH$\n" + 
			"		case 1:\n" + 
			"			i++;\n" + 
			"			/* $FALL-THROUGH$ */\n" + 
			"		case 2:\n" + 
			"			i++;\n" + 
			"		case 3:\n" + 
			"		}\n" + 
			"	}\n" + 
			"}\n";
			
		createFile("/P1/X.java", source);
		this.workingCopies = new ICompilationUnit[1];

		// Get first working copy and verify that there's no error
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/P1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems("Working copy should have problems:",
				"----------\n" + 
				"1. ERROR in /P1/X.java (at line 12)\n" + 
				"	case 3:\n" + 
				"	^^^^^^\n" + 
				"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" + 
				"----------\n"
		);
	} finally {
		deleteProject("P1");
	}
}
/*
 * Ensure that the option ICompilationUnit.IGNORE_METHOD_BODIES is honored
 */
public void testIgnoreMethodBodies1() throws CoreException {	
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;" +
		"public class X {\n" +
		"  public int foo() {\n" + // force an error by not returning
		"    int i = 0;\n" + 
		"  }\n" +
		"}");
	org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(AST.JLS3, ICompilationUnit.IGNORE_METHOD_BODIES, null, null);
	// X.foo() not returning any value should not be reported
	assertProblems("Working copy should have problems:",
			"----------\n" +
			"1. WARNING in /Reconciler/src/p1/X.java (at line 2)\n"+
			"	import p2.*;public class X {\n" +
			"	       ^^\n" +
			"The import p2 is never used\n"+
			"----------\n"
		);
	// statement declaring i should not be in the AST
	assertASTNodeEquals(
			"Unexpected participant ast",
			"package p1;\n" +
			"import p2.*;\n" +
			"public class X {\n" +
			"  public int foo(){\n" +
			"  }\n" +
			"}\n",
			ast
		);
}
public void testIgnoreMethodBodies2() throws CoreException {	
	setWorkingCopyContents(
		"package p1;\n" +
		"import p2.*;" +
		"public class X {\n" +
		"  public void foo() {\n" +
		"    int i = 0;\n" + 
		"  }\n" +
		"  public int bar() {\n" +
		"    int i = 0;\n" + 
		"    new X() /*start*/{\n" +
		"    }/*end*/;" +
		"  }\n" +
		"}");
	org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(AST.JLS3, ICompilationUnit.IGNORE_METHOD_BODIES, null, null);
	// methods with anonymous classes should have their statements intact
	assertASTNodeEquals(
			"Unexpected ast",
			"package p1;\n" +
			"import p2.*;\n" +
			"public class X {\n" +
			"  public void foo(){\n" +
			"  }\n" +
			"  public int bar(){\n" +
			"  }\n" +
			"}\n",
			ast
		);
}
}
