/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.internal.core.ExternalJavaProject;
import org.eclipse.jdt.internal.core.util.Util;

import junit.framework.Test;

/**
 * Tests APIs that take a WorkingCopyOwner.
 */
@SuppressWarnings("rawtypes")
public class WorkingCopyOwnerTests extends ModifyingResourceTests {

	/**
	 * Internal synonym for deprecated constant AST.JSL3
	 * to alleviate deprecation warnings.
	 * @deprecated
	 */
	/*package*/ static final int JLS3_INTERNAL = AST.JLS3;
	
	ICompilationUnit workingCopy = null;

	public class TestWorkingCopyOwner extends WorkingCopyOwner {

		public String toString() {
			return "Test working copy owner";
		}
	}

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

	// Use this static initializer to specify subset for tests
	// All specified tests which do not belong to the class are skipped...
	static {
//		TESTS_NAMES = new String[] { "testNewWorkingCopy03" };
//		TESTS_NUMBERS = new int[] { 2, 12 };
//		TESTS_RANGE = new int[] { 16, -1 };
	}

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

	public void setUpSuite() throws Exception {
		super.setUpSuite();

		createJavaProject("P");
		createFile(
			"P/X.java",
			"public class X {\n" +
			"}"
		);
	}

	public void tearDownSuite() throws Exception {
		deleteProject("P");

		super.tearDownSuite();
	}

	protected void tearDown() throws Exception {
		if (this.workingCopy != null) {
			this.workingCopy.discardWorkingCopy();
			this.workingCopy = null;
		}
		super.tearDown();
	}

	private void assertProblems(String expectedProblems, String path, String source, WorkingCopyOwner owner) throws JavaModelException {
		this.workingCopy = getWorkingCopy(path, source);
		ASTParser parser = ASTParser.newParser(JLS3_INTERNAL);
		parser.setSource(this.workingCopy);
		parser.setResolveBindings(true);
		parser.setWorkingCopyOwner(owner);
		CompilationUnit cu = (CompilationUnit) parser.createAST(null);
		assertProblems("Unexpected problems", expectedProblems, cu.getProblems(), source.toCharArray());
	}
	
	protected void assertTypeBindingsEqual(String message, String expected, ITypeBinding[] types) {
		StringBuffer buffer = new StringBuffer();
		if (types == null) {
			buffer.append("<null>");
		} else {
			for (int i = 0, length = types.length; i < length; i++){
				buffer.append(types[i].getQualifiedName());
				if (i != length-1) {
					buffer.append("\n");
				}
			}
		}
		if (!expected.equals(buffer.toString())) {
			System.out.println(org.eclipse.jdt.core.tests.util.Util.displayString(buffer.toString(), 2));
		}
		assertEquals(
			message,
			expected,
			buffer.toString()
		);
	}

	/*
	 * Tests that a primary compilation unit can become a working copy.
	 */
	public void testBecomeWorkingCopy1() throws CoreException {
		this.workingCopy = getCompilationUnit("P/X.java");
		assertTrue("should not be in working copy mode", !this.workingCopy.isWorkingCopy());

		this.workingCopy.becomeWorkingCopy(null);
		assertTrue("should be in working copy mode", this.workingCopy.isWorkingCopy());
	}

	/*
	 * Tests that a working copy remains a working copy when becomeWorkingCopy() is called.
	 */
	public void testBecomeWorkingCopy2() throws CoreException {
		this.workingCopy = getCompilationUnit("P/X.java").getWorkingCopy(new TestWorkingCopyOwner(), null);
		assertTrue("should be in working copy mode", this.workingCopy.isWorkingCopy());

		this.workingCopy.becomeWorkingCopy(null);
		assertTrue("should still be in working copy mode", this.workingCopy.isWorkingCopy());
	}

	/*
	 * Tests that a primary compilation unit is added from to its parent after it becomes a working copy and
	 * there is no underlying resource.
	 */
	public void testBecomeWorkingCopy3() throws CoreException {
		this.workingCopy = getCompilationUnit("P/Y.java");

		this.workingCopy.becomeWorkingCopy(null);
		assertSortedElementsEqual(
			"Unexpected children of default package",
			"X.java [in <default> [in <project root> [in P]]]\n" +
			"[Working copy] Y.java [in <default> [in <project root> [in P]]]",
			getPackage("/P").getChildren());
	}

	/*
	 * Ensure an OperationCanceledException is correcly thrown when progress monitor is canceled
	 */
	public void testBecomeWorkingCopy4() throws CoreException {
		this.workingCopy = getCompilationUnit("P/X.java");

		// count the number of time isCanceled() is called when converting this source unit
		CancelCounter counter = new CancelCounter();
		this.workingCopy.becomeWorkingCopy(counter);
		this.workingCopy.discardWorkingCopy();

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

		// last should not throw an OperationCanceledException
		this.workingCopy.becomeWorkingCopy(new Canceler(counter.count));
	}

