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

import junit.framework.Test;

import org.eclipse.core.resources.IFile;

import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;

public class RenameTests extends CopyMoveTests {
	ICompilationUnit cu;
/**
 */
public RenameTests(String name) {
	super(name);
}
/**
 * Attempts to rename the elements with optional 
 * forcing. The operation should fail with the failure code.
 */
public void renameNegative(IJavaElement[] elements ,String[] renamings, boolean force, int failureCode) throws JavaModelException {
	try {
		//rename
	 	getJavaModel().rename(elements, new IJavaElement[]{elements[0].getParent()}, renamings, force, null);
	} catch (JavaModelException jme) {
		assertTrue("Code not correct for JavaModelException: "  + jme, jme.getStatus().getCode() == failureCode); 
		return;
	}
	assertTrue("The rename should have failed for multiple renaming", false);
	return;
}
/**
 * Attempts to rename the element with optional 
 * forcing. The operation should fail with the failure code.
 */
public void renameNegative(IJavaElement element, String rename, boolean force, int failureCode) throws JavaModelException {
	try {
		//rename
		getJavaModel().rename(new IJavaElement[] {element}, new IJavaElement[] {element.getParent()}, new String[] {rename}, force, null);
	} catch (JavaModelException jme) {
		assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
		return;
	}
	assertTrue("The rename should have failed for: " + element, false);
	return;
}
/**
 * Renames the element to the container with optional 
 * forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void renamePositive(IJavaElement[] elements, String[] names, boolean force) throws JavaModelException {
	renamePositive(elements, new IJavaElement[]{elements[0].getParent()}, names, force);
}
/**
 * Renames the element to the container with optional 
 * forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void renamePositive(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean force) throws JavaModelException {
	renamePositive(elements, destinations, names, force, false);
}
/**
 * Renames the element to the container with optional 
 * forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void renamePositive(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean force, boolean originalShouldExist) throws JavaModelException {
	renamePositive(elements, destinations, names, force, originalShouldExist, null);
}
/**
 * Renames the element to the container with optional 
 * forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void renamePositive(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean force, boolean originalShouldExist, IProgressMonitor monitor) throws JavaModelException {
	// if forcing, ensure that a name collision exists
	int i;
	if (force) {
		for (i = 0; i < elements.length; i++) {
			IJavaElement e = elements[i];
			IJavaElement collision = generateHandle(e, names[i], e.getParent());
			assertTrue("Collision does not exist", collision.exists());
		}
	}

	// rename
	getJavaModel().rename(elements, destinations, names, force, monitor);
	for (i = 0; i < elements.length; i++) {
		// generate the new element	handle
		IJavaElement e = elements[i];
		IJavaElement renamed = generateHandle(e, names[i], e.getParent());
		assertTrue("Renamed element should exist", renamed.exists());
		if (!originalShouldExist) {
			assertTrue("Original element should not exist", !e.exists());
		}
		IJavaElementDelta destDelta = getDeltaFor(renamed.getParent());
		if (isMainType(e, e.getParent())) {
			assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
			assertTrue("Added children not correct for element copy", destDelta.getElement().equals(renamed.getParent()));
			assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
			assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(e.getParent()));
		} else {
			assertTrue("Destination container not changed", destDelta != null && deltaChildrenChanged(destDelta));
			IJavaElementDelta[] deltas = destDelta.getAddedChildren();
			assertTrue("Added children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(renamed));
			assertTrue("kind should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
			deltas = destDelta.getRemovedChildren();
			assertTrue("Removed children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(e));
			assertTrue("kind should be K_REMOVED", deltas[i].getKind() == IJavaElementDelta.REMOVED);
		}
	}
}
/**
 * Renames the element to the container with optional 
 * forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void renamePositive(IJavaElement element, String rename, boolean force) throws JavaModelException {
	renamePositive(new IJavaElement[] {element}, new String[] {rename}, force);
}
/**
 * Setup for the next test.
 */
public void setUp() throws Exception {
	super.setUp();

	this.createJavaProject("P", new String[] {"src"}, "bin");
	this.createFile(
		"/P/src/X.java",
		"public class X {\n" +
		"  boolean other;\n" +
		"  int bar;\n" +
		"  {\n" +
		"    bar = 1;\n" +
		"  }\n" +
		"  X(int i) {\n" +
		"  }\n" +
		"  void otherMethod(String s) {\n" +
		"  }\n" +
		"  void foo(String s) {\n" +
		"  }\n" +
		"}"
	);
	this.cu = getCompilationUnit("/P/src/X.java");
	
	startDeltas();
}
public void setUpSuite() throws Exception {
	super.setUpSuite();
	
	IJavaProject project = this.createJavaProject("BinaryProject", new String[] {"src"}, new String[] {"JCL_LIB"}, "lib");
	this.createFile(
		"/BinaryProject/src/X.java",
		"public class X {\n" +
		"  int bar;\n" +
		"  public void foo() {\n" +
		"  }\n" +
		"}"
	);
	project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
	project.setRawClasspath(
		new IClasspathEntry[] {
			JavaCore.newLibraryEntry(new Path("/BinaryProject/lib"), null, null)
		},
		null
	);
}
public static Test suite() {
	return new Suite(RenameTests.class);
}
/**
 * Cleanup after the previous test.
 */
public void tearDown() throws Exception {
	stopDeltas();
	this.deleteProject("P");

	super.tearDown();
}
public void tearDownSuite() throws Exception {
	this.deleteProject("BinaryProject");
	super.tearDownSuite();
}
/**
 * Ensures that a binary field cannot be renamed.
 */
public void testRenameBinaryField() throws JavaModelException {
	IClassFile cf = getClassFile("BinaryProject", "lib", "", "X.class");
	IField binaryField = cf.getType().getField("bar");
	renameNegative(binaryField, "fred", false, IJavaModelStatusConstants.READ_ONLY);
}
/**
 * Ensures that a binary method cannot be renamed.
 */
public void testRenameBinaryMethod() throws JavaModelException {
	IClassFile cf = getClassFile("BinaryProject", "lib", "", "X.class");
	IMethod binaryMethod = cf.getType().getMethods()[0];
	renameNegative(binaryMethod, "fred", false, IJavaModelStatusConstants.READ_ONLY);
}
/**
 * Ensures that a binary type cannot be renamed.
 */
public void testRenameBinaryType() throws JavaModelException {
	IClassFile cf = getClassFile("BinaryProject", "lib", "", "X.class");
	IType binaryType = cf.getType();
	renameNegative(binaryType, "Y", false, IJavaModelStatusConstants.READ_ONLY);
}

/**
 * This operation should fail as renaming a CU and a CU member at the
 * same time is not supported.
 */
public void testRenameCompilationUnitAndType() throws CoreException {
	renameNegative(
		new IJavaElement[] {this.cu, this.cu.getType("X")}, 
		new String[]{"Y.java", "Y"}, 
		false, 
		IJavaModelStatusConstants.INVALID_ELEMENT_TYPES);
}
/**
 * Ensures that compilation units cannot be renamed to an existing cu name
 * unless the force flag is set.
 */
public void testRenameCompilationUnitResultingInCollision() throws CoreException{
	this.createFile(
		"/P/src/Y.java",
		"public class Y {\n" +
		"}"
	);
	
	renameNegative(this.cu, "Y.java", false, IJavaModelStatusConstants.NAME_COLLISION);
	renamePositive(this.cu, "Y.java", true);
}
/**
 * Ensures that compilation units can be renamed.
 * Verifies that the proper change deltas are generated as a side effect
 * of running the operation.
 */
public void testRenameCompilationUnitsCheckingDeltas() throws CoreException{
	this.createFile(
		"/P/src/Y.java",
		"public class Y {\n" +
		"}"
	);
	ICompilationUnit cu2 = this.getCompilationUnit("/P/src/Y.java");
	
	clearDeltas();
	renamePositive(
		new ICompilationUnit[] {this.cu, cu2}, 
		new String[] {"NewX.java", "NewY.java"}, 
		false);
	
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		[default][*]: {CHILDREN}\n" + 
		"			X.java[-]: {MOVED_TO(NewX.java [in [default] [in src [in P]]])}\n" + 
		"			NewX.java[+]: {MOVED_FROM(X.java [in [default] [in src [in P]]])}\n" + 
		"			Y.java[-]: {MOVED_TO(NewY.java [in [default] [in src [in P]]])}\n" + 
		"			NewY.java[+]: {MOVED_FROM(Y.java [in [default] [in src [in P]]])}"
	);
}
/**
 * Ensures that a compilation unit cannot be renamed to an invalid name.  
 * The new name for a cu must end in .java and be a valid Java identifier.
 */
