/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Technical University Berlin - adapted for Object Teams
 *     Stephan Herrmann - contribution for
 *								bug 401035 - [1.8] A few tests have started failing recently
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;


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

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.FileLocator;
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.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.osgi.framework.Bundle;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ReconcilerTests extends ModifyingResourceTests {

	protected ICompilationUnit workingCopy;
	protected ProblemRequestor problemRequestor;

	/* A problem requestor that auto-cancels on first problem */
	static 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);
		}
	}
	
	/*package*/ static final int JLS_LATEST = AST.JLS13;

	static class ReconcileParticipant extends CompilationParticipant {
		IJavaElementDelta delta;
		org.eclipse.jdt.core.dom.CompilationUnit ast;
		ReconcileParticipant() {
			TestCompilationParticipant.PARTICIPANT = this;
		}
		public boolean isActive(IJavaProject project) {
			return true;
		}
		/**
		 * @deprecated
		 */
		public void reconcile(ReconcileContext context) {
			this.delta = context.getDelta();
			try {
				this.ast = context.getAST(JLS_LATEST);
			} catch (JavaModelException e) {
				assertNull("Unexpected exception", e);
			}
		}
	}

	static class ReconcileParticipant2 extends CompilationParticipant {
		IJavaElementDelta delta;
		org.eclipse.jdt.core.dom.CompilationUnit ast;
		ReconcileParticipant2() {
			TestCompilationParticipant.PARTICIPANT = this;
		}
		public boolean isActive(IJavaProject project) {
			return true;
		}
		/**
		 * @deprecated
		 */
		public void reconcile(ReconcileContext context) {
			this.delta = context.getDelta();
			try {
				this.ast = context.getAST(JLS_LATEST);
				assertTrue("Context should have statement recovery enabled", (context.getReconcileFlags() & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
				assertTrue("Context should have ignore method body enabled", (context.getReconcileFlags() & ICompilationUnit.IGNORE_METHOD_BODIES) != 0);
			} catch (JavaModelException e) {
				assertNull("Unexpected exception", e);
			}
		}
	}

	static class ReconcileParticipant3 extends CompilationParticipant {
		IJavaElementDelta delta;
		org.eclipse.jdt.core.dom.CompilationUnit ast;
		ReconcileParticipant3() {
			TestCompilationParticipant.PARTICIPANT = this;
		}
		public boolean isActive(IJavaProject project) {
			return true;
		}
		/**
		 * @deprecated
		 */
		public void reconcile(ReconcileContext context) {
			this.delta = context.getDelta();
			try {
				this.ast = context.getAST(JLS_LATEST);
				assertFalse("Context should have statement recovery enabled", (context.getReconcileFlags() & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
				assertTrue("Context should have ignore method body enabled", (context.getReconcileFlags() & ICompilationUnit.IGNORE_METHOD_BODIES) != 0);
			} 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[] { "testBug374176" };
//	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(JLS_LATEST,
			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);
}
protected 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",
			null
		);
		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 API (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 API (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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, true/*force problem detection*/, null/*primary owner*/, monitor);
				setWorkingCopyContents(
					"package p1;\n" +
					"import p2.*;\n" +
					"public class X {\n" +
					"}");
				ReconcilerTests.this.workingCopy.reconcile(JLS_LATEST, 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(JLS_LATEST, 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 correctly 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 API (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 API (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 API (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 API (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 API (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",
		"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
	);
	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",
		"[Working copy] X.java[*]: {CONTENT | FINE GRAINED}"
	);
	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"
	);
}
/**
 * Introduces a syntax error in the modifiers of a method.
 * Variant to force the expected modifier change.
 */
public void testMethodWithError01a() 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 \"public_\", public expected\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(JLS_LATEST, 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() {
		/**
		 * @deprecated
		 */
		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() {
		/**
		 * @deprecated
		 */
		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() {
		/**
		 * @deprecated
		 */
		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() {
		/**
		 * @deprecated
		 */
		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() {
		/**
		 * @deprecated
		 */
		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() {
		/**
		 * @deprecated
		 */
		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(JLS_LATEST, 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" +
//{ObjectTeams: our grammar has different expectations:
/* orig:
		"Syntax error, insert \")\" to complete MethodDeclaration\n" +
  :giro */
		"Syntax error, insert \")\" to complete MethodSpecLong\n" + 
		"----------\n" + 
		"2. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + 
		"	public void bar( {\n" + 
		"	               ^\n" + 
		"Syntax error, insert \"<-\" to complete CallinBindingLeft\n" + 
		"----------\n" + 
		"3. ERROR in /Reconciler/src/p1/X.java (at line 4)\n" + 
		"	public void bar( {\n" + 
		"	               ^\n" + 
		"Syntax error, insert \"MethodSpecsLong EmptyParameterMappings\" to complete ClassBodyDeclarations\n" +
// SH}
		"----------\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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST, 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(JLS_LATEST,
			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(JLS_LATEST,
			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(JLS_LATEST,
			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(JLS_LATEST,
			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(JLS_LATEST,
			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(JLS_LATEST,
			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" +
//{ObjectTeams: we don't check imports before analyze (see CUD.resolve())
/* orig:		
		"import p2.*;" +
		"public class X {\n" +
 */
// trigger a different warning:
		"public class X implements java.io.Serializable {\n" +
// SH}
		"  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(JLS_LATEST, 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"+
//{ObjectTeams: expect different warning:
/* orig:
			"	import p2.*;public class X {\n" +
			"	       ^^\n" +
			"The import p2 is never used\n"+
  :giro */
			"	public class X implements java.io.Serializable {\n" + 
			"	             ^\n" + 
			"The serializable class X does not declare a static final serialVersionUID field of type long\n" +
// SH}
			"----------\n"
		);
	// statement declaring i should not be in the AST
	assertASTNodeEquals(
			"Unexpected participant ast",
			"package p1;\n" +
//{ObjectTeams: different AST (see above):
/* orig: 
			"import p2.*;\n" +
			"public class X {\n" +
  :giro */
			"public class X implements java.io.Serializable {\n" +
// SH}
			"  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(JLS_LATEST, 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
		);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=130000
public void testIgnoreMethodBodies3() throws CoreException {
	new ReconcileParticipant2();
	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() {\n" +
		"    };" +
		"  }\n" +
		"}");
	org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(
			JLS_LATEST,
			ICompilationUnit.IGNORE_METHOD_BODIES | ICompilationUnit.ENABLE_STATEMENTS_RECOVERY,
			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
		);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=130000
public void testIgnoreMethodBodies4() throws CoreException {
	new ReconcileParticipant3();
	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() {\n" +
		"    };" +
		"  }\n" +
		"}");
	org.eclipse.jdt.core.dom.CompilationUnit ast = this.workingCopy.reconcile(
			JLS_LATEST,
			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
		);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
public void testGenericAPIUsageFromA14Project() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
			"/Reconciler15API/src/p2/BundleContext.java",
			"package p2;\n" +
			"public class BundleContext {\n" +
			"  public <S> S getService(S s) {\n" +
			"      return null;\n" +
			"  }\n" +
			"}"
		);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import p2.BundleContext;\n" +
			"public class X {\n" +
			"  public static void main(BundleContext context, String string) {\n" +
			"  String s = (String) context.getService(string); \n" +
			"  }\n" +
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + 
			"	String s = (String) context.getService(string); \n" + 
			"	       ^\n" + 
			"The value of the local variable s is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 (same as above, but with a JSR14 target)
public void testGenericAPIUsageFromA14Project2() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
			"/Reconciler15API/src/p2/BundleContext.java",
			"package p2;\n" +
			"public class BundleContext {\n" +
			"  public <S> S getService(S s) {\n" +
			"      return null;\n" +
			"  }\n" +
			"}"
		);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import p2.BundleContext;\n" +
			"public class X {\n" +
			"  public static void main(BundleContext context, String string) {\n" +
			"  String s = (String) context.getService(string); \n" +
			"  }\n" +
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + 
			"	String s = (String) context.getService(string); \n" + 
			"	       ^\n" + 
			"The value of the local variable s is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633
public void testGenericAPIUsageFromA14Project3() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
			"/Reconciler15API/src/p2/X.java",
			"package p2;\n" +
			"import java.util.Collection;\n" +
			"import java.util.Iterator;\n" +
			"public class X<E> implements Collection<E>{\n" +
			"   public static X getX() {\n" +
			"        	return new X();\n" +
			"	}\n" +
			"	public int size() {\n" +
			"		return 0;\n" +
			"	}\n" +
			"	public boolean isEmpty() {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public boolean contains(Object o) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public Iterator<E> iterator() {\n" +
			"		return null;\n" +
			"	}\n" +
			"	public Object[] toArray() {\n" +
			"		return null;\n" +
			"	}\n" +
			"	public <T> T[] toArray(T[] a) {\n" +
			"		return null;\n" +
			"	}\n" +
			"	public boolean add(E e) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public boolean remove(Object o) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public boolean containsAll(Collection<?> c) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public boolean addAll(Collection<? extends E> c) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public boolean removeAll(Collection<?> c) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public boolean retainAll(Collection<?> c) {\n" +
			"		return false;\n" +
			"	}\n" +
			"	public void clear() {\n" +
			"	}\n" +
			"}\n"
		);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import java.util.Collection;\n" +
			"public class X {\n" +
			"  public static void main(String string) {\n" +
			"  Collection c = p2.X.getX(); \n" +
			"  }\n" +
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + 
			"	Collection c = p2.X.getX(); \n" + 
			"	           ^\n" + 
			"The value of the local variable c is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 (variation: 15 uses 14)
public void testGenericAPIUsageFromA14Project4() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import java.lang.Comparable;\n" +
			"public class X implements Comparable {\n" +
			"  public static X getX() {\n" +
			"      return new X();\n" +
			"  }\n" +
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);

		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);

		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		String otherSource = "package p2;\n" +
		                     "public class X { \n" +
		                     " private p1.X x = p1.X.getX();\n" +
		                     " Comparable<String> y = null;\n" +
		                     "}\n";   
		                 
		createFile(
			"/Reconciler15API/src/p2/X.java",
			otherSource
		);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		IClasspathEntry[] oldClasspath = project15.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler1415"));
		project15.setRawClasspath(newClasspath, null);
				
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = otherSource.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler15API/src/p2/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler15API/src/p2/X.java (at line 3)\n" + 
			"	private p1.X x = p1.X.getX();\n" + 
			"	             ^\n" + 
			"The value of the field X.x is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633
public void testGenericAPIUsageFromA14Project5() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
				"/Reconciler15API/src/p2/List.java",
				"package p2;\n" +
				"public  class List<T> {}\n" +
				"  public static List<String> [] getArray() {\n" +
				"      return null;\n" +
				"  }\n" +
				"  public static List<String> [] getBackArray(List<String>[] p) {\n" +
				"      return p;\n" +
				"  }\n" +
				"}"
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import p2.List;\n" +
			"public class X {\n" +
			"  private List [] l = List.getArray();\n" +
			"  private List [] l2 = List.getBackArray(l);\n" +
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + 
			"	private List [] l2 = List.getBackArray(l);\n" + 
			"	                ^^\n" + 
			"The value of the field X.l2 is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850
public void testGenericAPIUsageFromA14Project6() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
				"/Reconciler15API/src/p2/Y.java",
				"package p2;\n" +
				"public abstract class Y implements I<Y> {\n" +
				"    public final Y foo(Object o, J<Y> j) {\n" +
				"        return null;\n" +
				"    }\n" +
				"    public final void bar(Object o, J<Y> j, Y y) {\n" +
				"    }\n" +
				"}\n" +
				"interface I<S> {\n" +
				"	public S foo(Object o, J<S> j);\n" +
				"	public void bar(Object o, J<S> j, S s);\n" +
				"}\n" +
				"interface J<S> {}\n"
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import p2.Y;\n" +
			"public class X {\n" + 
			"   private int unused = 0;\n" +
			"	public Object foo() {\n" + 
			"		return new Y() {};\n" + 
			"	}\n" + 
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + 
			"	private int unused = 0;\n" + 
			"	            ^^^^^^\n" + 
			"The value of the field X.unused is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850
public void testGenericAPIUsageFromA14Project7() throws CoreException, IOException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
				"/Reconciler15API/src/p2/Y.java",
				"package p2;\n" +
				"import java.util.List;\n" +
				"public class Y<T> extends List<T> {\n" +
				"    public static Y<String> getY() {\n" +
				"        return new Y<String>();\n" +
				"    }\n" +
				"}\n"
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		addLibrary(
				project15,
				"libList15.jar",
				"libList15src.zip",
				new String[] {
					"java/util/List.java",
					"package java.util;\n" +
					"public class List<T> {\n" +
					"}"
				},
				JavaCore.VERSION_1_5
			);

		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);

		addLibrary(
				project14,
				"libList14.jar",
				"libList14src.zip",
				new String[] {
					"java/util/List.java",
					"package java.util;\n" +
					"public class List {\n" +
					"}"
				},
				JavaCore.VERSION_1_4
			);

		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import java.util.List;\n" +
			"import p2.Y;\n" +
			"public class X {\n" + 
			"	private static List getList(boolean test) {\n" +
			"	    if (test)\n" +
			"	        return new Y();\n" + 
			"	    else\n" +
			"		    return Y.getY();\n" + 
			"   }\n" + 
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 5)\n" + 
			"	private static List getList(boolean test) {\n" + 
			"	                    ^^^^^^^^^^^^^^^^^^^^^\n" + 
			"The method getList(boolean) from the type X is never used locally\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850
public void testGenericAPIUsageFromA14Project8() throws CoreException, IOException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p2");
		createFile(
				"/Reconciler15API/src/p2/Y.java",
				"package p2;\n" +
				"public class Y<T> extends java.util.List<T> {\n" +
				"    public static Y<String> getY() {\n" +
				"        return new Y<String>();\n" +
				"    }\n" +
				"}\n"
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		addLibrary(
				project15,
				"libList15.jar",
				"libList15src.zip",
				new String[] {
					"java/util/List.java",
					"package java.util;\n" +
					"public class List<T> {\n" +
					"}"
				},
				JavaCore.VERSION_1_5
			);

		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);

		addLibrary(
				project14,
				"libList14.jar",
				"libList14src.zip",
				new String[] {
					"java/util/List.java",
					"package java.util;\n" +
					"public class List {\n" +
					"}"
				},
				JavaCore.VERSION_1_4
			);

		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"import p2.Y;\n" +
			"public class X {\n" + 
			"	private static java.util.List getList(boolean test) {\n" +
			"	    if (test)\n" +
			"	        return new Y();\n" + 
			"	    else\n" +
			"		    return Y.getY();\n" + 
			"   }\n" + 
			"}";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + 
			"	private static java.util.List getList(boolean test) {\n" + 
			"	                              ^^^^^^^^^^^^^^^^^^^^^\n" + 
			"The method getList(boolean) from the type X is never used locally\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328775
public void test14ProjectWith15JRE() throws CoreException, IOException {
	IJavaProject project14 = null;
	try {
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);

		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"public class X {\n" +
			"	int a;\n" +
			"   private Class c = a == 1 ? int.class : long.class;\n" + 
			"}\n";
		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + 
			"	private Class c = a == 1 ? int.class : long.class;\n" + 
			"	              ^\n" + 
			"The value of the field X.c is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=329593
public void testJsr14TargetProjectWith14JRE() throws CoreException, IOException {
	IJavaProject project14 = null;
	try {
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);

		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"public class X {\n" +
			"    public void foo() {\n" +
			"        Class type = null;\n" +
			"        if (type == byte.class)\n" +
			"            return;\n" +
			"    }\n" +
			"}\n";
		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 6)\n" + 
			"	return;\n" + 
			"	^^^^^^^\n" + 
			"Dead code\n" + 
			"----------\n"

		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
	}
}
public void testGenericAPIUsageFromA14Project9() throws CoreException {
	IJavaProject project14 = null;
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler15API/src/p1");
		createFile(
				"/Reconciler15API/src/p1/Y.java",
				"package p1;\n" +
				"public class Y {\n" +
				"    static <T> void foo(List<T> expected) {}\n" +
				"    public static <T> void foo(T expected) {}\n" +
				"}\n"
			);
		createFile(
				"/Reconciler15API/src/p1/List.java",
				"package p1;\n" +
				"public class List<T> {}\n"
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
		
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
		
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
		project14.setRawClasspath(newClasspath, null);
		
		createFolder("/Reconciler1415/src/p1");
		String source = 
			"package p1;\n" +
			"public class X {\n" +
			"	private int unused = 0;\n" + 
			"    X(List l) {\n" +
			"        Y.foo(l);\n" +
			"    }\n" +
			"}\n";

		createFile(
			"/Reconciler1415/src/p1/X.java",
			source
		);
		
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 3)\n" + 
			"	private int unused = 0;\n" + 
			"	            ^^^^^^\n" + 
			"The value of the field X.unused is not used\n" + 
			"----------\n"
		);
	} finally {
		if (project14 != null)
			deleteProject(project14);
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=374176
// verify that a reconcile does not result in errors for a CU whose package does not have
// default null annotations
public void testBug374176() throws CoreException, IOException, InterruptedException {
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("TestAnnot", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/TestAnnot/src/p1");
		String source = "package p1;\n" +
				"public class Y {\n" +
				"}\n;";
		createFile(
				"/TestAnnot/src/p1/Y.java",
				source
			);
		createFolder("/TestAnnot/src/p2");
		createFile(
				"/TestAnnot/src/p2/Y2.java",
				"package p2;\n" +
				"public class Y2{\n" +
				"}\n"
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR);
		project15.setOption(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR);
		project15.setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR);
		project15.setOption(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED);
		project15.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
		project15.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);

		this.workingCopies = new ICompilationUnit[2];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/TestAnnot/src/p1/Y.java").getWorkingCopy(this.wcOwner, null);
		this.workingCopies[0].makeConsistent(null);
		this.workingCopies[0].reconcile(ICompilationUnit.NO_AST, false, null, null);

		assertNoProblem(sourceChars, this.workingCopies[0]);
	} finally {
		if (project15 != null)
			deleteProject(project15);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=374176
// verify that a reconcile DOES result in errors for package-info whose package does not have
// default null annotations
public void testBug374176b() throws CoreException, IOException, InterruptedException {
	IJavaProject project15 = null;
	try {
		project15 = createJavaProject("TestAnnot", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/TestAnnot/src/p1");
		String source = "package p1;\n";
		createFile(
				"/TestAnnot/src/p1/package-info.java",
				source
			);
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR);
		project15.setOption(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR);
		project15.setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR);
		project15.setOption(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED);
		project15.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
		project15.setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR);

		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = source.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/TestAnnot/src/p1/package-info.java").getWorkingCopy(this.wcOwner, null);
		this.workingCopies[0].makeConsistent(null);
		this.workingCopies[0].reconcile(ICompilationUnit.NO_AST, false, null, null);

		assertProblems("Unexpected problems",
			"----------\n" + 
			"1. ERROR in /TestAnnot/src/p1/package-info.java (at line 1)\n" + 
			"	package p1;\n" + 
			"	        ^^\n" + 
			"A default nullness annotation has not been specified for the package p1\n" + 
			"----------\n");
		assertProblems("Unexpected problems",
			"----------\n" + 
			"1. ERROR in /TestAnnot/src/p1/package-info.java (at line 1)\n" + 
			"	package p1;\n" + 
			"	        ^^\n" + 
			"A default nullness annotation has not been specified for the package p1\n" + 
			"----------\n",
			this.problemRequestor);
	} finally {
		if (project15 != null)
			deleteProject(project15);
	}
}
public void testSecondaryTypeDeletion() throws CoreException, IOException {
	
	// Set working copy content with no error
	setUpWorkingCopy("/Reconciler/src/X.java",
			"interface I {\n" +
					"	void foo();\n" +
					"}\n" +
					"public class X {\n" +
					"	static void goo(I i) {\n" +
					"	}\n" +
					"}\n"
			);
	assertProblems(
			"Unexpected problems",
			"----------\n" +
			"----------\n"
			);

	String contents = 
					"public class X {\n" +
					"	static void goo(I i) {\n" +
					"	}\n" +
					"}\n";
	
	setWorkingCopyContents(contents);
	this.workingCopy.reconcile(ICompilationUnit.NO_AST, true, null, null);
	assertProblems(
			"Wrong expected problems",
			"----------\n" + 
			"1. ERROR in /Reconciler/src/X.java (at line 2)\n" + 
			"	static void goo(I i) {\n" + 
			"	                ^\n" + 
			"I cannot be resolved to a type\n" + 
			"----------\n"
			);
	
}
/**
 * Project's compliance: source: 1.5, compiler: 1.5
 * Jar's compliance: source: 1.3, compiler: 1.3
 * Jar contains a class with "enum" package and is located inside the project.
 * The test verifies that class from the "enum" package is correctly reconciled.
 */
public void testBug410207a() throws Exception {
	try {
		IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5");
		Util.createJar(new String[] {
				"a/enum/b/NonCompliant.java",
				"package a.enum.b;\n" +
				"public class NonCompliant {\n" +
				"}",
				"lib/External.java",
				"package lib;\n" +
				"import a.enum.b.NonCompliant;\n" +
				"public class External {\n" +
				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
				"      return null;\n" +
				"	}\n" +
				"}"
			},
			p.getProject().getLocation().append("lib.jar").toOSString(),
			"1.3");
		refresh(p);
		setUpWorkingCopy(
				"/P/src/p/Main.java",
				"package p;\n" +
				"import lib.External;\n" +
				"public class Main {\n" +
				"   public void m() {\n" +
				"      External external = new External();\n" +
				"      external.setNonCompliant(null);\n" +
				"   };\n" +
				"}"
		);
		this.problemRequestor.reset();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n"
		);
	} finally {
		deleteProject("P");
	}
}
/**
 * Project's compliance: source: 1.5, compiler: 1.5
 * Jar's compliance: source: 1.4, compiler: 1.6
 * Jar contains a class with "enum" package and is located inside the project.
 * The test verifies that class from the "enum" package is correctly reconciled.
 */
public void testBug410207b() throws Exception {
	try {
		IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5");
		Map options = new HashMap();
		options.put(CompilerOptions.OPTION_Source, "1.4");
		Util.createJar(new String[] {
				"a/enum/b/NonCompliant.java",
				"package a.enum.b;\n" +
				"public class NonCompliant {\n" +
				"}",
				"lib/External.java",
				"package lib;\n" +
				"import a.enum.b.NonCompliant;\n" +
				"public class External {\n" +
				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
				"      return null;\n" +
				"	}\n" +
				"}"
			},
			null,/*extraPathsAndContents*/
			p.getProject().getLocation().append("lib.jar").toOSString(),
			null,/*classpath*/
			"1.6",
			options);
		refresh(p);
		setUpWorkingCopy(
				"/P/src/p/Main.java",
				"package p;\n" +
				"import lib.External;\n" +
				"public class Main {\n" +
				"   public void m() {\n" +
				"      External external = new External();\n" +
				"      external.setNonCompliant(null);\n" +
				"   };\n" +
				"}"
		);
		this.problemRequestor.reset();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n"
		);
	} finally {
		deleteProject("P");
	}
}
/**
 * Two projects:
 * 		Lib: source: 1.4, compiler: 1.4
 * 		P: source: 1.5, compiler: 1.5
 * Lib contains a class with "enum" package and is required by P (dependency on the bin folder).
 * The test verifies that class from the "enum" package is correctly reconciled for P.
 */
public void testBug410207c() throws Exception {
	try {
		createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4");
		createFolder("/Lib/src/a/enum/b");
		createFile(
				"/Lib/src/a/enum/b/NonCompliant.java",
				"package a.enum.b;\n" +
				"public class NonCompliant {\n" +
				"}"
		);
		createFolder("/Lib/src/lib");
		createFile(
				"/Lib/src/lib/External.java",
				"package lib;\n" +
				"import a.enum.b.NonCompliant;\n" +
				"public class External {\n" +
				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
				"      return null;\n" +
				"	}\n" +
				"}"
		);
		getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null);
		createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/Lib/bin"}, "bin", "1.5");
		setUpWorkingCopy(
				"/P/src/p/Main.java",
				"package p;\n" +
				"import lib.External;\n" +
				"public class Main {\n" +
				"   public void m() {\n" +
				"      External external = new External();\n" +
				"      external.setNonCompliant(null);\n" +
				"   };\n" +
				"}"
		);
		this.problemRequestor.reset();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n"
		);
	} finally {
		deleteProjects(new String[] { "Lib", "P" });
	}
}
/**
 * Two projects:
 * 		Lib: source: 1.4, compiler: 1.4
 * 		P: source: 1.5, compiler: 1.5
 * Lib contains a class with "enum" package and is required by P (dependency on the whole project).
 * The test verifies that class from the "enum" package is correctly reconciled for P.
 */
public void testBug410207d() throws Exception {
	try {
		createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4");
		createFolder("/Lib/src/a/enum/b");
		createFile(
				"/Lib/src/a/enum/b/NonCompliant.java",
				"package a.enum.b;\n" +
				"public class NonCompliant {\n" +
				"}"
		);
		createFolder("/Lib/src/lib");
		createFile(
				"/Lib/src/lib/External.java",
				"package lib;\n" +
				"import a.enum.b.NonCompliant;\n" +
				"public class External {\n" +
				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
				"      return null;\n" +
				"	}\n" +
				"}"
		);
		getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null);
		createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, new String[] {"/Lib"}, "bin", "1.5");
		setUpWorkingCopy(
				"/P/src/p/Main.java",
				"package p;\n" +
				"import lib.External;\n" +
				"public class Main {\n" +
				"   public void m() {\n" +
				"      External external = new External();\n" +
				"      external.setNonCompliant(null);\n" +
				"   };\n" +
				"}"
		);
		this.problemRequestor.reset();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n"
		);
	} finally {
		deleteProjects(new String[] { "Lib", "P" });
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=440592, Cannot easily launch application in case of certain usage of lambda expressions
public void testBug440592() throws Exception {
	try {
		createJavaProject("P", new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		createFile(
				"/P/src/BugTest.java",
				"public class BugTest {\n" +
				"	public void baz(InterfaceForBugTest arg) {\n" +
				"	}\n" +
				"	public void bar() {\n" +
				"		baz(InterfaceForBugTest.instance); \n" +
				"	}\n" +
				"	public Runnable returningLambda() { \n" +
				"		return () -> {\n" +
				"		};\n" +
				"	}\n" +
				"	public static void main(String[] args) {\n" +
				"	}\n" +
				"}\n"
		);
		createFile(
				"/P/src/InterfaceForBugTest.java",
				"public interface InterfaceForBugTest {\n" +
				"	public static InterfaceForBugTest creator1(Runnable simpleInstance){\n" +
				"		return null;\n" +
				"	}\n" +
				"	public static void methodWithAnonymousImplementation() {\n" +
				"		new InterfaceForBugTest() {\n" +
				"			@Override\n" +
				"			public void fun1() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun2() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun3() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun4() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun5() {\n" +
				"			}\n" +
				"		};\n" +
				"	} \n" +
				"	public static void methodWithAnonymousImplementation2() {\n" +
				"		new InterfaceForBugTest() {\n" +
				"			@Override\n" +
				"			public void fun1() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun2() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun3() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun4() {\n" +
				"			}\n" +
				"			@Override\n" +
				"			public void fun5() {\n" +
				"			}\n" +
				"		};\n" +
				"	}\n" +
				"	public static InterfaceForBugTest instance = creator1(() -> {\n" +
				"	});\n" +
				"	void fun1();\n" +
				"	void fun2();\n" +
				"	void fun3();\n" +
				"	void fun4();\n" +
				"	void fun5();\n" +
				"}\n"

		);
		getProject("P").build(IncrementalProjectBuilder.FULL_BUILD, null);
		setUpWorkingCopy(
				"/P/src/BugTest.java",
				"public class BugTest {\n" +
				"	public void baz(InterfaceForBugTest arg) {\n" +
				"	}\n" +
				"	public void bar() {\n" +
				"		baz(InterfaceForBugTest.instance); \n" +
				"	}\n" +
				"	public Runnable returningLambda() { \n" +
				"		return () -> {\n"  +
				"		};\n" +
				"	}\n" +
				"	public static void main(String[] args) {\n" +
				"	}\n" +
				"}\n"
		);
		this.problemRequestor.reset();
		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
		assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n"
		);
	} finally {
		deleteProjects(new String[] { "P" });
	}
}
public void testBug485092() throws CoreException, IOException, InterruptedException {

	IJavaProject project15 = null;
	IJavaProject project18 = null;
	try {
		project15 = createJavaProject("Reconciler1518", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler1518/src/p1");
		String source = 
				"package p1;\n" +
				"\n" +
				"public interface PreferenceableOption<T extends Object> {}\n";

		createFile(
			"/Reconciler1518/src/p1/PreferenceableOption.java",
			source
		);

		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);

		project18 = createJavaProject("Reconciler18", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
		createFolder("/Reconciler18/src/p2");
		String otherSource = 
				"package p2;\n" +
				"import org.eclipse.jdt.annotation.NonNull;\n" +
				"import org.eclipse.jdt.annotation.Nullable;\n" +
				"\n" +
				"import p1.PreferenceableOption;\n" +
				"public class PivotEnvironmentFactory\n" +
				"{\n" +
				"	public @NonNull Object @Nullable [] scopeContexts = null;\n" +
				"}\n";

		createFile(
			"/Reconciler18/src/p2/PivotEnvironmentFactory.java",
			otherSource
		);
		project18.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
		project18.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
		project18.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);


		project18.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
		Bundle[] bundles = Platform.getBundles("org.eclipse.jdt.annotation","[2.0.0,3.0.0)");
		File bundleFile = FileLocator.getBundleFile(bundles[0]);
		String annotationsLib = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath();
		IClasspathEntry nullAnnotationsClassPathEntry = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null);
				
		IClasspathEntry[] oldClasspath = project18.getRawClasspath();
		int oldLength = oldClasspath.length;
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+2];
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler1518"));
		newClasspath[oldLength + 1] = nullAnnotationsClassPathEntry;
		project18.setRawClasspath(newClasspath, null);
				
		this.workingCopies = new ICompilationUnit[1];
		char[] sourceChars = otherSource.toCharArray();
		this.problemRequestor.initialize(sourceChars);
		this.workingCopies[0] = getCompilationUnit("/Reconciler18/src/p2/PivotEnvironmentFactory.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"1. WARNING in /Reconciler18/src/p2/PivotEnvironmentFactory.java (at line 5)\n" + 
			"	import p1.PreferenceableOption;\n" + 
			"	       ^^^^^^^^^^^^^^^^^^^^^^^\n" + 
			"The import p1.PreferenceableOption is never used\n" + 
			"----------\n"
		);
	} finally {
		if (project15 != null)
			deleteProject(project15);
		if (project18 != null)
			deleteProject(project18);
	}
}
public void testBug534865() throws CoreException, IOException {
	IJavaProject project18 = null;
	try {
		project18 = createJavaProject("Reconciler18", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin");
		setUpProjectCompliance(project18, "1.8");
		project18.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
		createFolder("/Reconciler18/src/org/eclipse/jdt/annotation");
		createFile(
			"/Reconciler18/src/org/eclipse/jdt/annotation/Nullable.java",
			"package org.eclipse.jdt.annotation;\n" +
					"import static java.lang.annotation.ElementType.TYPE_USE;\n" + 
					"\n" + 
					"import java.lang.annotation.Documented;\n" + 
					"import java.lang.annotation.Retention;\n" + 
					"import java.lang.annotation.RetentionPolicy;\n" + 
					"import java.lang.annotation.Target;\n" +
					"@Documented\n" + 
					"@Retention(RetentionPolicy.CLASS)\n" + 
					"@Target({ TYPE_USE })\n" + 
					"public @interface Nullable {\n" + 
					"	// marker annotation with no members\n" + 
					"}\n"
		);
		String source = 
				"package org.eclipse.jdt.annotation;\n" +
				"import static java.lang.annotation.ElementType.TYPE_USE;\n" + 
				"\n" + 
				"import java.lang.annotation.Documented;\n" + 
				"import java.lang.annotation.Retention;\n" + 
				"import java.lang.annotation.RetentionPolicy;\n" + 
				"import java.lang.annotation.Target;\n" +
				"@Documented\n" + 
				"@Retention(RetentionPolicy.CLASS)\n" + 
				"@Target({ TYPE_USE })\n" + 
				"public @interface NonNull {\n" + 
				"	// marker annotation with no members\n" + 
				"}\n";

		createFile(
			"/Reconciler18/src/org/eclipse/jdt/annotation/NonNull.java",
			source
		);
		this.workingCopies = new ICompilationUnit[1];
		this.problemRequestor.initialize(source.toCharArray());
		this.workingCopies[0] = getCompilationUnit("/Reconciler18/src/org/eclipse/jdt/annotation/NonNull.java").getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"----------\n"
		);
	} finally {
		if (project18 != null)
			deleteProject(project18);
	}
}
}
