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

import java.io.IOException;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.internal.resources.mapping.ResourceMapping;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CopyArguments;
import org.eclipse.ltk.core.refactoring.participants.CopyRefactoring;
import org.eclipse.ltk.core.refactoring.participants.ReorgExecutionLog;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportContainer;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IInitializer;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
import org.eclipse.jdt.internal.corext.refactoring.reorg.INewNameQueries;
import org.eclipse.jdt.internal.corext.refactoring.reorg.INewNameQuery;
import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgQueries;
import org.eclipse.jdt.internal.corext.refactoring.reorg.JavaCopyProcessor;
import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
import org.eclipse.jdt.internal.corext.util.JavaElementResourceMapping;

import org.eclipse.jdt.testplugin.JavaProjectHelper;

import org.eclipse.jdt.ui.tests.refactoring.ParticipantTesting;
import org.eclipse.jdt.ui.tests.refactoring.RefactoringTest;
import org.eclipse.jdt.ui.tests.refactoring.RefactoringTestSetup;


public class CopyTest extends RefactoringTest {

	private static final Class clazz= CopyTest.class;
	private static final String REFACTORING_PATH= "Copy/";

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

	public static Test suite() {
		return new RefactoringTestSetup(new TestSuite(clazz));
	}

	public static Test setUpTest(Test test) {
		return new RefactoringTestSetup(test);
	}

	protected String getRefactoringPath() {
		return REFACTORING_PATH;
	}

	private void verifyDisabled(IResource[] resources, IJavaElement[] javaElements) throws JavaModelException {
		assertTrue("copy should be disabled", ! RefactoringAvailabilityTester.isCopyAvailable(resources, javaElements));
		assertTrue(JavaCopyProcessor.create(resources, javaElements) == null);
	}

	private JavaCopyProcessor verifyEnabled(IResource[] resources, IJavaElement[] javaElements, INewNameQueries newNameQueries, IReorgQueries reorgQueries) throws JavaModelException {
		assertTrue("copy should be enabled", RefactoringAvailabilityTester.isCopyAvailable(resources, javaElements));
		JavaCopyProcessor processor= JavaCopyProcessor.create(resources, javaElements);
		assertNotNull(processor);
		if (newNameQueries != null)
			processor.setNewNameQueries(newNameQueries);
		if (reorgQueries != null)
			processor.setReorgQueries(reorgQueries);
		return processor;
	}
	
	private IReorgQueries createReorgQueries(){
		return new MockReorgQueries();
	}
	
	private void verifyInvalidDestination(JavaCopyProcessor processor, Object destination) throws Exception {
		RefactoringStatus status= null;
		if (destination instanceof IResource)
			status= processor.setDestination((IResource)destination);
		else if (destination instanceof IJavaElement)
			status= processor.setDestination((IJavaElement)destination);
		else assertTrue(false);
		
		assertEquals("destination was expected to be not valid",  RefactoringStatus.FATAL, status.getSeverity());
	}
	
	private void verifyValidDestination(JavaCopyProcessor processor, Object destination) throws Exception {
		RefactoringStatus status= null;
		if (destination instanceof IResource)
			status= processor.setDestination((IResource)destination);
		else if (destination instanceof IJavaElement)
			status= processor.setDestination((IJavaElement)destination);
		else assertTrue(false);
		
		assertEquals("destination was expected to be valid: " + status.getMessageMatchingSeverity(status.getSeverity()), RefactoringStatus.OK, status.getSeverity());
	}

	private void verifyCopyingOfSubCuElements(ICompilationUnit[] cus, Object destination, IJavaElement[] javaElements) throws JavaModelException, Exception, IOException {
		JavaCopyProcessor processor= verifyEnabled(new IResource[0], javaElements, new MockNewNameQueries(), createReorgQueries());
		verifyValidDestination(processor, destination);
		RefactoringStatus status= performRefactoring(new CopyRefactoring(processor), false);
		assertNull("failed precondition", status);
		for (int i= 0; i < cus.length; i++) {
			assertEqualLines("different source in " + cus[i].getElementName(), getFileContents(getOutputTestFileName(removeExtension(cus[i].getElementName()))), cus[i].getSource());
		}
	}

	private final RefactoringStatus performRefactoring(JavaCopyProcessor processor, boolean providesUndo) throws Exception {
		return performRefactoring(new CopyRefactoring(processor), false);
	}
	
	private static class MockNewNameQueries implements INewNameQueries{

		private static final String NEW_PACKAGE_NAME= "unused.name";
		private static final String NEW_PACKAGE_FOLDER_NAME= "name";
		private static final String NEW_PACKAGE_FRAGMENT_ROOT_NAME= "UnusedName";
		private static final String NEW_FILE_NAME= "UnusedName.gif";
		private static final String NEW_FOLDER_NAME= "UnusedName";
		private static final String NEW_CU_NAME= "UnusedName";
		
		public INewNameQuery createNewCompilationUnitNameQuery(ICompilationUnit cu, String s) {
			return createStaticQuery(NEW_CU_NAME);
		}

		public INewNameQuery createNewResourceNameQuery(IResource res, String s) {
			if (res instanceof IFile)
				return createStaticQuery(NEW_FILE_NAME);
			else
				return createStaticQuery(NEW_FOLDER_NAME);
		}

		public INewNameQuery createNewPackageNameQuery(IPackageFragment pack, String s) {
			return createStaticQuery(NEW_PACKAGE_NAME);
		}

		public INewNameQuery createNullQuery() {
			return createStaticQuery(null);
		}

		public INewNameQuery createStaticQuery(final String newName) {
			return new INewNameQuery(){
				public String getNewName() {
					return newName;
				}
			};
		}

		public INewNameQuery createNewPackageFragmentRootNameQuery(IPackageFragmentRoot root, String initialSuggestedName) {
			return createStaticQuery(NEW_PACKAGE_FRAGMENT_ROOT_NAME);
		}
	}
	
	private static class MockCancelNameQueries implements INewNameQueries{
		public INewNameQuery createNewCompilationUnitNameQuery(ICompilationUnit cu, String s) {
			return createNullQuery();
		}
		public INewNameQuery createNewResourceNameQuery(IResource res, String s) {
			return createNullQuery();
		}
		public INewNameQuery createNewPackageNameQuery(IPackageFragment pack, String s) {
			return createNullQuery();
		}
		public INewNameQuery createNullQuery() {
			return new INewNameQuery() {
				public String getNewName() {
					throw new OperationCanceledException();
				}
			};
		}
		public INewNameQuery createStaticQuery(final String newName) {
			return createNullQuery();
		}
		public INewNameQuery createNewPackageFragmentRootNameQuery(IPackageFragmentRoot root, String initialSuggestedName) {
			return createNullQuery();
		}
	}
	