public void testRenameCompilationUnitWithInvalidName() throws JavaModelException {
	renameNegative(this.cu, "NewX", false, IJavaModelStatusConstants.INVALID_NAME);
	renameNegative(this.cu, "New X.java", false, IJavaModelStatusConstants.INVALID_NAME);
}
/**
 * This operation should fail as renaming a CU with a null name should throw
 * an <code>IllegalArgumentException</code>
 */
public void testRenameCompilationUnitWithNull() throws JavaModelException {
	try {
		this.cu.rename(null, false, null);
	} catch (IllegalArgumentException iae) {
		return;
	}
	assertTrue("Should not be able to rename a cu with a null name", false);
}
/**
 * Ensures that a construtor cannot be renamed using the
 * <code>RenameElementsOperation</code>.  
 */
public void testRenameConstructor() throws JavaModelException {
	IMethod constructor = this.cu.getType("X").getMethod("X",  new String[] {"I"});
	renameNegative(constructor, "newName", false, IJavaModelStatusConstants.NAME_COLLISION);
}

/**
 * 
 */
public void testRenameCU() throws CoreException {
	this.cu.rename("NewX.java", false, null);
	assertTrue("Original CU should not exist", !cu.exists());

	ICompilationUnit newCU = getCompilationUnit("/P/src/NewX.java");
	assertTrue("New CU should exist", newCU.exists());
	
	assertTypesEqual(
		"Unexpected types",
		"NewX\n",
		newCU.getAllTypes());

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		[default][*]: {CHILDREN}\n" + 
		"			X.java[-]: {MOVED_TO(NewX.java [in [default] [in src [in P]]])}\n" + 
		"			NewX.java[+]: {MOVED_FROM(X.java [in [default] [in src [in P]]])}"
	);
}
public void testRenameCUForce() throws CoreException {
	this.createFile(
		"/P/src/Y.java",
		"public class Y {\n" +
		"}"
	);

	clearDeltas();
	this.cu.rename("Y.java", true, null);

	IFile file = (IFile)this.cu.getResource();
	ICompilationUnit destCU = getCompilationUnit("/P/src/Y.java");
	IFile destFile = (IFile)destCU.getResource();

	assertTrue("Original CU should not exist", !cu.exists());
	assertTrue("Original file should not exist", !file.exists());
	assertTrue("Destination CU should exist", destCU.exists());
	assertTrue("Destination file should exist", destFile.exists());
	
	assertTypesEqual(
		"Unexpected types",
		"Y\n",
		destCU.getAllTypes());

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		[default][*]: {CHILDREN}\n" + 
		"			X.java[-]: {MOVED_TO(Y.java [in [default] [in src [in P]]])}\n" + 
		"			Y.java[+]: {MOVED_FROM(X.java [in [default] [in src [in P]]])}"
	);
}
/*
 * Ensures that renaming an empty package fragment doesn't make it disappear
 * (regression test for bug 24505 Refactoring an empty package makes it disappears)
 */