	/*
	 * Tests that a primary working copy can be commited.
	 */
	public void testCommitPrimaryWorkingCopy() throws CoreException {
		try {
			IFile file = createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);
			String newContents =
				"public class Y {\n" +
				"  void foo() {\n" +
				"  }\n" +
				"}";
			this.workingCopy.getBuffer().setContents(newContents);
			this.workingCopy.commitWorkingCopy(false, null);
			assertSourceEquals(
				"Unexpected source",
				newContents,
				new String(Util.getResourceContentsAsCharArray(file)));
		} finally {
			deleteFile("P/Y.java");
		}
	}

	/*
	 * Ensures that no delta is issued when a primary working copy that is consistent is commited.
	 * (regression test for bug 40782 Primary working copies: unnecessary deltas on save)
	 */
	public void testDeltaCommitPrimaryWorkingCopy1() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);
			this.workingCopy.getBuffer().setContents(
				"public class Y {\n" +
				"  void foo() {\n" +
				"  }\n" +
				"}"
			);
			this.workingCopy.makeConsistent(null);

			startDeltas();
			this.workingCopy.commitWorkingCopy(false, null);
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			[Working copy] Y.java[*]: {PRIMARY RESOURCE}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}
	}

	/*
	 * Ensures that the correct delta is issued when a primary working copy that is not consistent is commited.
	 */
	public void testDeltaCommitPrimaryWorkingCopy2() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);
			this.workingCopy.getBuffer().setContents(
				"public class Y {\n" +
				"  void foo() {\n" +
				"  }\n" +
				"}"
			);

			startDeltas();
			this.workingCopy.commitWorkingCopy(false, null);
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			[Working copy] Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" +
				"				Y[*]: {CHILDREN | FINE GRAINED}\n" +
				"					foo()[+]: {}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}
	}

	/*
	 * Ensures that the correct delta is issued when a non-primary working copy is created.
	 */
	public void testDeltaCreateNonPrimaryWorkingCopy() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			ICompilationUnit cu = getCompilationUnit("P/Y.java");
			startDeltas();
			this.workingCopy = cu.getWorkingCopy(null);
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			[Working copy] Y.java[+]: {}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}

	}

	/*
	 * Ensures that the correct delta is issued when a primary compilation unit becomes a working copy.
	 */
	public void testDeltaBecomeWorkingCopy1() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			this.workingCopy = getCompilationUnit("P/Y.java");
			startDeltas();
			this.workingCopy.becomeWorkingCopy(null);
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			[Working copy] Y.java[*]: {PRIMARY WORKING COPY}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}

	}

	/*
	 * Ensures that an ADDED delta is issued when a primary compilation unit becomes a working copy
	 * and this compilation unit doesn't exist on disk.
	 * (regression test for bug 44085 becomeWorkingCopy() should add the working copy in the model)
	 */
	public void testDeltaBecomeWorkingCopy2() throws CoreException {
		try {
			this.workingCopy = getCompilationUnit("P/Y.java");
			startDeltas();
			this.workingCopy.becomeWorkingCopy(null);
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			[Working copy] Y.java[+]: {PRIMARY WORKING COPY}"
			);
		} finally {
			stopDeltas();
		}

	}

	/*
	 * Ensures that the correct delta is issued when a non-primary working copy is discarded.
	 */
	public void testDeltaDiscardNonPrimaryWorkingCopy() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			ICompilationUnit cu = getCompilationUnit("P/Y.java");
			this.workingCopy = cu.getWorkingCopy(null);

			startDeltas();
			this.workingCopy.discardWorkingCopy();
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			[Working copy] Y.java[-]: {}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}

	}

	/*
	 * Ensures that the correct delta is issued when a primary working copy becomes a compilation unit.
	 */
	public void testDeltaDiscardPrimaryWorkingCopy1() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);

			startDeltas();
			this.workingCopy.discardWorkingCopy();
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			Y.java[*]: {PRIMARY WORKING COPY}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}

	}

	/*
	 * Ensures that the correct delta is issued when a primary working copy that contained a change
	 * becomes a compilation unit.
	 * (regression test for bug 40779 Primary working copies: no deltas on destroy)

	 */
	public void testDeltaDiscardPrimaryWorkingCopy2() throws CoreException {
		try {
			createFile(
				"P/Y.java",
				"public class Y {\n" +
				"}"
			);
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);
			this.workingCopy.getType("Y").createField("int x;", null, false, null);

			startDeltas();
			this.workingCopy.discardWorkingCopy();
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY WORKING COPY}\n" +
				"				Y[*]: {CHILDREN | FINE GRAINED}\n" +
				"					x[-]: {}"
			);
		} finally {
			stopDeltas();
			deleteFile("P/Y.java");
		}
	}

	/*
	 * Ensures that a REMOVED delta is issued when a primary working copy becomes a compilation unit
	 * and this compilation unit doesn't exist on disk.
	 * (regression test for bug 44084 No refresh when deleting edited unit)
	 */
	public void testDeltaDiscardPrimaryWorkingCopy3() throws CoreException {
		try {
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);

			startDeltas();
			this.workingCopy.discardWorkingCopy();
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			Y.java[-]: {PRIMARY WORKING COPY}"
			);
		} finally {
			stopDeltas();
		}
	}

	/*
	 * Ensures that a CONTENT delta is issued when a primary working copy becomes a compilation unit
	 * with unsaved changes.
	 * (regression test for bug 146012 No F_CONTENT flag on delta when reverting to old annotations)
	 */
	public void testDeltaDiscardPrimaryWorkingCopy4() throws CoreException {
		try {
			this.workingCopy = getCompilationUnit("P/X.java");
			this.workingCopy.becomeWorkingCopy(null);

			this.workingCopy.getBuffer().setContents("/*annotation*/public class X {}");
			startDeltas();
			this.workingCopy.discardWorkingCopy();
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"P[*]: {CHILDREN}\n" +
				"	<project root>[*]: {CHILDREN}\n" +
				"		<default>[*]: {CHILDREN}\n" +
				"			X.java[*]: {CONTENT | FINE GRAINED | PRIMARY WORKING COPY}"
			);
		} finally {
			stopDeltas();
		}
	}

	/*
	 * Tests that a primary working copy is back in compilation unit mode when discardWorkingCopy() is called.
	 */
	public void testDiscardWorkingCopy1() throws CoreException {
		ICompilationUnit cu = null;
		try {
			cu = getCompilationUnit("P/X.java");
			cu.becomeWorkingCopy(null);
			assertTrue("should be in working copy mode", cu.isWorkingCopy());

			cu.discardWorkingCopy();
			assertTrue("should no longer be in working copy mode", !cu.isWorkingCopy());
		} finally {
			if (cu != null) {
				cu.discardWorkingCopy();
			}
		}
	}

	/*
	 * Tests that the same number of calls to discardWorkingCopy() is needed for primary working copy to be back
	 * in compilation uint mode.
	 */
	public void testDiscardWorkingCopy2() throws CoreException {
		ICompilationUnit cu = null;
		try {
			cu = getCompilationUnit("P/X.java");
			cu.becomeWorkingCopy(null);
			cu.becomeWorkingCopy(null);
			cu.becomeWorkingCopy(null);
			assertTrue("should be in working copy mode", cu.isWorkingCopy());

			cu.discardWorkingCopy();
			assertTrue("should still be in working copy mode", cu.isWorkingCopy());

			cu.discardWorkingCopy();
			cu.discardWorkingCopy();
			assertTrue("should no longer be in working copy mode", !cu.isWorkingCopy());
		} finally {
			if (cu != null) {
				int max = 3;
				while (cu.isWorkingCopy() && max-- > 0) {
					cu.discardWorkingCopy();
				}
			}
		}
	}

	/*
	 * Tests that the same number of calls to discardWorkingCopy() is needed for non-primary working copy
	 * to be discarded.
	 */
	public void testDiscardWorkingCopy3() throws CoreException {
		try {
			ICompilationUnit cu = getCompilationUnit("P/X.java");
			TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
			this.workingCopy = cu.getWorkingCopy(owner, null);
			this.workingCopy = cu.getWorkingCopy(owner, null);
			this.workingCopy = cu.getWorkingCopy(owner, null);
			assertTrue("should be in working copy mode", this.workingCopy.isWorkingCopy());
			assertTrue("should be opened", this.workingCopy.isOpen());
			assertTrue("should exist", this.workingCopy.exists());

			this.workingCopy.discardWorkingCopy();
			assertTrue("should still be in working copy mode (1)", this.workingCopy.isWorkingCopy());
			assertTrue("should still be opened", this.workingCopy.isOpen());
			assertTrue("should still exist", this.workingCopy.exists());

			this.workingCopy.discardWorkingCopy();
			this.workingCopy.discardWorkingCopy();
			assertTrue("should still be in working copy mode (2)", this.workingCopy.isWorkingCopy());
			assertTrue("should no longer be opened", !this.workingCopy.isOpen());
			assertTrue("should no longer exist", !this.workingCopy.exists());

		} finally {
			if (this.workingCopy != null) {
				int max = 3;
				while (this.workingCopy.isWorkingCopy() && max-- > 0) {
					this.workingCopy.discardWorkingCopy();
				}
			}
		}
	}

	/*
	 * Tests that a non-primary working copy that is discarded cannot be reopened.
	 */
	public void testDiscardWorkingCopy4() throws CoreException {
		ICompilationUnit cu = getCompilationUnit("P/X.java");
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = cu.getWorkingCopy(owner, null);

		boolean gotException = false;
		try {
			this.workingCopy.getAllTypes();
		} catch (JavaModelException e) {
			gotException = true;
		}
		assertTrue("should not get a JavaModelException before discarding working copy", !gotException);

		this.workingCopy.discardWorkingCopy();

		gotException = false;
		try {
			this.workingCopy.getAllTypes();
		} catch (JavaModelException e) {
			gotException = true;
		}
		assertTrue("should get a JavaModelException after discarding working copy", gotException);
	}

	/*
	 * Tests that a primary working copy  is removed from its parent after it is discarded and
	 * there is no underlying resource.
	 */
	public void testDiscardWorkingCopy5() throws CoreException {
		ICompilationUnit cu = null;
		try {
			cu = getCompilationUnit("P/Y.java");
			cu.becomeWorkingCopy(null);

			cu.discardWorkingCopy();
			assertElementsEqual(
				"Unexpected children of default package",
				"X.java [in <default> [in <project root> [in P]]]",
				getPackage("/P").getChildren());
		} finally {
			if (cu != null) {
				cu.discardWorkingCopy();
			}
		}
	}

	/*
	 * Ensures that a type that is otherwise missing can be looked up using the working copy owner.
	 */
	public void testFindType1() throws Exception {
		WorkingCopyOwner owner = new WorkingCopyOwner() {
			public String findSource(String typeName, String packageName) {
				if ("to.be".equals(packageName) && "Generated".equals(typeName)) {
					return
						"package to.be;\n" +
						"public class Generated {\n" +
						"}";
				}
				return super.findSource(typeName, packageName);
			}
			public boolean isPackage(String[] pkg) {
				switch (pkg.length) {
				case 1:
					return "to".equals(pkg[0]);
				case 2:
					return "to".equals(pkg[0]) && "be".equals(pkg[1]);
				}
				return false;
			}
		};
		assertProblems(
			"",
			"/P/X.java",
			"public class X extends to.be.Generated {\n" +
			"}", 
			owner);
	}

	/*
	 * Ensures that a type that is otherwise available can be hidden using the working copy owner.
	 */
	public void testFindType2() throws Exception {
		try {
			createFile("/P/Y.java", "public class Y {}");
			WorkingCopyOwner owner = new WorkingCopyOwner() {
				public String findSource(String typeName, String packageName) {
					if ("".equals(packageName) && "Y".equals(typeName)) {
						return "";
					}
					return super.findSource(typeName, packageName);
				}
			};
			assertProblems(
				"1. ERROR in /P/X.java (at line 1)\n" + 
				"	public class X extends Y {\n" + 
				"	                       ^\n" + 
				"Y cannot be resolved to a type\n" + 
				"----------\n",
				"/P/X.java",
				"public class X extends Y {\n" +
				"}", 
				owner);
		} finally {
			deleteFile("/P/Y.java");
		}
	}

	/*
	 * Ensures that getCorrespondingResource() returns a non-null value for a primary working copy.
	 * (regression test for bug 44065 NPE during hot code replace)
	 */
	public void testGetCorrespondingResource() throws CoreException {
		ICompilationUnit cu = null;
		try {
			cu = getCompilationUnit("P/X.java");
			cu.becomeWorkingCopy(null);
			assertResourceNamesEqual(
				"Unexpected resource",
				"X.java",
				new Object[] {cu.getCorrespondingResource()});
		} finally {
			if (cu != null) {
				cu.discardWorkingCopy();
			}
		}
	}

	/*
	 * Ensures that getOwner() returns the correct owner for a non-primary working copy.
	 */
	public void testGetOwner1() throws CoreException {
		ICompilationUnit cu = getCompilationUnit("P/X.java");
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = cu.getWorkingCopy(owner, null);

		assertEquals("Unexpected owner", owner, this.workingCopy.getOwner());
	}

	/*
	 * Ensures that getOwner() returns null for a primary compilation unit.
	 */
	public void testGetOwner2()  {
		ICompilationUnit cu = getCompilationUnit("P/X.java");
		assertEquals("Unexpected owner", null, cu.getOwner());
	}

	/*
	 * Ensures that getPrimary() on a non-primary working copy returns the primary compilation unit.
	 */
	public void testGetPrimary1() throws CoreException {
		ICompilationUnit cu = getCompilationUnit("P/X.java");
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = cu.getWorkingCopy(owner, null);

		assertEquals("Unexpected compilation unit", cu, this.workingCopy.getPrimary());
	}

	/*
	 * Ensures that getPrimary() on a primary working copy returns the same handle.
	 */
	public void testGetPrimary2() throws CoreException {
		this.workingCopy = getCompilationUnit("P/X.java");
		this.workingCopy.becomeWorkingCopy(null);

		assertEquals("Unexpected compilation unit", this.workingCopy, this.workingCopy.getPrimary());
	}

	/*
	 * Ensures that getPrimaryElement() on an element of a non-primary working copy returns
	 * an element ofthe primary compilation unit.
	 */
	public void testGetPrimaryElement1() throws CoreException {
		ICompilationUnit cu = getCompilationUnit("P/X.java");
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = cu.getWorkingCopy(owner, null);
		IJavaElement element = this.workingCopy.getType("X");

		assertEquals("Unexpected element", cu.getType("X"), element.getPrimaryElement());
	}

	/*
	 * Ensures that getPrimaryElement() on an element of primary working copy returns the same handle.
	 */
	public void testGetPrimaryElement2() throws CoreException {
		this.workingCopy = getCompilationUnit("P/X.java");
		this.workingCopy.becomeWorkingCopy(null);
		IJavaElement element = this.workingCopy.getType("X");

		assertEquals("Unexpected element", element, element.getPrimaryElement());
	}

	/*
	 * Ensures that getPrimaryElement() on an package fragment returns the same handle.
	 */
	public void testGetPrimaryElement3()  {
		IPackageFragment pkg = getPackage("P");
		assertEquals("Unexpected element", pkg, pkg.getPrimaryElement());
	}

	/*
	 * Ensures that getPrimaryElement() on an initializer of a .class file returns the same handle.
	 */
	public void testGetPrimaryElement4() throws JavaModelException {
		IInitializer initializer = getClassFile("P/X.class").getType().getInitializer(1);
		assertEquals("Unexpected element", initializer, initializer.getPrimaryElement());
	}

	/*
	 * Ensures that the correct working copies are returned by JavaCore.getWorkingCopies(WorkingCopyOwner)
	 */
	public void testGetWorkingCopies() throws CoreException {
		ICompilationUnit workingCopy11 = null;
		ICompilationUnit workingCopy12 = null;
		ICompilationUnit workingCopy21 = null;
		try {
			// initialiy no working copies for this owner
			TestWorkingCopyOwner owner1 = new TestWorkingCopyOwner();
			assertSortedElementsEqual(
				"Unexpected working copies (1)",
				"",
				JavaCore.getWorkingCopies(owner1)
			);

			// create working copy on existing cu
			ICompilationUnit cu1 = getCompilationUnit("P/X.java");
			workingCopy11 = cu1.getWorkingCopy(owner1, null);
			assertSortedElementsEqual(
				"Unexpected working copies (2)",
				"[Working copy] X.java [in <default> [in <project root> [in P]]]",
				JavaCore.getWorkingCopies(owner1)
			);

			// create working copy on non-existing cu
			ICompilationUnit cu2 = getCompilationUnit("P/Y.java");
			workingCopy12 = cu2.getWorkingCopy(owner1, null);
			assertSortedElementsEqual(
				"Unexpected working copies (3)",
				"[Working copy] X.java [in <default> [in <project root> [in P]]]\n" +
				"[Working copy] Y.java [in <default> [in <project root> [in P]]]",
				JavaCore.getWorkingCopies(owner1)
			);

			// create working copy for another owner
			TestWorkingCopyOwner owner2 = new TestWorkingCopyOwner();
			workingCopy21 = cu1.getWorkingCopy(owner2, null);

			// owner2 should have the new working copy
			assertSortedElementsEqual(
				"Unexpected working copies (4)",
				"[Working copy] X.java [in <default> [in <project root> [in P]]]",
				JavaCore.getWorkingCopies(owner2)
			);

			// owner1 should still have the same working copies
			assertSortedElementsEqual(
				"Unexpected working copies (5)",
				"[Working copy] X.java [in <default> [in <project root> [in P]]]\n" +
				"[Working copy] Y.java [in <default> [in <project root> [in P]]]",
				JavaCore.getWorkingCopies(owner1)
			);

			// discard first working copy
			workingCopy11.discardWorkingCopy();
			assertSortedElementsEqual(
				"Unexpected working copies (6)",
				"[Working copy] Y.java [in <default> [in <project root> [in P]]]",
				JavaCore.getWorkingCopies(owner1)
			);
		} finally {
			if (workingCopy11 != null) {
				workingCopy11.discardWorkingCopy();
			}
			if (workingCopy12 != null) {
				workingCopy12.discardWorkingCopy();
			}
			if (workingCopy21 != null) {
				workingCopy21.discardWorkingCopy();
			}
		}
	}

	/*
	 * Ensures that getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
	 * returns the same working copy if called twice with the same working copy owner.
	 */
	public void testGetWorkingCopy1() throws CoreException {
		try {
			ICompilationUnit cu = getCompilationUnit("P/X.java");
			TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
			this.workingCopy = cu.getWorkingCopy(owner, null);

			assertEquals("Unexpected working copy", this.workingCopy, cu.getWorkingCopy(owner, null));
		} finally {
			if (this.workingCopy != null) {
				int max = 2;
				while (this.workingCopy.isWorkingCopy() && max-- > 0) {
					this.workingCopy.discardWorkingCopy();
				}
			}
		}
	}

	/*
	 * Ensures that getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
	 * returns a different working copy if called twice with a different working copy owner.
	 */
	public void testGetWorkingCopy2() throws CoreException {
		ICompilationUnit workingCopy1 = null;
		ICompilationUnit workingCopy2 = null;
		try {
			ICompilationUnit cu = getCompilationUnit("P/X.java");
			TestWorkingCopyOwner owner1 = new TestWorkingCopyOwner();
			workingCopy1 = cu.getWorkingCopy(owner1, null);
			TestWorkingCopyOwner owner2 = new TestWorkingCopyOwner();
			workingCopy2 = cu.getWorkingCopy(owner2, null);

			assertTrue("working copies should be different", !workingCopy1.equals(workingCopy2));
		} finally {
			if (workingCopy1 != null) {
				workingCopy1.discardWorkingCopy();
			}
			if (workingCopy2 != null) {
				workingCopy2.discardWorkingCopy();
			}
		}
	}

	/*
	 * Ensure that the hierarchy using a working copy owner doesn't have primary working copy owner type
	 * that are hidden by a type of the working copy owner
	 * (regression test for bug 133372 [hierarchy] Type hierarchy returns type twice if executed on working copy layer)
	 */
	public void testHierarchy() throws CoreException {
		try {
			createFile(
				"/P/Y.java",
				"public class Y extends X {\n" +
				"}"
			);
			WorkingCopyOwner owner = new TestWorkingCopyOwner();
			this.workingCopy = getCompilationUnit("/P/Y.java").getWorkingCopy(owner, null/*no progress*/);
			IType focus = getCompilationUnit("/P/X.java").getType("X");
			ITypeHierarchy hierarchy = focus.newTypeHierarchy(owner, null/*no progress*/);
			IType[] subtypes = hierarchy.getSubtypes(focus);
			assertTypesEqual(
				"Unexpected types",
				"Y\n",
				subtypes);
		} finally {
			deleteFile("/P/Y.java");
		}
	}

	/*
	 * Ensures that moving a primary working copy from one package to another removes that
	 * working copy from the original package.
	 * (regression test for bug 43847 IPackageFragment not updated after CUs have moved)
	 */
	public void testMoveWorkingCopy() throws CoreException {
		try {
			createFolder("/P/p1");
			createFile(
				"/P/p1/Y.java",
				"package p1;\n" +
				"public class Y {\n" +
				"}"
			);
			createFolder("/P/p2");
			this.workingCopy = getCompilationUnit("P/p1/Y.java");
			this.workingCopy.becomeWorkingCopy(null);

			// ensure the package is open
			getPackage("/P/p1").open(null);

			this.workingCopy.move(getPackage("/P/p2"), null, null, false, null);
			assertElementDescendants(
				"Unexpected content of /P/p1",
				"p1",
				getPackage("/P/p1"));
		} finally {
			deleteFolder("P/p1");
			deleteFolder("P/p2");
		}
	}

	/*
	 * Ensures that creating a new working copy with no resource works.
	 */
	public void testNewWorkingCopy01() throws JavaModelException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		assertTrue("Working copy should exist", this.workingCopy.exists());
	}

	/*
	 * Ensures that the children of a new working copy with no resource are correct.
	 */
	public void testNewWorkingCopy02() throws CoreException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		assertElementDescendants(
			"Unexpected children",
			"[Working copy] X.java\n" +
			"  class X",
			this.workingCopy);
	}

	/*
	 * Ensures that the path of a new working copy with no resource is correct.
	 */
	public void testNewWorkingCopy03() throws CoreException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		assertEquals("Unexpected path", "/" + ExternalJavaProject.EXTERNAL_PROJECT_NAME + "/X.java", this.workingCopy.getPath().toString());
	}

	/*
	 * Ensures that the resource of a new working copy does not exist.
	 */
	public void testNewWorkingCopy04() throws CoreException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		assertFalse("Unexpected resource", this.workingCopy.getResource().exists());
	}

	/*
	 * Ensures that a new working copy with no resource can be reconciled and that the delta is correct.
	 */
	public void testNewWorkingCopy05() throws CoreException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		this.workingCopy.getBuffer().setContents(
			"public class X {\n" +
			"  int field;\n" +
			"}"
		);
		try {
			startDeltas();
			this.workingCopy.reconcile(ICompilationUnit.NO_AST, false, null, null);
			assertWorkingCopyDeltas(
				"Unexpected delta",
				"X[*]: {CHILDREN | FINE GRAINED}\n" +
				"	field[+]: {}"
			);
		} finally {
			stopDeltas();
		}
	}

	/*
	 * Ensures that a new working copy with no resource can be reconciled and that the resulting AST is correct.
	 */
	public void testNewWorkingCopy06() throws CoreException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		this.workingCopy.getBuffer().setContents(
			"public class X {\n" +
			"  int field;\n" +
			"}"
		);
		CompilationUnit ast = this.workingCopy.reconcile(JLS3_INTERNAL, false, null, null);
		assertASTNodeEquals(
			"Unexpected AST",
			"public class X {\n" +
			"  int field;\n" +
			"}\n",
			ast);
	}

	/*
	 * Ensures that no bindings are created when reconciling a new working copy with no resource.
	 */
	public void testNewWorkingCopy07() throws CoreException {
		this.workingCopy =  newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		this.workingCopy.getBuffer().setContents(
			"public class X {\n" +
			"  int field;\n" +
			"}"
		);
		CompilationUnit ast = this.workingCopy.reconcile(JLS3_INTERNAL, true/*force resolution*/, null, null);
		TypeDeclaration type = (TypeDeclaration) ast.types().get(0);
		assertNull("Unexpected binding", type.resolveBinding());
	}

	/*
	 * Ensures that a new working copy with no resource can be committed (its buffer is saved).
	 */
	public void testNewWorkingCopy08() throws CoreException {
		WorkingCopyOwner owner = new WorkingCopyOwner() {
			public IBuffer createBuffer(ICompilationUnit wc) {
				IBuffer buffer = new TestBuffer(wc);
				buffer.setContents(
					"public class X {\n" +
					"}"
				);
				return buffer;
			}
		};
		this.workingCopy = owner.newWorkingCopy("X.java", null/*no classpath*/, null/*no progress monitor*/);
		this.workingCopy.commitWorkingCopy(true, null);
		assertFalse("Should not have unsaved changes", this.workingCopy.hasUnsavedChanges());
	}

	/*
	 * Ensures that a Java project named " " doesn't exist if a working copy with no resource is created.
	 * (regression test for bug 138999 Regression: Fix for 128258 introduces regression in JavaProject.exists())
	 */
	public void testNewWorkingCopy09() throws CoreException {
		this.workingCopy = newExternalWorkingCopy(
			"X.java",
			"public class X {\n" +
			"}"
		);
		assertFalse("Java project named \" \" should not exist", getJavaProject(ExternalJavaProject.EXTERNAL_PROJECT_NAME).exists());
	}

	/**
	 * Ensures that creating a DOM AST and computing the bindings takes the owner's working copies into account.
	 * (regression test for bug 39533 Working copy with no corresponding file not considered by NameLookup)
	 * @deprecated using deprecated code
	 */
	public void testParseCompilationUnit1() throws CoreException {
		ICompilationUnit workingCopy1 = null;
		ICompilationUnit workingCopy2 = null;
		try {
			TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
			workingCopy1 = getCompilationUnit("P/X.java").getWorkingCopy(owner, null);
			workingCopy1.getBuffer().setContents(
				"public class X implements I {\n" +
				"}"
			);
			workingCopy1.makeConsistent(null);

			workingCopy2 = getCompilationUnit("P/I.java").getWorkingCopy(owner, null);
			workingCopy2.getBuffer().setContents(
				"public interface I {\n" +
				"}"
			);
			workingCopy2.makeConsistent(null);

			ASTParser parser = ASTParser.newParser(AST.JLS2);
			parser.setSource(workingCopy1);
			parser.setResolveBindings(true);
			parser.setWorkingCopyOwner(owner);
			CompilationUnit cu = (CompilationUnit) parser.createAST(null);
			List types = cu.types();
			assertEquals("Unexpected number of types in AST", 1, types.size());
			TypeDeclaration type = (TypeDeclaration)types.get(0);
			ITypeBinding typeBinding = type.resolveBinding();
			assertTypeBindingsEqual(
				"Unexpected interfaces",
				"I",
				typeBinding.getInterfaces());
		} finally {
			if (workingCopy1 != null) {
				workingCopy1.discardWorkingCopy();
			}
			if (workingCopy2 != null) {
				workingCopy2.discardWorkingCopy();
			}
		}
	}

	/**
	 * Ensures that creating a DOM AST and computing the bindings takes the owner's working copies into account.
	 * @deprecated using deprecated code
	 */
	public void testParseCompilationUnit2() throws CoreException {
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = getCompilationUnit("P/Y.java").getWorkingCopy(owner, null);
		this.workingCopy.getBuffer().setContents(
			"public class Y {\n" +
			"}"
		);
		this.workingCopy.makeConsistent(null);

		char[] source = (
			"public class Z extends Y {\n" +
			"}").toCharArray();
		ASTParser parser = ASTParser.newParser(AST.JLS2);
		parser.setSource(source);
		parser.setUnitName("Z.java");
		parser.setProject(getJavaProject("P"));
		parser.setWorkingCopyOwner(owner);
		parser.setResolveBindings(true);
		CompilationUnit cu = (CompilationUnit) parser.createAST(null);

		List types = cu.types();
		assertEquals("Unexpected number of types in AST", 1, types.size());
		TypeDeclaration type = (TypeDeclaration)types.get(0);
		ITypeBinding typeBinding = type.resolveBinding();
		assertNotNull("No binding", typeBinding);
		assertEquals(
			"Unexpected super type",
			"Y",
			typeBinding.getSuperclass().getQualifiedName());
	}

	/**
	 * Ensures that creating a DOM AST and computing the bindings takes the owner's working copies into account.
	 * @deprecated using deprecated code
	 */
	public void testParseCompilationUnit3() throws CoreException {
		try {
			createJavaProject("P1", new String[] {"src"}, new String[] {"JCL_LIB", "lib"}, "bin");

			// create X.class in lib folder
			/* Evaluate the following in a scrapbook:
				org.eclipse.jdt.core.tests.model.ModifyingResourceTests.generateClassFile(
					"X",
					"public class X {\n" +
					"}")
			*/
			byte[] bytes = new byte[] {
				-54, -2, -70, -66, 0, 3, 0, 45, 0, 13, 1, 0, 1, 88, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 7, 0, 3, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 12, 0, 5, 0, 6, 10, 0, 4, 0, 8, 1, 0, 15, 76, 105, 110, 101, 78, 117,
				109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 6, 88, 46, 106, 97, 118, 97, 0, 33, 0, 2, 0, 4, 0, 0, 0, 0, 0, 1, 0, 1, 0, 5, 0, 6, 0, 1, 0, 7, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 9, -79, 0, 0, 0, 1, 0, 10, 0, 0, 0, 6,
				0, 1, 0, 0, 0, 1, 0, 1, 0, 11, 0, 0, 0, 2, 0, 12,
			};
			this.createFile("P1/lib/X.class", bytes);

			// create libsrc and attach source
			createFolder("P1/libsrc");
			createFile(
				"P1/libsrc/X.java",
				"public class X extends Y {\n" +
				"}"
			);
			IPackageFragmentRoot lib = getPackageFragmentRoot("P1/lib");
			lib.attachSource(new Path("/P1/libsrc"), null, null);

			// create Y.java in src folder
			createFile("P1/src/Y.java", "");

			// create working copy on Y.java
			TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
			this.workingCopy = getCompilationUnit("P1/src/Y.java").getWorkingCopy(owner, null);
			this.workingCopy.getBuffer().setContents(
				"public class Y {\n" +
				"}"
			);
			this.workingCopy.makeConsistent(null);

			// parse and resolve class file
			IClassFile classFile = getClassFile("P1/lib/X.class");
			ASTParser parser = ASTParser.newParser(AST.JLS2);
			parser.setSource(classFile);
			parser.setResolveBindings(true);
			parser.setWorkingCopyOwner(owner);
			CompilationUnit cu = (CompilationUnit) parser.createAST(null);
			List types = cu.types();
			assertEquals("Unexpected number of types in AST", 1, types.size());
			TypeDeclaration type = (TypeDeclaration)types.get(0);
			ITypeBinding typeBinding = type.resolveBinding();
			ITypeBinding superType = typeBinding.getSuperclass();
			assertEquals(
				"Unexpected super type",
				"Y",
				superType == null ? "<null>" : superType.getQualifiedName());
		} finally {
			deleteProject("P1");
		}
	}

	/*
	 * Ensures that searching takes the owner's working copies into account.
	 */
	public void testSearch1() throws CoreException {
		ICompilationUnit cu = getCompilationUnit("P/Y.java");
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = cu.getWorkingCopy(owner, null);
		this.workingCopy.getBuffer().setContents(
			"public class Y {\n" +
			"  X field;\n" +
			"}"
		);
		this.workingCopy.makeConsistent(null);

		SearchPattern pattern = SearchPattern.createPattern(
			"X",
			IJavaSearchConstants.TYPE,
			IJavaSearchConstants.REFERENCES,
			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
		JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
		new SearchEngine(owner).search(
			pattern,
			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
			SearchEngine.createWorkspaceScope(),
			resultCollector,
			null);
		assertEquals(
			"Y.java Y.field [X]",
			resultCollector.toString());
	}

	/*
	 * Ensures that searching takes the owner's working copies into account.
	 */
	public void testSearch2() throws CoreException {
		ICompilationUnit cu = getCompilationUnit("P/X.java");
		TestWorkingCopyOwner owner = new TestWorkingCopyOwner();
		this.workingCopy = cu.getWorkingCopy(owner, null);

		// remove type X
		this.workingCopy.getBuffer().setContents("");
		this.workingCopy.makeConsistent(null);

		SearchPattern pattern = SearchPattern.createPattern(
			"X",
			IJavaSearchConstants.TYPE,
			IJavaSearchConstants.DECLARATIONS,
			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
		JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
		new SearchEngine(owner).search(
			pattern,
			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
			SearchEngine.createWorkspaceScope(),
			resultCollector,
			null);
		assertEquals(
			"", // should not find any in the owner's context
			resultCollector.toString());
	}

	/*
	 * Ensures that searching takes the primary owner's working copies into account only if the working copy
	 * is not saved.
	 */
	public void testSearch3() throws CoreException {
		try {
			createFile("/P/Y.java", "");
			this.workingCopy = getCompilationUnit("P/Y.java");
			this.workingCopy.becomeWorkingCopy(null);

			// create type Y in working copy
			this.workingCopy.getBuffer().setContents("public class Y {}");
			this.workingCopy.makeConsistent(null);

			JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
			search(
				"Y",
				IJavaSearchConstants.TYPE,
				IJavaSearchConstants.DECLARATIONS,
				SearchEngine.createWorkspaceScope(),
				resultCollector);
			assertEquals(
				"Y.java Y [Y]",
				resultCollector.toString());

			//	commit new type
			this.workingCopy.commitWorkingCopy(false, null);
			resultCollector = new JavaSearchTests.JavaSearchResultCollector();
			search(
				"Y",
				IJavaSearchConstants.TYPE,
				IJavaSearchConstants.DECLARATIONS,
				SearchEngine.createWorkspaceScope(),
				resultCollector);
			assertEquals(
				"Y.java Y [Y]",
				resultCollector.toString());
		} finally {
			deleteFile("/P/Y.java");
		}
	}

	/*
	 * Ensures that searching takes the primary owner's working copies and the given working copies into account.
	 * (regression test for bug 43300 SearchEngine(IWorkingCopy[] workingCopies) not backward compatible)
	 */
	public void testSearch4() throws CoreException {
		ICompilationUnit primaryWorkingCopy = null;
		try {
			createFolder("P/p");
			createFile("/P/p/Y.java", "");
			primaryWorkingCopy = getCompilationUnit("P/p/Y.java");
			primaryWorkingCopy.becomeWorkingCopy(null);

			// create type Y in working copy
			primaryWorkingCopy.getBuffer().setContents(
				"package p;\n" +
				"public class Y {\n" +
				"}");
			primaryWorkingCopy.makeConsistent(null);

			// create new working copy on X.java and add type X
			this.workingCopy = getCompilationUnit("P/p/X.java").getWorkingCopy(null);
			this.workingCopy.getBuffer().setContents(
				"package p;\n" +
				"public class X {\n" +
				"}"
			);
			this.workingCopy.makeConsistent(null);

			JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
			IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {primaryWorkingCopy.getParent()});
			SearchPattern pattern = SearchPattern.createPattern(
				"*",
				IJavaSearchConstants.TYPE,
				IJavaSearchConstants.DECLARATIONS,
				SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE);
			new SearchEngine(new ICompilationUnit[] {this.workingCopy}).search(
				pattern,
				new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
				scope,
				resultCollector,
				null);
			assertEquals(
				"p/X.java p.X [X]\n" +
				"p/Y.java p.Y [Y]",
				resultCollector.toString());

		} finally {
			if (primaryWorkingCopy != null) {
				primaryWorkingCopy.discardWorkingCopy();
			}
			deleteFile("/P/p/Y.java");
		}
	}

}