	//---------------
	
	public void test_field_declared_in_multi_yes_type() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IField field= cu.getType("A").getField("bar");
			IType type= cu.getType("A");
			IJavaElement[] javaElements= { field };
			Object destination= type;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_fields_declared_in_multi_yes_type() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IField field1= cu.getType("A").getField("bar");
			IField field2= cu.getType("A").getField("baz");
			IType type= cu.getType("A");
			IJavaElement[] javaElements= { field1, field2 };
			Object destination= type;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_fields_declared_in_multi_yes_type_1() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IField field1= cu.getType("A").getField("var11");
			IField field2= cu.getType("A").getField("var2");
			IField field3= cu.getType("A").getField("var3");
			IType type= cu.getType("A");
			IJavaElement[] javaElements= { field1, field2, field3};
			Object destination= type;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDisabled_empty() throws Exception {
		IJavaElement[] javaElements= {};
		IResource[] resources= {};
		verifyDisabled(resources, javaElements);
	}
	
	public void testDisabled_null_element() throws Exception {
		IJavaElement[] javaElements= {null};
		IResource[] resources= {};
		verifyDisabled(resources, javaElements);
	}

	public void testDisabled_null_resource() throws Exception {
		IJavaElement[] javaElements= {};
		IResource[] resources= {null};
		verifyDisabled(resources, javaElements);
	}

	public void testDisabled_javaProject() throws Exception {
		IJavaElement[] javaElements= {RefactoringTestSetup.getProject()};
		IResource[] resources= {};
		verifyDisabled(resources, javaElements);
	}

	public void testDisabled_defaultPackage() throws Exception {
		IPackageFragment defaultPackage= getRoot().getPackageFragment("");
		assertTrue(defaultPackage.exists());
		IJavaElement[] javaElements= {defaultPackage};
		IResource[] resources= {};
		verifyDisabled(resources, javaElements);
	}

	public void testDisabled_project() throws Exception {
		IJavaElement[] javaElements= {};
		IResource[] resources= {RefactoringTestSetup.getProject().getProject()};
		verifyDisabled(resources, javaElements);
	}

	public void testDisabled_notExistingElement() throws Exception {
		ICompilationUnit notExistingCu= getPackageP().getCompilationUnit("NotMe.java");
		assertTrue(! notExistingCu.exists());
		IJavaElement[] javaElements= {notExistingCu};
		IResource[] resources= {};
		verifyDisabled(resources, javaElements);		
	}

	public void testDisabled_notExistingResource() throws Exception {
		IFolder folder= (IFolder)getPackageP().getResource();
		IFile notExistingFile= folder.getFile("a.txt");
		
		IJavaElement[] javaElements= {};
		IResource[] resources= {notExistingFile};
		verifyDisabled(resources, javaElements);
	}
	
	public void testDisabled_noCommonParent0() throws Exception {
		IJavaElement[] javaElements= {getPackageP(), getRoot()};
		IResource[] resources= {};
		verifyDisabled(resources, javaElements);		
	}
	
	public void testDisabled_noCommonParent1() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
		try {
			IType classA= cu.getType("A");
			IMethod	methodFoo= classA.getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { classA, methodFoo };
			IResource[] resources= {};
			verifyDisabled(resources, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}		
	}

//	public void testDisabled_noCommonParent2() throws Exception {
//		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
//		try {
//			IType classA= cu.getType("A");
//			IJavaElement[] javaElements= { classA, cu};
//			IResource[] resources= {};
//			verifyDisabled(resources, javaElements);
//		} finally {
//			performDummySearch();
//			cu.delete(true, new NullProgressMonitor());
//		}		
//	}

	public void testDisabled_noCommonParent3() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
		try {
			IJavaElement[] javaElements= {cu, getPackageP()};
			IResource[] resources= {};
			verifyDisabled(resources, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}		
	}

	public void testDisabled_noCommonParent5() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
		try {
			IJavaElement[] javaElements= {cu, getRoot()};
			IResource[] resources= {};
			verifyDisabled(resources, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}		
	}

	public void testDisabled_noCommonParent6() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
		try {
			IJavaElement[] javaElements= {cu, getRoot()};
			IResource[] resources= {};
			verifyDisabled(resources, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}		
	}

	public void testDisabled_noCommonParent7() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{class Inner{}}", false, new NullProgressMonitor());
		try {
			IType classA= cu.getType("A");
			IType classInner= classA.getType("Inner");
			IJavaElement[] javaElements= { classA, classInner};
			IResource[] resources= {};
			verifyDisabled(resources, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}
	
	public void testDisabled_noCommonParent8() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try {
			IType classA= cu.getType("A");
			IMethod	methodFoo= classA.getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { methodFoo, classA};
			IResource[] resources= {};
			verifyDisabled(resources, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testEnabled_cu() throws Exception {
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try {
			IJavaElement[] javaElements= { cu};
			IResource[] resources= {};
			verifyEnabled(resources, javaElements, null, createReorgQueries());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}		
	}
	
	public void testEnabled_package() throws Exception {
		IJavaElement[] javaElements= { getPackageP()};
		IResource[] resources= {};
		verifyEnabled(resources, javaElements, null, createReorgQueries());
	}	
	
	public void testEnabled_packageRoot() throws Exception {
		IJavaElement[] javaElements= { getRoot()};
		IResource[] resources= {};
		verifyEnabled(resources, javaElements, null, createReorgQueries());
	}	

	public void testEnabled_file() throws Exception {
		IFolder folder= (IFolder)getPackageP().getResource();
		IFile file= folder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			verifyEnabled(resources, javaElements, null, createReorgQueries());			
		} finally{
			performDummySearch();
			file.delete(true, false, null);
		}
	}	

	public void testEnabled_folder() throws Exception{
		IFolder folder= (IFolder)getPackageP().getResource();
		
		IJavaElement[] javaElements= {};
		IResource[] resources= {folder};
		verifyEnabled(resources, javaElements, null, createReorgQueries());			
	}

	public void testEnabled_fileFolder() throws Exception {
		IFolder superFolder= (IFolder)getPackageP().getResource();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file, folder};
			verifyEnabled(resources, javaElements, null, createReorgQueries());			
		} finally{
			performDummySearch();
			file.delete(true, false, null);
			folder.delete(true, false, null);
		}
	}	