public void testRenameEmptyPF() throws CoreException {
	this.createFolder("/P/src/x/y/z");

	clearDeltas();
	getPackage("/P/src/x/y/z").rename("x.y", false, null);
	
	IPackageFragment newFrag = getPackage("/P/src/x/y");
	assertTrue("New package should exist", newFrag.exists());
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		x.y.z[-]: {MOVED_TO(x.y [in src [in P]])}\n" + 
		"		x.y[+]: {MOVED_FROM(x.y.z [in src [in P]])}"
	);
}
/**
 * Ensures that fields can be renamed.  
 * Verifies that the proper change deltas are generated as a side effect
 * of running the operation. As well ensures that the fields are
 * positioned in the same location as before the rename.
 */
public void testRenameFieldsCheckingDeltasAndPositions() throws JavaModelException {
	IType type = this.cu.getType("X");
	IField field = type.getField("bar");
	renamePositive(field, "fred", false);
	
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		[default][*]: {CHILDREN}\n" + 
		"			X.java[*]: {CHILDREN | FINE GRAINED}\n" + 
		"				X[*]: {CHILDREN | FINE GRAINED}\n" + 
		"					fred[+]: {}\n" + 
		"					bar[-]: {}"
	);
	ensureCorrectPositioning((IParent)type, type.getField("fred"), type.getField("other"));
}
/**
 * Ensures that fields can be renamed even if one of the renamings fails.  
 */