	public void testEnabled_fileFolderCu() throws Exception {
		IFolder superFolder= (IFolder)getPackageP().getResource();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file, folder};
			verifyEnabled(resources, javaElements, null, createReorgQueries());			
		} finally{
			performDummySearch();
			file.delete(true, false, null);
			folder.delete(true, false, null);
			cu.delete(true, new NullProgressMonitor());
		}
	}
	
	public void testDestination_package_no_1() throws Exception{
		IJavaElement[] javaElements= { getPackageP()};
		IResource[] resources= {};
		JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());
		verifyInvalidDestination(ref, RefactoringTestSetup.getProject());
	}

	public void testDestination_package_no_2() throws Exception{		
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		try {
			IJavaElement[] javaElements= { getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination=cu;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());			
		}
	}

	public void testDestination_package_no_3() throws Exception{		
		IFolder superFolder= (IFolder)getPackageP().getResource();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);

		try {
			IJavaElement[] javaElements= { getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= file;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			file.delete(true, new NullProgressMonitor());			
		}
	}

	public void testDestination_package_no_4() throws Exception{		
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		try {
			IJavaElement[] javaElements= { getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= folder;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testDestination_cu_no_1() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		IProject closedProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		closedProject.create(null);
		assertTrue(! closedProject.isOpen());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= closedProject;
			verifyInvalidDestination(ref, destination);
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
			closedProject.delete(true, true, null);
		}
	}

	public void testDestination_folder_no_0() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= folder;//same folder
			verifyInvalidDestination(ref, destination);	
		}finally{
			performDummySearch();
			folder.delete(true, false, null);
		}
	}

	public void testDestination_folder_no_1() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		IFolder childFolder= folder.getFolder("folder");
		childFolder.create(true, true, null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= childFolder;
			verifyInvalidDestination(ref, destination);			
		}finally{
			performDummySearch();
			folder.delete(true, false, null);
			childFolder.delete(true, false, null);
		}
	}
	
	public void testDestination_folder_no_2() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		IFile childFile= folder.getFile("a.txt");
		childFile.create(getStream("123"), true, null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= childFile;
			verifyInvalidDestination(ref, destination);			
		}finally{
			performDummySearch();
			folder.delete(true, false, null);
			childFile.delete(true, false, null);
		}
	}
	
	public void testDestination_folder_no_3() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		assertTrue(! simpleProject.isOpen());
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= simpleProject;
			verifyInvalidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			simpleProject.delete(true, true, new NullProgressMonitor());
		}
	}

	
	public void testDestination_root_no_0() throws Exception{
		IJavaElement[] javaElements= {getRoot()};
		IResource[] resources= {};
		JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

		Object destination= getPackageP();
		verifyInvalidDestination(ref, destination);			
	}

	public void testDestination_root_no_1() throws Exception{
		ICompilationUnit cu= getPackageP().createCompilationUnit("B.java", "package p;class B{}", false, new NullProgressMonitor());
		
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= cu;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}			
	}

	public void testDestination_root_no_2() throws Exception{
		ICompilationUnit cu= getPackageP().createCompilationUnit("B.java", "package p;class B{}", false, new NullProgressMonitor());
		
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			IType classB= cu.getType("B");
			Object destination= classB;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}			
	}
	
	public void testDestination_root_no_3() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);

		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= file;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
		}			
	}

	public void testDestination_root_no_4() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= folder;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_root_yes_2() throws Exception{
		IJavaElement[] javaElements= { getRoot()};
		IResource[] resources= {};
		JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

		Object destination= getRoot();
		verifyValidDestination(ref, destination);
	}
	
	public void testDestination_cu_yes_0() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());
			Object destination= cu1;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_cu_yes_1() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getPackageP();
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_cu_yes_2() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		IPackageFragment otherPackage= getRoot().createPackageFragment("otherPackage", true, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= otherPackage;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
			otherPackage.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_cu_yes_3() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getRoot();
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_cu_yes_4() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_cu_yes_5() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		simpleProject.open(null);
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= simpleProject;
			verifyValidDestination(ref, destination);
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
			simpleProject.delete(true, true, null);
		}
	}

	public void testDestination_cu_yes_6() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= file;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
			file.delete(true, false, null);
		}
	}

	public void testDestination_cu_yes_7() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= folder;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
			folder.delete(true, false, null);
		}
	}

	public void testDestination_cu_yes_8() throws Exception{
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		ICompilationUnit cu2= getPackageP().createCompilationUnit("B.java", "package p;class B{}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= { cu1};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= cu2;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			cu1.delete(true, new NullProgressMonitor());
			cu2.delete(true, new NullProgressMonitor());
		}
	}
	

	public void testDestination_file_yes_0() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= file;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
		}
	}		

	public void testDestination_file_yes_1() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		IFile otherFile= superFolder.getFile("b.txt");
		otherFile.create(getStream("123"), true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= otherFile;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
			otherFile.delete(true, new NullProgressMonitor());
		}
	}		

	public void testDestination_file_yes_3() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= folder;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
			folder.delete(true, new NullProgressMonitor());
		}
	}		

	public void testDestination_file_yes_4() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		ICompilationUnit cu1= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());			
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= cu1;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
			cu1.delete(true, new NullProgressMonitor());
		}
	}		
	
	public void testDestination_file_yes_5() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getPackageP();
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_file_yes_6() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getRoot();
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
		}
	}		

	public void testDestination_file_yes_7() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
		}
	}		

	public void testDestination_file_yes_8() throws Exception{
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		IFile file= parentFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= parentFolder;
			verifyValidDestination(ref, destination);			
		}finally{
			performDummySearch();
			file.delete(true, new NullProgressMonitor());
		}
	}
	
	public void testDestination_file_yes_9() throws Exception{
		IFolder superFolder= (IFolder)getPackageP().getResource();
		IFile file= superFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);

		ICompilationUnit cu2= getPackageP().createCompilationUnit("B.java", "package p;class B{}", false, new NullProgressMonitor());
		try {
			IJavaElement[] javaElements= {};
			IResource[] resources= {file};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= cu2;
			verifyValidDestination(ref, destination);
		} finally {
			performDummySearch();
			file.delete(true, new NullProgressMonitor());			
			cu2.delete(true, new NullProgressMonitor());
		}
	}
			
	public void testDestination_folder_yes_0() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		IFolder otherFolder= superFolder.getFolder("otherfolder");
		otherFolder.create(true, true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= otherFolder;
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			otherFolder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testDestination_folder_yes_1() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testDestination_folder_yes_2() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getRoot();
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testDestination_folder_yes_3() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getPackageP();
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}
	
	public void testDestination_folder_yes_4() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		IFolder otherFolder= superFolder.getFolder("otherfolder");
		otherFolder.create(true, true, null);
		IFile fileInAnotherFolder= otherFolder.getFile("f.tex");
		fileInAnotherFolder.create(getStream("123"), true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= fileInAnotherFolder;
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());	
			otherFolder.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_folder_yes_5() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= cu;
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_folder_yes_6() throws Exception{
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder folder= superFolder.getFolder("folder");
		folder.create(true, true, null);

		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		simpleProject.open(null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= simpleProject;
			verifyValidDestination(ref, destination);						
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			simpleProject.delete(true, true, new NullProgressMonitor());
		}
	}

	public void testDestination_package_yes_0() throws Exception{
		IJavaElement[] javaElements= {getPackageP()};
		IResource[] resources= {};
		JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

		Object destination= getRoot();
		verifyValidDestination(ref, destination);						
	}

	public void testDestination_package_yes_1() throws Exception{
		IJavaElement[] javaElements= { getPackageP()};
		IResource[] resources= {};
		JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());
		verifyValidDestination(ref, getPackageP());
	}

	public void testDestination_package_yes_2() throws Exception{		
		IPackageFragment otherPackage= getRoot().createPackageFragment("other.pack", true, new NullProgressMonitor());
		try {
			IJavaElement[] javaElements= { getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= otherPackage;
			verifyValidDestination(ref, destination);
		} finally {
			performDummySearch();
			otherPackage.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_root_yes_0() throws Exception{
		IJavaElement[] javaElements= {getRoot()};
		IResource[] resources= {};
		JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

		Object destination= getRoot().getJavaProject();
		verifyValidDestination(ref, destination);
	}
	
	public void testDestination_root_yes_1() throws Exception{
		IJavaProject otherJavaProject= JavaProjectHelper.createJavaProject("other", "bin");
		
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= otherJavaProject;
			verifyValidDestination(ref, destination);
		} finally {
			performDummySearch();
			JavaProjectHelper.delete(otherJavaProject);
		}						
	}
	
	public void testDestination_method_no_cu() throws Exception{
		ICompilationUnit cu= null;
		ICompilationUnit otherCu= getPackageP().createCompilationUnit("C.java", "package p;class C{}", false, new NullProgressMonitor());
		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= otherCu;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			otherCu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_method_no_package() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getPackageP();
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_method_no_file() throws Exception{
		ICompilationUnit cu= null;
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);

		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= file;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			file.delete(true, false, null);
		}
	}

	public void testDestination_method_no_folder() throws Exception{
		ICompilationUnit cu= null;
		IProject parentFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= parentFolder.getFolder(folderName);
		folder.create(true, true, null);	

		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= folder;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			folder.delete(true, false, null);
		}
	}

	public void testDestination_method_no_root() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getRoot();
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_method_no_java_project() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_method_no_simple_project() throws Exception{
		ICompilationUnit cu= null;
		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		simpleProject.open(null);
		try {
			cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= simpleProject;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			simpleProject.delete(true, true, null);	
		}
	}

	public void testDestination_method_no_import_container() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "import java.util.*;package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			IImportContainer importContainer= cu.getImportContainer();
			Object destination= importContainer;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_method_no_import_declaration() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "import java.util.*;package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			IImportDeclaration importDeclaration= cu.getImport("java.util.*");
			Object destination= importDeclaration;
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_method_no_package_declaration() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "import java.util.*;package p;class A{void foo(){}}", false, new NullProgressMonitor());
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= cu.getPackageDeclaration("p");
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_method_yes_itself() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			Object destination= method;

			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