public void testRenameFieldsMultiStatus() throws CoreException {
	String addition = "multiStatus";
	IType type = this.cu.getType("X");
	IField[] iFields = type.getFields();
	String[] newNames = new String[iFields.length];
	int i;
	for (i = 0; i < iFields.length; i++) {
		IField f = iFields[i];
		newNames[i] = addition + f.getElementName();
	}
	newNames[1] = ";"; //invalid name

	boolean e = false;
	try {
		type.getJavaModel().rename(iFields, new IJavaElement[] {type}, newNames, false, null);
	} catch (JavaModelException jme) {
		assertTrue("Should not be multistatus (only one failure)", !jme.getStatus().isMultiStatus());
		assertTrue("Should be an invalid destination", jme.getStatus().getCode() == IJavaModelStatusConstants.INVALID_NAME);
		e = true;
	}
	assertTrue("Should have been an exception", e);
	
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		[default][*]: {CHILDREN}\n" + 
		"			X.java[*]: {CHILDREN | FINE GRAINED}\n" + 
		"				X[*]: {CHILDREN | FINE GRAINED}\n" + 
		"					multiStatusother[+]: {}\n" + 
		"					other[-]: {}"
	);
	
	IJavaElement copy = generateHandle(iFields[0], newNames[0], type);
	assertTrue("Copy should exist", copy.exists());
}
/**
 * Ensures that fields cannot be renamed to the same name.
 */
public void testRenameFieldsResultingInCollision() throws JavaModelException {
	String addition = "new";
	IType type= this.cu.getType("X");
	IField[] iFields = type.getFields();
	String[] newNames = new String[iFields.length];
	int i;
	for (i = 0; i < iFields.length; i++) {
		IField f = iFields[i];
		newNames[i] = addition + f.getElementName();
	}
	//set two fields to have the same new name
	newNames[i-1]= newNames[i-2];

	renameNegative(iFields, newNames, false, IJavaModelStatusConstants.NAME_COLLISION);
}
/**
 * Ensures that renaming can be canceled.
 */
public void testRenameFieldsWithCancel() throws CoreException {
	boolean isCanceled = false;
	String addition = "new1";
	IType type = RenameTests.this.cu.getType("X");
	IField[] iFields = type.getFields();
	String[] newNames = new String[iFields.length];
	int i;
	for (i = 0; i < iFields.length; i++) {
		IField f = iFields[i];
		newNames[i] = addition + f.getElementName();
	}
	try {
		TestProgressMonitor monitor = TestProgressMonitor.getInstance();
		monitor.setCancelledCounter(1);
		renamePositive(iFields, new IJavaElement[] {type}, newNames, false, false, monitor);
	} catch (OperationCanceledException e) {
		isCanceled = true;
	}
	assertTrue("Operation should have thrown an operation canceled exception", isCanceled);
}
/**
 * Ensures that an initializer cannot be renamed.
 */
public void testRenameInitializer() throws JavaModelException {
	IType typeSource= this.cu.getType("X");
	IInitializer initializerSource= typeSource.getInitializer(1);

	renameNegative(initializerSource, "someName", false, IJavaModelStatusConstants.INVALID_ELEMENT_TYPES);
}
/**
 * Ensures that main types can be renamed. As a side effect
 * of renaming the main types, the types' enclosing compilation unit
 * are renamed as well.
 */