//	public void test_method_yes_cu_with_main_type() throws Exception{
//		ICompilationUnit cu= null;
//		ICompilationUnit otherCu= createCUfromTestFile(getPackageP(), "C");
//		try {
//			cu= createCUfromTestFile(getPackageP(), "A");
//			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
//			IJavaElement[] javaElements= { method };
//			Object destination= otherCu;
//
//			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu, otherCu}, destination, javaElements);
//		} finally {
//			performDummySearch();
//			cu.delete(true, new NullProgressMonitor());
//			otherCu.delete(true, new NullProgressMonitor());
//		}
//	}
	public void test_method_yes_other_method() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IMethod otherMethod= cu.getType("A").getMethod("bar", new String[0]);
			IJavaElement[] javaElements= { method };
			Object destination= otherMethod;

			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_method_yes_field() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IField field= cu.getType("A").getField("bar");
			IJavaElement[] javaElements= { method };
			Object destination= field;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_method_yes_type() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			Object destination= cu.getType("A");

			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}
	
	public void test_method_yes_initializer() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IMethod method= cu.getType("A").getMethod("foo", new String[0]);
			IJavaElement[] javaElements= { method };
			Object destination= cu.getType("A").getInitializer(1);

			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_field_yes_field() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IField field= cu.getType("A").getField("bar");
			IField otherField= cu.getType("A").getField("baz");
			IJavaElement[] javaElements= { field };
			Object destination= otherField;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_inner_type_yes_cu() throws Exception{
		ICompilationUnit cu= null;
		ICompilationUnit otherCu= createCUfromTestFile(getPackageP(), "C");

		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IType type= cu.getType("A").getType("Inner");
			IJavaElement[] javaElements= { type };
			Object destination= otherCu;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{otherCu, cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			otherCu.delete(true, new NullProgressMonitor());
		}
	}
	
	public void test_type_yes_package() throws Exception{
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{}", true, new NullProgressMonitor());
		ICompilationUnit newCu= null;
		try {
			ParticipantTesting.reset();
			IType type= cu.getType("A");
			IJavaElement[] javaElements= { type };
			IResource[] resources=  {};
			ResourceMapping mapping= JavaElementResourceMapping.create(type.getCompilationUnit());
			String[] handles= ParticipantTesting.createHandles(type.getCompilationUnit(), mapping);
			IPackageFragment destination= getPackageP();
			INewNameQueries queries= new MockNewNameQueries();
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			verifyValidDestination(ref, destination);
			assertTrue("source cu does not exist before copying", cu.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			assertTrue("source cu does not exist after copying", cu.exists());
			newCu= getPackageP().getCompilationUnit(MockNewNameQueries.NEW_CU_NAME + ".java");
			assertTrue("new cu does not exist after copying", newCu.exists());
			ReorgExecutionLog executionLog= new ReorgExecutionLog();
			executionLog.setNewName(type.getCompilationUnit(), MockNewNameQueries.NEW_CU_NAME + ".java");
			executionLog.setNewName(mapping, MockNewNameQueries.NEW_CU_NAME + ".java");
			executionLog.markAsProcessed(type.getCompilationUnit());
			executionLog.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, executionLog), 
				new CopyArguments(destination.getResource(), executionLog)
			});
		} finally {
			performDummySearch();
			if (newCu != null && newCu.exists())
				newCu.delete(true, new NullProgressMonitor());
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_type_canel_package() throws Exception{
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{}", true, new NullProgressMonitor());
		ICompilationUnit newCu= null;
		try {
			ParticipantTesting.reset();
			IType type= cu.getType("A");
			IJavaElement[] javaElements= { type };
			IResource[] resources=  {};
			ResourceMapping mapping= JavaElementResourceMapping.create(type.getCompilationUnit());
			String[] handles= ParticipantTesting.createHandles(type.getCompilationUnit(), mapping);
			IPackageFragment destination= getPackageP();
			INewNameQueries queries= new MockCancelNameQueries();
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			verifyValidDestination(ref, destination);
			assertTrue("source cu does not exist before copying", cu.exists());
			try {
				performRefactoring(ref, false);
			} catch (OperationCanceledException e) {
			}
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsCanceled();
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), 
				new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			if (newCu != null && newCu.exists())
				newCu.delete(true, new NullProgressMonitor());
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_type_yes_other_package() throws Exception{
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{}", true, new NullProgressMonitor());
		IPackageFragment otherPackage= getRoot().createPackageFragment("other", true, new NullProgressMonitor());
		ICompilationUnit newCu= null;
		try {
			ParticipantTesting.reset();
			
			IType type= cu.getType("A");
			IJavaElement[] javaElements= { type };
			IResource[] resources=  {};
			IPackageFragment destination= otherPackage;
			ResourceMapping mapping= JavaElementResourceMapping.create(type.getCompilationUnit());
			String[] handles= ParticipantTesting.createHandles(type.getCompilationUnit(), mapping);
			
			INewNameQueries queries= new MockNewNameQueries();
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			verifyValidDestination(ref, destination);
			assertTrue("source cu does not exist before copying", cu.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			assertTrue("source cu does not exist after copying", cu.exists());
			newCu= otherPackage.getCompilationUnit(cu.getElementName());
			assertTrue("new cu does not exist after copying", newCu.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(type.getCompilationUnit());
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), 
				new CopyArguments(destination.getResource(), log)
			});
			
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			if (newCu != null && newCu.exists())
				newCu.delete(true, new NullProgressMonitor());
			otherPackage.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_initializer_no_package() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "import java.util.*;package p;class A{void foo(){}{}}", false, new NullProgressMonitor());
			IInitializer initializer= cu.getType("A").getInitializer(1);
			IJavaElement[] javaElements= { initializer };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());

			Object destination= getPackageP();
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_initializer_yes_type() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IInitializer initializer= cu.getType("A").getInitializer(1);
			IJavaElement[] javaElements= { initializer };
			Object destination= cu.getType("A");
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_initializer_yes_method() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IInitializer initializer= cu.getType("A").getInitializer(1);
			IJavaElement[] javaElements= { initializer };
			Object destination= cu.getType("A").getMethod("foo", new String[0]);

			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testDestination_import_container_no_package() throws Exception{
		ICompilationUnit cu= null;
		try {
			cu= getPackageP().createCompilationUnit("A.java", "import java.util.*;package p;class A{void foo(){}{}}", false, new NullProgressMonitor());
			IImportContainer container= cu.getImportContainer();
			IJavaElement[] javaElements= { container };
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, null, createReorgQueries());
	
			Object destination= getPackageP();
			verifyInvalidDestination(ref, destination);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_import_container_yes_type_in_different_cu() throws Exception{
		ICompilationUnit cu= null;
		ICompilationUnit otherCu= createCUfromTestFile(getPackageP(), "C");

		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IImportContainer container= cu.getImportContainer();
			IJavaElement[] javaElements= { container };
			Object destination= otherCu.getType("C");
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu, otherCu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			otherCu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_import_container_yes_method_in_different_cu() throws Exception{
		ICompilationUnit cu= null;
		ICompilationUnit otherCu= createCUfromTestFile(getPackageP(), "C");

		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IImportContainer container= cu.getImportContainer();
			IJavaElement[] javaElements= { container };
			Object destination= otherCu.getType("C").getMethod("foo", new String[0]);
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu, otherCu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			otherCu.delete(true, new NullProgressMonitor());
		}
	}

	public void test_import_container_yes_cu() throws Exception{
		ICompilationUnit cu= null;
		ICompilationUnit otherCu= createCUfromTestFile(getPackageP(), "C");

		try {
			cu= createCUfromTestFile(getPackageP(), "A");
			IImportContainer container= cu.getImportContainer();
			IJavaElement[] javaElements= { container };
			Object destination= otherCu;
			verifyCopyingOfSubCuElements(new ICompilationUnit[]{cu, otherCu}, destination, javaElements);
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			otherCu.delete(true, new NullProgressMonitor());
		}
	}


	public void testCopy_File_to_Folder() throws Exception {
		ParticipantTesting.reset();
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
		
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder destinationFolder= superFolder.getFolder("folder");
		destinationFolder.create(true, true, null);
		
		IFile newFile= null;
		try {
			
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			String[] handles= ParticipantTesting.createHandles(file);
			
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= destinationFolder;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= destinationFolder.getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(file);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log)
			});
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			destinationFolder.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_Same_Folder() throws Exception {
		ParticipantTesting.reset();
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
		
		IFolder destinationFolder= parentFolder;
		
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			String[] handles= ParticipantTesting.createHandles(file);
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= destinationFolder;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= destinationFolder.getFile(MockNewNameQueries.NEW_FILE_NAME);
			assertTrue("new file does not exist after copying", newFile.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.setNewName(file, MockNewNameQueries.NEW_FILE_NAME);
			log.markAsProcessed(file);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log)
			});
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}
	
	public void testCopy_File_to_Same_Folder_Cancel() throws Exception {
		ParticipantTesting.reset();
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
		
		IFolder destinationFolder= parentFolder;
		
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockCancelNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			String[] handles= ParticipantTesting.createHandles(file);
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= destinationFolder;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			try {
				performRefactoring(ref, false);
			} catch(OperationCanceledException e) {
			}
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsCanceled();
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log)
			});
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}
	
	public void testCopy_File_to_Itself() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
				
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= file;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= parentFolder.getFile(MockNewNameQueries.NEW_FILE_NAME);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_AnotherFile() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);

		IFile otherFile= RefactoringTestSetup.getProject().getProject().getFile("b.txt");
		otherFile.create(getStream("123"), true, null);
				
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= otherFile;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= RefactoringTestSetup.getProject().getProject().getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			otherFile.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_Package() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
		
		IPackageFragment otherPackage= getRoot().createPackageFragment("other.pack", true, new NullProgressMonitor());
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= otherPackage;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= ((IFolder)otherPackage.getResource()).getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			otherPackage.delete(true, new NullProgressMonitor());
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_DefaultPackage() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
		
		IPackageFragment defaultPackage= getRoot().getPackageFragment("");
		assertTrue(defaultPackage.exists());
		assertTrue(defaultPackage.isDefaultPackage());
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= defaultPackage;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= ((IFolder)defaultPackage.getResource()).getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_SourceFolder() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
				
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= getRoot();
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= ((IFolder)getRoot().getResource()).getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_JavaProject() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
				
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= RefactoringTestSetup.getProject().getProject().getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_File_to_Cu() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
				
		IFile newFile= null;
		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= cu;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= parentFolder.getFile(MockNewNameQueries.NEW_FILE_NAME);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			cu.delete(true, new NullProgressMonitor());
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}
	
	public void testCopy_File_to_SimpleProject() throws Exception {
		IFolder parentFolder= (IFolder) getPackageP().getResource();
		String fileName= "a.txt";
		IFile file= parentFolder.getFile(fileName);
		file.create(getStream("123"), true, null);
				
		IFile newFile= null;
		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		simpleProject.open(null);
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {};
			IResource[] resources= { file };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= simpleProject;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", file.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", file.exists());
			
			newFile= simpleProject.getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			file.delete(true, false, null);
			simpleProject.delete(true, new NullProgressMonitor());
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_Cu_to_Folder() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		IFolder destinationFolder= superFolder.getFolder("folder");
		destinationFolder.create(true, true, null);
		
		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= { };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= destinationFolder;
			verifyValidDestination(ref, destination);
			
			assertTrue("source cu does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source cu does not exist after copying", cu.exists());
			
			newFile= destinationFolder.getFile(fileName);
			assertTrue("new cu does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			destinationFolder.delete(true, false, null);
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_Cu_to_Same_Package() throws Exception {
		ParticipantTesting.reset();
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		ICompilationUnit newCu= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= { };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(cu);
			String[] handles= ParticipantTesting.createHandles(cu, mapping);
			
			IPackageFragment destination= getPackageP();
			verifyValidDestination(ref, destination);
			
			assertTrue("source cu does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source cu does not exist after copying", cu.exists());
			
			String newName= MockNewNameQueries.NEW_CU_NAME + ".java";
			newCu= getPackageP().getCompilationUnit(newName);
			assertTrue("new cu does not exist after copying", newCu.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.setNewName(cu, newName);
			log.setNewName(mapping, newName);
			log.markAsProcessed(cu);
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			if (newCu != null && newCu.exists()){
				newCu.delete(true, new NullProgressMonitor());
			}
		}
	}

	public void testCopy_Cu_to_Same_Package_Cancel() throws Exception {
		ParticipantTesting.reset();
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		ICompilationUnit newCu= null;
		try {
			INewNameQueries queries= new MockCancelNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= { };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(cu);
			String[] handles= ParticipantTesting.createHandles(cu, mapping);
			
			IPackageFragment destination= getPackageP();
			verifyValidDestination(ref, destination);
			
			assertTrue("source cu does not exist before copying", cu.exists());
			
			try {
				performRefactoring(ref, false);
			} catch (OperationCanceledException e) {
			}
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsCanceled();
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			if (newCu != null && newCu.exists()){
				newCu.delete(true, new NullProgressMonitor());
			}
		}
	}

	public void test_type_yes_type() throws Exception{
		ICompilationUnit cu= createCUfromTestFile(getPackageP(), "A");
		ICompilationUnit otherCu= createCUfromTestFile(getPackageP(), "C");

		ICompilationUnit newCu= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= { };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			
			Object destination= otherCu;
			verifyValidDestination(ref, destination);
			
			assertTrue("source cu does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source cu does not exist after copying", cu.exists());
			
			newCu= getPackageP().getCompilationUnit(MockNewNameQueries.NEW_CU_NAME + ".java");
			assertTrue("new cu does not exist after copying", newCu.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			if (newCu != null && newCu.exists()){
				newCu.delete(true, new NullProgressMonitor());
			}
			if (otherCu != null && otherCu.exists()){
				otherCu.delete(true, new NullProgressMonitor());
			}
		}
	}
	
	public void testCopy_Cu_to_Itself() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
				
		ICompilationUnit newCu= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= { };
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= cu;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			newCu= getPackageP().getCompilationUnit(MockNewNameQueries.NEW_CU_NAME + ".java");
			assertTrue("new file does not exist after copying", newCu.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			if (newCu != null && newCu.exists()){
				newCu.delete(true, new NullProgressMonitor());
			}
		}
	}

	public void testCopy_Cu_to_OtherPackage() throws Exception {
		ParticipantTesting.reset();
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IPackageFragment otherPackage= getRoot().createPackageFragment("other.pack", true, new NullProgressMonitor());
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(cu);
			String[] handles= ParticipantTesting.createHandles(cu, mapping);

			IPackageFragment destination= otherPackage;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			ICompilationUnit newCu= otherPackage.getCompilationUnit(fileName);
			assertTrue("new file does not exist after copying", newCu.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(cu);
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			otherPackage.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_Cu_to_DefaultPackage() throws Exception {
		ParticipantTesting.reset();
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IPackageFragment defaultPackage= getRoot().getPackageFragment("");
		assertTrue(defaultPackage.exists());
		assertTrue(defaultPackage.isDefaultPackage());
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(cu);
			String[] handles= ParticipantTesting.createHandles(cu, mapping);

			IPackageFragment destination= defaultPackage;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			ICompilationUnit newCu= defaultPackage.getCompilationUnit(fileName);
			assertTrue("new file does not exist after copying", newCu.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(cu);
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_Cu_to_SourceFolder() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		ICompilationUnit newCu= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= getRoot();
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			newCu= getRoot().getPackageFragment("").getCompilationUnit(fileName);
			assertTrue("new file does not exist after copying", newCu.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_Cu_to_JavaProject() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			newFile= RefactoringTestSetup.getProject().getProject().getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			if (newFile != null)
				newFile.delete(true, false, null);
		}
	}

	public void testCopy_Cu_to_File_In_Package() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IFolder parentFolder= (IFolder) getPackageP().getResource();
		IFile file= parentFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);
		assertTrue(file.exists());

		ICompilationUnit newCu= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= file;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			newCu= getPackageP().getCompilationUnit(MockNewNameQueries.NEW_CU_NAME + ".java");
			assertTrue("new file does not exist after copying", newCu.exists());
			
			String expectedSource= "package p;class "+ MockNewNameQueries.NEW_CU_NAME +"{void foo(){}class Inner{}}";
			assertEqualLines("source compare failed", expectedSource, newCu.getSource());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			file.delete(true, false, null);
			if (newCu != null && newCu.exists()){
				newCu.delete(true, new NullProgressMonitor());
			}
		}
	}

	public void testCopy_Cu_to_File_In_Resource_Folder() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IProject parentFolder= RefactoringTestSetup.getProject().getProject();
		IFile file= parentFolder.getFile("a.txt");
		file.create(getStream("123"), true, null);

		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= file;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			newFile= RefactoringTestSetup.getProject().getProject().getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			file.delete(true, false, null);
			newFile.delete(true, false, null);
		}
	}
	
	public void testCopy_Cu_to_SimpleProject() throws Exception {
		String fileName= "A.java";
		ICompilationUnit cu= getPackageP().createCompilationUnit(fileName, "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());

		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		simpleProject.open(null);

		IFile newFile= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {cu};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= simpleProject;
			verifyValidDestination(ref, destination);
			
			assertTrue("source file does not exist before copying", cu.exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source file does not exist after copying", cu.exists());
			
			newFile= simpleProject.getFile(fileName);
			assertTrue("new file does not exist after copying", newFile.exists());
		} finally {
			performDummySearch();
			cu.delete(true, new NullProgressMonitor());
			simpleProject.delete(true, false, null);
			newFile.delete(true, false, null);
		}
	}

	public void testCopy_Package_to_Its_Root() throws Exception {
		ParticipantTesting.reset();
		IPackageFragment newPackage= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(getPackageP());
			String[] handles= ParticipantTesting.createHandles(getPackageP(), mapping);

			IPackageFragmentRoot destination= getRoot();
			verifyValidDestination(ref, destination);
			
			assertTrue("source package does not exist before copying", getPackageP().exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source package does not exist after copying", getPackageP().exists());
			
			newPackage= getRoot().getPackageFragment(MockNewNameQueries.NEW_PACKAGE_NAME);
			assertTrue("new package does not exist after copying", newPackage.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.setNewName(getPackageP(), MockNewNameQueries.NEW_PACKAGE_NAME);
			log.markAsProcessed(getPackageP());
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log),
				new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			newPackage.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_Package_to_Its_Root_Cancel() throws Exception {
		ParticipantTesting.reset();
		try {
			INewNameQueries queries= new MockCancelNameQueries();

			IJavaElement[] javaElements= {getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(getPackageP());
			String[] handles= ParticipantTesting.createHandles(getPackageP(), mapping);

			IPackageFragmentRoot destination= getRoot();
			verifyValidDestination(ref, destination);
			
			assertTrue("source package does not exist before copying", getPackageP().exists());
			
			try {
				performRefactoring(ref, false);
			} catch(OperationCanceledException e) {
			}
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsCanceled();
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log),
				new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
		}
	}

	public void testCopy_Package_to_Itself() throws Exception {
		ParticipantTesting.reset();
		IPackageFragment newPackage= null;
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(getPackageP());
			String[] handles= ParticipantTesting.createHandles(getPackageP(), mapping);

			IPackageFragment destination= getPackageP();
			verifyValidDestination(ref, destination);
			
			assertTrue("source package does not exist before copying", getPackageP().exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source package does not exist after copying", getPackageP().exists());
			
			newPackage= getRoot().getPackageFragment(MockNewNameQueries.NEW_PACKAGE_NAME);
			assertTrue("new package does not exist after copying", newPackage.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(getPackageP());
			log.markAsProcessed(mapping);
			log.setNewName(getPackageP(), MockNewNameQueries.NEW_PACKAGE_NAME);
			log.setNewName(mapping, MockNewNameQueries.NEW_PACKAGE_FOLDER_NAME);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination.getParent(), log),
				new CopyArguments(destination.getParent().getResource(), log)
			});
		} finally {
			performDummySearch();
			if (newPackage != null && newPackage.exists())
				newPackage.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_Package_to_Another_Root() throws Exception {
		IPackageFragmentRoot otherRoot= JavaProjectHelper.addSourceContainer(RefactoringTestSetup.getProject(), "otherRoot");
		IPackageFragment newPackage= null;
		String packageName= getPackageP().getElementName();
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= otherRoot;
			verifyValidDestination(ref, destination);
			
			assertTrue("source package does not exist before copying", getPackageP().exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source package does not exist after copying", getPackageP().exists());
			
			newPackage= otherRoot.getPackageFragment(packageName);
			assertTrue("new package does not exist after copying", newPackage.exists());
		} finally {
			performDummySearch();
			newPackage.delete(true, new NullProgressMonitor());
			otherRoot.delete(0, 0, new NullProgressMonitor());
		}
	}

	public void testCopy_Package_to_JavaProject_That_Is_Root() throws Exception {
		IJavaProject otherProject= JavaProjectHelper.createJavaProject("otherProject", null);
		JavaProjectHelper.addSourceContainer(otherProject, null);
		try {
			INewNameQueries queries= new MockNewNameQueries();

			IJavaElement[] javaElements= {getPackageP()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, queries, createReorgQueries());

			Object destination= otherProject;
			verifyValidDestination(ref, destination);
			
			assertTrue("source package does not exist before copying", getPackageP().exists());
			
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source package does not exist after copying", getPackageP().exists());
			
			IPackageFragment newPackage= null;
			IPackageFragmentRoot[] roots= otherProject.getAllPackageFragmentRoots();
			for (int i= 0; i < roots.length; i++) {
				if (ReorgUtils.isSourceFolder(roots[i])){
					newPackage= roots[i].getPackageFragment(getPackageP().getElementName());
					assertTrue("new package does not exist after copying", newPackage.exists());					
				}
			}
			assertNotNull(newPackage);
		} finally {
			performDummySearch();
			JavaProjectHelper.delete(otherProject);
		}
	}
	
	public void testCopy_folder_to_other_folder() throws Exception {
		ParticipantTesting.reset();
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		IFolder otherFolder= superFolder.getFolder("otherfolder");
		otherFolder.create(true, true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());
			String[] handles= ParticipantTesting.createHandles(folder);

			Object destination= otherFolder;
			verifyValidDestination(ref, destination);	

			assertTrue("source does not exist before copying", folder.exists());
								
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());
			assertTrue("copied folder does not exist after copying", otherFolder.getFolder(folderName).exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(folder);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log)
			});
			
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			otherFolder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testCopy_folder_to_same_container() throws Exception {
		ParticipantTesting.reset();
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);
		IFolder newFolder= null;
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());
			String[] handles= ParticipantTesting.createHandles(folder);

			Object destination= superFolder;
			verifyValidDestination(ref, destination);	

			assertTrue("source does not exist before copying", folder.exists());
								
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());
			newFolder= superFolder.getFolder(MockNewNameQueries.NEW_FOLDER_NAME);
			assertTrue("copied folder does not exist after copying", newFolder.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(folder);
			log.setNewName(folder, MockNewNameQueries.NEW_FOLDER_NAME);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log)
			});
			
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			newFolder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testCopy_folder_to_same_container_cancel() throws Exception {
		ParticipantTesting.reset();
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);
		
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockCancelNameQueries(), createReorgQueries());
			String[] handles= ParticipantTesting.createHandles(folder);

			Object destination= superFolder;
			verifyValidDestination(ref, destination);	

			assertTrue("source does not exist before copying", folder.exists());
								
			try {
				performRefactoring(ref, false);
			} catch (OperationCanceledException e) {
			}
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsCanceled();
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log)
			});
			
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testCopy_folder_Java_project() throws Exception {
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());

			Object destination= RefactoringTestSetup.getProject();
			verifyValidDestination(ref, destination);						

			assertTrue("source does not exist before copying", folder.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());
			
			assertTrue("copied folder does not exist after copying", RefactoringTestSetup.getProject().getProject().getFolder(folderName).exists());
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testCopy_folder_to_source_folder() throws Exception {
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());

			Object destination= getRoot();
			verifyValidDestination(ref, destination);						

			assertTrue("source does not exist before copying", folder.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());
			
			assertTrue("copied folder does not exist after copying", ((IFolder)getRoot().getResource()).getFolder(folderName).exists());
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}
	}

	public void testCopy_folder_to_package() throws Exception {
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());

			IPackageFragment destination= getPackageP();
			verifyValidDestination(ref, destination);						
			assertTrue("source does not exist before copying", folder.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());			
			assertTrue("copied folder does not exist after copying", ((IFolder)destination.getResource()).getFolder(folderName).exists());
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
		}

	}
	public void testCopy_folder_to_file_in_another_folder() throws Exception {
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		IFolder otherFolder= superFolder.getFolder("otherfolder");
		otherFolder.create(true, true, null);
		IFile fileInAnotherFolder= otherFolder.getFile("f.tex");
		fileInAnotherFolder.create(getStream("123"), true, null);

		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());

			Object destination= fileInAnotherFolder;
			verifyValidDestination(ref, destination);						
			assertTrue("source does not exist before copying", folder.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());			
			assertTrue("copied folder does not exist after copying", otherFolder.getFolder(folderName).exists());
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());	
			otherFolder.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_folder_to_cu() throws Exception {
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		ICompilationUnit cu= getPackageP().createCompilationUnit("A.java", "package p;class A{void foo(){}class Inner{}}", false, new NullProgressMonitor());
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());

			ICompilationUnit destination= cu;
			verifyValidDestination(ref, destination);						
			assertTrue("source does not exist before copying", folder.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());			
			assertTrue("copied folder does not exist after copying", ((IFolder)getPackageP().getResource()).getFolder(folderName).exists());
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			cu.delete(true, new NullProgressMonitor());
		}
	}

	public void testCopy_folder_to_simple_project() throws Exception {
		IProject superFolder= RefactoringTestSetup.getProject().getProject();
		String folderName= "folder";
		IFolder folder= superFolder.getFolder(folderName);
		folder.create(true, true, null);

		IProject simpleProject= ResourcesPlugin.getWorkspace().getRoot().getProject("mySImpleProject");
		simpleProject.create(null);
		simpleProject.open(null);
		try{
			IJavaElement[] javaElements= {};
			IResource[] resources= {folder};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());

			Object destination= simpleProject;
			verifyValidDestination(ref, destination);						
			assertTrue("source does not exist before copying", folder.exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);
			
			assertTrue("source does not exist after copying", folder.exists());			
			assertTrue("copied folder does not exist after copying", simpleProject.getFolder(folderName).exists());
		} finally{
			performDummySearch();
			folder.delete(true, new NullProgressMonitor());			
			simpleProject.delete(true, true, new NullProgressMonitor());
		}
	}

	public void testCopy_root_to_same_Java_project() throws Exception {
		ParticipantTesting.reset();
		IPackageFragmentRoot newRoot= null;
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {			};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(getRoot());
			String[] handles= ParticipantTesting.createHandles(getRoot(), mapping);

			IJavaProject destination= getRoot().getJavaProject();
			verifyValidDestination(ref, destination);
			assertTrue("source does not exist before copying", getRoot().exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);

			assertTrue("source does not exist after copying", getRoot().exists());
			String newName= MockNewNameQueries.NEW_PACKAGE_FRAGMENT_ROOT_NAME;
			newRoot= getSourceFolder(RefactoringTestSetup.getProject(), newName);
			assertNotNull("copied folder does not exist after copying", newRoot);
			assertTrue("copied folder does not exist after copying", newRoot.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.setNewName(getRoot(), newName);
			log.setNewName(mapping, newName);
			log.markAsProcessed(getRoot());
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			if (newRoot != null && newRoot.exists())
				newRoot.delete(0, 0, new NullProgressMonitor());
		}
	}
	
	public void testCopy_root_to_same_Java_project_cancel() throws Exception {
		ParticipantTesting.reset();
		IPackageFragmentRoot newRoot= null;
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockCancelNameQueries(), createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(getRoot());
			String[] handles= ParticipantTesting.createHandles(getRoot(), mapping);

			IJavaProject destination= getRoot().getJavaProject();
			verifyValidDestination(ref, destination);
			assertTrue("source does not exist before copying", getRoot().exists());
			try {
				performRefactoring(ref, false);
			} catch (OperationCanceledException e) {
			}
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsCanceled();
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getResource(), log)
			});
		} finally {
			performDummySearch();
			if (newRoot != null && newRoot.exists())
				newRoot.delete(0, 0, new NullProgressMonitor());
		}
	}
	
	public void testCopy_root_to_other_Java_project() throws Exception {
		ParticipantTesting.reset();
		IJavaProject otherJavaProject= JavaProjectHelper.createJavaProject("other", "bin");
		try {
			IJavaElement[] javaElements= { getRoot()};
			IResource[] resources= {};
			JavaCopyProcessor ref= verifyEnabled(resources, javaElements, new MockNewNameQueries(), createReorgQueries());
			ResourceMapping mapping= JavaElementResourceMapping.create(getRoot());
			String[] handles= ParticipantTesting.createHandles(getRoot(), mapping);

			IJavaProject destination= otherJavaProject;
			verifyValidDestination(ref, destination);
			assertTrue("source does not exist before copying", getRoot().exists());
			RefactoringStatus status= performRefactoring(ref, false);
			assertEquals(null, status);

			assertTrue("source does not exist after copying", getRoot().exists());
			String newName= getRoot().getElementName();
			IPackageFragmentRoot newRoot= getSourceFolder(otherJavaProject, newName);
			assertNotNull("copied folder does not exist after copying", newRoot);
			assertTrue("copied folder does not exist after copying", newRoot.exists());
			ReorgExecutionLog log= new ReorgExecutionLog();
			log.markAsProcessed(getRoot());
			log.markAsProcessed(mapping);
			ParticipantTesting.testCopy(handles, new CopyArguments[] {
				new CopyArguments(destination, log), new CopyArguments(destination.getProject(), log)
			});
		} finally {
			performDummySearch();
			JavaProjectHelper.delete(otherJavaProject);
		}						
	}
}