public void testRenameMainTypes() throws CoreException {
	this.createFile(
		"/P/src/Y.java",
		"public class Y {\n" +
		"  public Y() {\n" +
		"  }\n" +
		"}"
	);
	ICompilationUnit cu2 = getCompilationUnit("/P/src/Y.java");
	IPackageFragment pkg = (IPackageFragment) this.cu.getParent();

	IJavaElement[] types = new IJavaElement[] {
		this.cu.getType("X"),
		cu2.getType("Y")
	};
	String[] newNames = new String[] {"NewX", "NewY"};
	renamePositive(
		new IJavaElement[] {
			this.cu.getType("X"),
			cu2.getType("Y")
		}, 
		new IJavaElement[] {
			types[0].getParent(), 
			types[1].getParent()}, 
		newNames, 
		false);

	//test that both the compilation unit, main type and constructors have been renamed.
	ICompilationUnit renamedCU1= pkg.getCompilationUnit("NewX.java");
	ICompilationUnit renamedCU2= pkg.getCompilationUnit("NewY.java");
	IType newType1 = renamedCU1.getType("NewX");
	IType newType2 = renamedCU2.getType("NewY");
	assertTrue("NewX should be present", newType1.exists());
	assertTrue("NewY should be present", newType2.exists());
	
	IMethod constructor1 = newType1.getMethod("NewX", new String[] {"I"});
	IMethod constructor2 = newType2.getMethod("NewY", new String[] {});
	assertTrue("NewX(int) should be present", constructor1.exists());
	assertTrue("NewY() should be present", constructor2.exists());
}
/**
 * Ensures that main types can be renamed as well as a child of a main type. As a side effect
 * of renaming the main types, the types enclosing compilation unit
 * are renamed as well.
 * @see 1FTKMBD: ITPJCORE:ALL - JM- Cannot rename parent and child with the same operation
 */
public void testRenameMainTypesAndAChild() throws CoreException {
	this.createFile(
		"/P/src/Y.java",
		"public class Y {\n" +
		"  public Y() {\n" +
		"  }\n" +
		"}"
	);
	ICompilationUnit cu2 = getCompilationUnit("/P/src/Y.java");

	String[] newNames = new String[] {
		"newBar",
		"NewX",
		"NewY"
	};
	IJavaElement[] elements = new IJavaElement[] {
		this.cu.getType("X").getField("bar"),
		this.cu.getType("X"),
		cu2.getType("Y")
	};
	IJavaElement[] destinations = new IJavaElement[elements.length];
	for (int i = 0; i < elements.length; i++) {
		destinations[i] = elements[i].getParent();
	}
	
	getJavaModel().rename(elements, destinations, newNames, false, null);

	//test that both the compilation unit and the main type have been renamed.
	IPackageFragment pkg = (IPackageFragment) this.cu.getParent();
	ICompilationUnit renamedCU1= pkg.getCompilationUnit("NewX.java");
	IType newX = renamedCU1.getType("NewX");
	assertTrue("NewX should be present", newX.exists());
	
	ICompilationUnit renamedCU2= pkg.getCompilationUnit("NewY.java");
	IType newY = renamedCU2.getType("NewY");
	assertTrue("NewY should be present", newY.exists());
	
	IField newBar = newX.getField("newBar");
	assertTrue("Renamed field should exist", newBar.exists());
}
/**
 * Ensures that a method can be renamed.
 */
public void testRenameMethod() throws JavaModelException {
	IType type = this.cu.getType("X");
	IMethod method = type.getMethod("foo", new String[] {"QString;"});
	renamePositive(method, "newFoo", false);
	
	//ensure that the method did not move as a result of the rename
	ensureCorrectPositioning(
		type, 
		type.getMethod("newFoo", new String[] {"QString;"}), 
		type.getMethod("otherMethod", new String[] {"QString;"}));
}
/**
 * Ensures that a method cannot be renamed to an existing method name.
 */
public void testRenameMethodResultingInCollision() throws JavaModelException {
	IType type = this.cu.getType("X");
	IMethod method = type.getMethod("foo", new String[] {"QString;"});
	renameNegative(method, "otherMethod", false, IJavaModelStatusConstants.NAME_COLLISION);
}
/**
 * Ensures that a method cannot be renamed to an invalid method name
 */
public void testRenameMethodsWithInvalidName() throws JavaModelException {
	IMethod method = this.cu.getType("X").getMethod("foo", new String[] {"QString;"});
	renameNegative(method, "%%someInvalidName", false, IJavaModelStatusConstants.INVALID_NAME);
}
public void testRenamePF() throws CoreException {
	this.createFolder("/P/src/x/y/z");
	this.createFile(
		"/P/src/x/y/z/A.java",
		"package x.y.z;\n" +
		"public class A {\n" +
		"}"
	);

	IPackageFragment frag = getPackage("/P/src/x/y/z");
	clearDeltas();
	frag.rename("x.y.newZ", false, null);
	
	IPackageFragment newFrag = getPackage("/P/src/x/y/newZ");
	assertTrue("Old package should not exist", !frag.exists());
	assertTrue("New package should exist", newFrag.exists());

	ICompilationUnit compilationUnit = newFrag.getCompilationUnit("A.java");
	assertTrue("A.java should exits in new package", compilationUnit.exists());
	
	IType[] types = compilationUnit.getTypes();
	assertTrue(types != null && types.length == 1);
	IType mainType = types[0];
	assertEquals(
		"Unexpected A.java's main type'", 
		"x.y.newZ.A",
		mainType.getFullyQualifiedName());

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		x.y.z[-]: {MOVED_TO(x.y.newZ [in src [in P]])}\n" + 
		"		x.y.newZ[+]: {MOVED_FROM(x.y.z [in src [in P]])}"
	);
}
/*
 * Ensures that renaming to a name containing spaces works
 * (regression test for bug 21957 'refactor rename' allows subpackage name to start with a space)
 */
public void testRenamePF2() throws CoreException {
	this.createFolder("/P/src/x/y/z");
	this.createFile(
		"/P/src/x/y/z/A.java",
		"package x.y.z;\n" +
		"public class A {\n" +
		"}"
	);

	IPackageFragment frag = getPackage("/P/src/x/y/z");
	clearDeltas();
	frag.rename("x.y. z2", false, null);
	
	IPackageFragment newFrag = getPackage("/P/src/x/y/z2");
	assertTrue("Old package should not exist", !frag.exists());
	assertTrue("New package should exist", newFrag.exists());

	ICompilationUnit compilationUnit = newFrag.getCompilationUnit("A.java");
	assertTrue("A.java should exits in new package", compilationUnit.exists());
	
	IType[] types = compilationUnit.getTypes();
	assertTrue(types != null && types.length == 1);
	IType mainType = types[0];
	assertEquals(
		"Unexpected A.java's main type'", 
		"x.y.z2.A",
		mainType.getFullyQualifiedName());

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		x.y.z[-]: {MOVED_TO(x.y.z2 [in src [in P]])}\n" + 
		"		x.y.z2[+]: {MOVED_FROM(x.y.z [in src [in P]])}"
	);
}
public void testRenamePFWithSubPackages() throws CoreException {
	this.createFolder("/P/src/x/y/z");
	this.createFile(
		"/P/src/x/y/z/A.java",
		"package x.y.z;\n" +
		"public class A {\n" +
		"}"
	);

	clearDeltas();
	getPackage("/P/src/x").rename("newX", false, null);
	
	IPackageFragment oldFrag = getPackage("/P/src/x/y/z");
	assertTrue("Old inner package should still exist", oldFrag.exists());

	IPackageFragment newFrag = getPackage("/P/src/newX");
	assertTrue("New package should exist", newFrag.exists());

	ICompilationUnit compilationUnit = oldFrag.getCompilationUnit("A.java");
	assertTrue("A.java should exits in old inner package", compilationUnit.exists());
	
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" + 
		"	src[*]: {CHILDREN}\n" + 
		"		newX[+]: {}"
	);
}
/**
 * Ensures that a method can be renamed if it contains syntax errors.
 */
public void testRenameSyntaxErrorMethod() throws CoreException {
	this.createFile(
		"/P/src/Y.java",
		"public class Y {\n" +
		"  void foo( {\n" + // syntax error
		"  }\n" +
		"}"
	);
	IMethod method = getCompilationUnit("/P/src/Y.java").getType("Y").getMethod("foo", null);;
	renamePositive(method, "newFoo", false);
}
/**
 * Ensures that attempting to rename with an incorrect number of renamings fails
 */
public void testRenameWithInvalidRenamings() throws JavaModelException {
	IMethod method = getCompilationUnit("/P/src/X.java").getType("X").getMethod("foo", null);;

	renameNegative(
		new IJavaElement[] {method}, 
		new String[]{"", ""}, 
		false, 
		IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS);

	renameNegative(
		new IJavaElement[] {method}, 
		null, 
		false, 
		IJavaModelStatusConstants.NULL_NAME);
}
/**
 * Ensures that a working copy cannot be renamed.
 */
public void testRenameWorkingCopy() throws JavaModelException {
	IWorkingCopy copy = null;
	try {
		copy = (IWorkingCopy) this.cu.getWorkingCopy();
		renameNegative((IJavaElement)copy, "NewX", false, IJavaModelStatusConstants.INVALID_ELEMENT_TYPES);
	} finally {
		if (copy != null) copy.destroy();
	}
}

}
