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


import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

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

import org.eclipse.core.resources.IContainer;
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.IResourceVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.ICVSRunnable;
import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter;
import org.eclipse.team.tests.ccvs.core.CVSTestSetup;
import org.eclipse.team.tests.ccvs.core.EclipseTest;

/**
 * Tests the EclipseSynchronizer.
 * Does not test state change broadcasts.
 */
public class EclipseSynchronizerTest extends EclipseTest {
	private IProject project;
	private static EclipseSynchronizer sync = EclipseSynchronizer.getInstance();
	
	public EclipseSynchronizerTest() {
		super();
	}
	
	public EclipseSynchronizerTest(String name) {
		super(name);
	}
	
	public static Test suite() {
		TestSuite suite = new TestSuite();

		// Run all tests twice to ensure consistency between batched and non-batched behaviour.
		// 1. First run -- no batching
		suite.addTestSuite(EclipseSynchronizerTest.class);
		// 2. Second run -- with batching
		suite.addTest(new BatchedTestSetup(new TestSuite(EclipseSynchronizerTest.class)));
		return new CVSTestSetup(suite);
	}
	
	public void testFolderSync() throws CoreException, CVSException {
		// Workspace root
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		// Setting should not be an error but sync info should always be null
		FolderSyncInfo info = sync.getFolderSync(root);
		assertNull(info);
		sync.deleteFolderSync(root);
		sync.setFolderSync(root, dummyFolderSync(root));
		info = sync.getFolderSync(root);
		assertNull(info);

		// Non-existant project
		IProject project = root.getProject(getName() + "-" + System.currentTimeMillis());
		assertDoesNotExistInFileSystem(project);
		_testFolderSyncInvalid(project);

		// Project
		project.create(null);
		project.open(null);
		_testFolderSyncValid(project);
		
		// Non-existant folder
		IFolder folder = project.getFolder("folder1");
		assertDoesNotExistInFileSystem(folder);
		_testFolderSyncInvalid(folder);
		
		// Non-existant folder with non-existant parent
		IFolder childFolder = folder.getFolder("folder2");
		assertDoesNotExistInFileSystem(childFolder);
		_testFolderSyncInvalid(childFolder);
		
		// Folder
		folder.create(false /*force*/, true /*local*/, null);
		_testFolderSyncValid(folder);
		
		// Child folder
		childFolder.create(false /*force*/, true /*local*/, null);
		_testFolderSyncValid(childFolder);
		
		// Deleted folder -- sync info should no longer exist
		sync.setFolderSync(folder, dummyFolderSync(folder));
		folder.delete(false /*force*/, null);
		_testFolderSyncInvalid(folder); // verifies sync info was deleted
		
		// Recreated folder -- sync info should not be preserved across deletions
		folder.create(false /*force*/, true /*local*/, null);
		sync.setFolderSync(folder, dummyFolderSync(folder));
		folder.delete(false /*force*/, null);
		folder.create(false /*force*/, true /*local*/, null);
		_testFolderSyncValid(folder); // verifies sync info has not reappeared
		
		// Deleted project
		sync.setFolderSync(project, dummyFolderSync(project));
		project.delete(false /*force*/, null);
		_testFolderSyncInvalid(project);
	}
	
	/*
	 * Test get/set/delete folder sync for things that support it.
	 * Assumes container does not already have sync info.
	 */
	private void _testFolderSyncValid(IContainer container) throws CoreException, CVSException {
		FolderSyncInfo info = sync.getFolderSync(container);
		assertNull(info);
		sync.deleteFolderSync(container);
		FolderSyncInfo newInfo = dummyFolderSync(container);
		sync.setFolderSync(container, newInfo);
		info = sync.getFolderSync(container);
		assertEquals(newInfo, info);
		// verify that deleteFolderSync() does the right thing
		buildResources(container, new String[] { "hassync/", "nosync", "hassync.txt", "nosync.txt" }, true);
		IResource resource = container.getFile(new Path("hassync.txt"));
		sync.setResourceSync(resource, dummyResourceSync(resource));
		resource = container.getFolder(new Path("hassync"));
		sync.setResourceSync(resource, dummyResourceSync(resource));
		assertNotNull(sync.getResourceSync(container.getFile(new Path("hassync.txt"))));
		assertNull(sync.getResourceSync(container.getFile(new Path("nosync.txt"))));
		assertNotNull(sync.getResourceSync(container.getFolder(new Path("hassync"))));
		assertNull(sync.getResourceSync(container.getFolder(new Path("nosync"))));
		if (container.getType() == IResource.FOLDER) {
			sync.setResourceSync(container, dummyResourceSync(container));
			assertNotNull(sync.getResourceSync(container));
		}
		// should delete folder sync for self, and resource sync for children
		sync.deleteFolderSync(container);
		info = sync.getFolderSync(container);
		assertNull(info);
		assertNull(sync.getResourceSync(container.getFile(new Path("hassync.txt"))));
		assertNull(sync.getResourceSync(container.getFile(new Path("nosync.txt"))));
		assertNull(sync.getResourceSync(container.getFolder(new Path("hassync"))));
		assertNull(sync.getResourceSync(container.getFolder(new Path("nosync"))));
		if (container.getType() == IResource.FOLDER) {
			assertNotNull(sync.getResourceSync(container));
		}
	}
	
	/*
	 * Test get/set/delete folder sync for things that should not support it.
	 * Assumes container does not already have sync info.
	 */
	private void _testFolderSyncInvalid(IContainer container) throws CVSException {
		FolderSyncInfo info = sync.getFolderSync(container);
		assertNull(info);
		sync.deleteFolderSync(container);
		try {
			sync.setFolderSync(container, dummyFolderSync(container));
			fail("Expected CVSException");
		} catch (CVSException e) {
		}
		info = sync.getFolderSync(container);
		assertNull(info);
	}
	
	public void testResourceSync() throws CoreException, CVSException {
		// Workspace root
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		_testResourceSyncInvalid(root);

		// Project
		IProject project = getUniqueTestProject(getName());
		assertExistsInFileSystem(project);
		_testResourceSyncInvalid(project);
		
		// Folder
		IFolder folder = project.getFolder("folder1");
		folder.create(false /*force*/, true /*local*/, null);
		_testResourceSyncValid(folder);
		
		// File
		IFile file = folder.getFile("file1");
		file.create(getRandomContents(), false /*force*/, null);
		_testResourceSyncValid(file);
		
		// Deleted/recreated file -- if parent exists, sync info should be preserved across deletions
		ResourceSyncInfo info = dummyResourceSync(file);
		sync.setResourceSync(file, info);
		// Note: deleting a resource will delete it's sync info unless the project has a CVS provider
		file.delete(false /*force*/, null);
		ResourceSyncInfo newInfo = sync.getResourceSync(file);
		//assertEquals(newInfo, info);
		assertEquals(newInfo, null); /* changed for reason noted above */
		file.create(getRandomContents(), false /*force*/, null);
		sync.setResourceSync(file, info); /* added for reason noted above */
		newInfo = sync.getResourceSync(file);
		assertEquals(newInfo, info);
		sync.deleteResourceSync(file);
		file.delete(false /*force*/, null);
		_testResourceSyncValid(file);
		
		// Deleted parent -- sync info of children should also be deleted
		sync.setResourceSync(file, info);
		folder.delete(false /*force*/, null);
		info = sync.getResourceSync(file);
		assertNull(info);
		
		// File in non-existant folder
		IFolder dummyFolder = project.getFolder("folder2");
		assertDoesNotExistInFileSystem(dummyFolder);
		IFile dummyFile = dummyFolder.getFile("file2");
		assertDoesNotExistInFileSystem(dummyFile);
		_testResourceSyncInvalid(dummyFile);
	}
	
	/*
	 * Test get/set/delete resource sync for things that support it.
	 * Assumes resource does not already have sync info.
	 */
	private void _testResourceSyncValid(IResource resource) throws CVSException {
		ResourceSyncInfo info = sync.getResourceSync(resource);
		assertNull(info);
		sync.deleteResourceSync(resource);
		ResourceSyncInfo newInfo = dummyResourceSync(resource);
		sync.setResourceSync(resource, newInfo);
		info = sync.getResourceSync(resource);
		assertEquals(newInfo, info);
		sync.deleteResourceSync(resource);
		info = sync.getResourceSync(resource);
		assertNull(info);
	}
	
	/*
	 * Test get/set/delete resource sync for things that should not support it.
	 * Assumes resource does not already have sync info.
	 */
	private void _testResourceSyncInvalid(IResource resource) throws CVSException {
		ResourceSyncInfo info = sync.getResourceSync(resource);
		assertNull(info);
		sync.deleteResourceSync(resource);
		try {
			sync.setResourceSync(resource, dummyResourceSync(resource));
			fail("Expected CVSException");
		} catch (CVSException e) {
		}
		info = sync.getResourceSync(resource);
		assertNull(info);
	}

	public void testIsIgnored() throws CoreException, TeamException {
		IProject project = getUniqueTestProject("isIgnoredTests");
		IResource[] resources = buildResources(project, new String[] {"a.txt", "c.java", "folder1/", "folder1/b.txt", "folder2/"}, true /* include project */);
		
		sync.addIgnored(project, "*.txt");
		
		assertIsIgnored(project.getFile("a.txt"), true);
		assertIsIgnored(project.getFile("c.java"), false);
		assertIsIgnored(project.getFolder("folder1"), false);
		assertIsIgnored(project.getFolder("folder2"), false);
		assertIsIgnored(project.getFile("folder1/b.txt"), false);	
		assertIsIgnored(project.getFile("folder1/not-existing.txt"), false);
		assertIsIgnored(project.getParent(), false);
		assertIsIgnored(project, false);
		
		sync.addIgnored(project, "folder1");
		
		assertIsIgnored(project.getFile("a.txt"), true);
		assertIsIgnored(project.getFile("c.java"), false);
		assertIsIgnored(project.getFolder("folder1"), true);
		assertIsIgnored(project.getFolder("folder2"), false);
		assertIsIgnored(project.getFile("folder1/b.txt"), true);	
		assertIsIgnored(project.getFile("folder1/not-existing.txt"), true);
		assertIsIgnored(project.getParent(), false);
		assertIsIgnored(project, false);
		
		// delete the ignores, the resource delta should clear the cached
		// ignore list
		IResource cvsIgnore = project.getFile(".cvsignore");
		cvsIgnore.delete(true, null);
		waitForIgnoreFileHandling();
		
		assertIsIgnored(project.getFile("a.txt"), false);
		assertIsIgnored(project.getFile("c.java"), false);
		assertIsIgnored(project.getFolder("folder1"), false);
		assertIsIgnored(project.getFolder("folder2"), false);
		assertIsIgnored(project.getFile("folder1/b.txt"), false);	
		assertIsIgnored(project.getFile("folder1/not-existing.txt"), false);
		assertIsIgnored(project.getParent(), false);
		assertIsIgnored(project, false);
		project.delete(true, true, null);
	}
	
	public void testIgnores() throws CoreException, CVSException {
		// Workspace root
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		_testIgnoresInvalid(root);

		// Non-existant project
		IProject project = root.getProject(getName() + "-" + System.currentTimeMillis());
		assertDoesNotExistInFileSystem(project);
		_testIgnoresInvalid(project);

		// Project
		project.create(null);
		project.open(null);
		_testIgnoresValid(project);
		
		// Non-existant folder
		IFolder folder = project.getFolder("folder1");
		assertDoesNotExistInFileSystem(folder);
		_testIgnoresInvalid(folder);
		
		// Non-existant folder with non-existant parent
		IFolder childFolder = folder.getFolder("folder2");
		assertDoesNotExistInFileSystem(childFolder);
		_testIgnoresInvalid(childFolder);
		
		// Folder
		folder.create(false /*force*/, true /*local*/, null);
		_testIgnoresValid(folder);
		
		// Child folder
		childFolder.create(false /*force*/, true /*local*/, null);
		_testIgnoresValid(childFolder);
		
		// Deleted folder -- ignores should no longer exist
		sync.addIgnored(folder, "*.foo");
		folder.delete(false /*force*/, null);
		_testIgnoresInvalid(folder); // verifies sync info was deleted
		
		// Recreated folder -- sync info should not be preserved across deletions
		folder.create(false /*force*/, true /*local*/, null);
		sync.addIgnored(folder, "*.foo");
		folder.delete(false /*force*/, null);
		folder.create(false /*force*/, true /*local*/, null);
		_testIgnoresValid(folder); // verifies sync info has not reappeared
		
		// Deleted project
		sync.addIgnored(project, "*.foo");
		project.delete(false /*force*/, null);
		_testIgnoresInvalid(project);
	}
	
	
	
	/*
	 * Test get/set ignores for things that should not support it.
	 * Assumes resource does not already have ignores.
	 */
	private void _testIgnoresValid(IContainer container) throws CVSException {
		String[] ignored = getIgnored(container);
		assertTrue(ignored.length == 0);
		sync.addIgnored(container, "*.xyz");
		ignored = getIgnored(container);
		assertBijection(ignored, new String[] { "*.xyz" }, null);
		sync.addIgnored(container, "*.abc");
		sync.addIgnored(container, "*.def");
		ignored = getIgnored(container);
		assertBijection(ignored, new String[] { "*.abc", "*.def", "*.xyz" }, null);
	}

	/**
	 * TODO: should use chached ignores somehow
	 * @param container
	 * @return String[]
	 * @throws CVSException
	 */
	private String[] getIgnored(IContainer container) throws CVSException {
		if (container.getType() == IResource.ROOT) return new String[0];
		String[] ignored = SyncFileWriter.readCVSIgnoreEntries(container);
		if (ignored == null) return new String[0];
		return ignored;
	}

	/*
	 * Test get/set ignores for things that should not support it.
	 * Assumes resource does not already have ignores.
	 */
	private void _testIgnoresInvalid(IContainer container) throws CVSException {
		try {
			sync.addIgnored(container, "*.xyz");
			fail("Expected CVSException");
		} catch (CVSException e) {
		}
	}
	
	public void testMembers() throws CoreException, CVSException {
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IProject project1 = getUniqueTestProject(getName() + "1");
		IProject project2 = root.getProject(getName() + "2" + System.currentTimeMillis());

		// Workspace root
		IResource[] members = sync.members(ResourcesPlugin.getWorkspace().getRoot());
		assertBijection(members, ResourcesPlugin.getWorkspace().getRoot().getProjects(), null);

		// Non-existant project
		members = sync.members(project2);
		assertEquals("Non-existant project should have no members", 0, members.length);
		
		// Non-existant folder
		IFolder folder = project1.getFolder("folder1");
		assertDoesNotExistInFileSystem(folder);
		members = sync.members(folder);
		assertEquals("Non-existant folder should have no members", 0, members.length);
		
		// Non-existant folder with non-existant parent
		IFolder childFolder = folder.getFolder("folder2");
		assertDoesNotExistInFileSystem(childFolder);
		members = sync.members(childFolder);
		assertEquals("Non-existant folder should have no members", 0, members.length);
		
		// Project
		buildResources(project1, new String[] {
			"hassync.txt", "deleted_nosync.txt", "deleted.txt", "hassync/", "deleted/", "deleted_nosync/" }, true);

		// initially none of the resources have sync info and they all exist
		Object[] ignores = new Object[] { project1.getFolder("CVS") };
		Set expectedMembers = new HashSet(Arrays.asList(project1.members()));
		members = sync.members(project1);
		assertBijection(expectedMembers.toArray(), members, ignores);
		
		// add sync info, resources should still appear exactly once
		IResource resource = project1.getFile("hassync.txt");
		sync.setResourceSync(resource, dummyResourceSync(resource));
		resource = project1.getFolder("hassync");
		sync.setResourceSync(resource, dummyResourceSync(resource));

		resource = project1.getFile("deleted.txt");
		sync.setResourceSync(resource, dummyResourceSync(resource));
		resource = project1.getFolder("deleted");
		sync.setResourceSync(resource, dummyResourceSync(resource));

		members = sync.members(project1);
		assertBijection(expectedMembers.toArray(), members, ignores);

		// delete resources, those with sync info should still appear, those without should not
		// (Note: This is only true for projects that have a CVS provider)
		resource = project1.getFile("deleted.txt");
		resource.delete(false /*force*/, null);
		expectedMembers.remove(resource); /* added for reason noted above */
		resource = project1.getFolder("deleted");
		resource.delete(false /*force*/, null);
		expectedMembers.remove(resource); /* added for reason noted above */

		resource = project1.getFile("deleted_nosync.txt");
		resource.delete(false /*force*/, null);
		expectedMembers.remove(resource);
		resource = project1.getFolder("deleted_nosync");
		resource.delete(false /*force*/, null);
		expectedMembers.remove(resource);

		members = sync.members(project1);
		assertBijection(expectedMembers.toArray(), members, ignores);
		
		// delete sync info, only those that exist should appear
		resource = project1.getFile("hassync.txt");
		sync.deleteResourceSync(resource);
		resource = project1.getFolder("hassync");
		sync.deleteResourceSync(resource);

		resource = project1.getFile("deleted.txt");
		sync.deleteResourceSync(resource);
		expectedMembers.remove(resource);
		resource = project1.getFolder("deleted");
		sync.deleteResourceSync(resource);
		expectedMembers.remove(resource);

		members = sync.members(project1);
		assertBijection(expectedMembers.toArray(), members, ignores);
	}
	
	private FolderSyncInfo dummyFolderSync(IContainer container) {
		return new FolderSyncInfo("repo", ":pserver:user@host:/root", CVSTag.DEFAULT, false);
	}

	private ResourceSyncInfo dummyResourceSync(IResource resource) {
		if (resource.getType() == IResource.FILE) {
			MutableResourceSyncInfo info = new MutableResourceSyncInfo(resource.getName(), "1.1");
			info.setTag(CVSTag.DEFAULT);
			return info;
		} else {
			return new ResourceSyncInfo(resource.getName());
		}
	}
	
	/**
	 * Assert that there exists a bijection between the elements of the arrays.
	 */
	private void assertBijection(Object[] a, Object[] b, Object[] ignores) {
		List listA = new LinkedList(Arrays.asList(a));
		List listB = new LinkedList(Arrays.asList(b));
		if (ignores != null) {
			for (int i = 0; i < ignores.length; ++i ) {
				listA.remove(ignores[i]);
				listB.remove(ignores[i]);
			}
		}
		assertEquals("Should have same number of elements", listA.size(), listB.size());
		for (Iterator it = listB.iterator(); it.hasNext();) {
			Object obj = it.next();
			assertTrue("Should contain the same elements", listA.contains(obj));
			listA.remove(obj);
		}
	}
	
	/**
	 * Create a test project whose name is derived from the currently running test case.
	 * The resources are built using the names supplied in the given String array.
	 * Paths ending in / will be folders while others will be files. Intermediate folders
	 * are created as needed. Dummy sync info is applied to all created resources and
	 * the project is mapped to the CVS repository provider.
	 * @param resourcePaths paths of resources to be generated
	 * @return the create project
	 */
	protected IProject createProject(String[] resourcePaths) throws CoreException {
		// Create the project and build the resources
		IProject project = getUniqueTestProject(getName());
		buildResources(project, resourcePaths, true);
		
		// Associate dummy sync info with al create resources
		project.accept(new IResourceVisitor() {
			public boolean visit(IResource resource) throws CoreException {
				if (resource.getType() != IResource.PROJECT) {
					sync.setResourceSync(resource, dummyResourceSync(resource));
				}
				if (resource.getType() != IResource.FILE) {
					sync.setFolderSync((IContainer)resource, dummyFolderSync((IContainer)resource));
				}
				return true;
			}
		});
		
		// Map the project to CVS so the Move/Delete hook works
		RepositoryProvider.map(project, CVSProviderPlugin.getTypeId());
		return project;
	}
	
	/**
	 * Assert that the resources at the given resource paths have sync info.
	 * Also assert that the ancestors of the resources also have sync info
	 * @param project the project containing the resources
	 * @param resourcePaths the project relative resource paths
	 * @throws CVSException
	 */
	protected void assertHasSyncInfo(IProject project, String[] resourcePaths) throws CVSException {
		for (int i = 0; i < resourcePaths.length; i++) {
			String path = resourcePaths[i];
			IResource resource = findResource(project, path);
			assertHasSyncInfo(resource);
		}
	}

	private IResource findResource(IProject project, String path) {
		IResource resource = project.findMember(path);
		if (resource == null) {
			if (path.charAt(path.length()-1) == Path.SEPARATOR)
				resource = (IResource) project.getFolder(path);
			else
				resource = (IResource) project.getFile(path);
		}
		return resource;
	}

	/**
	 * Assert that the resource and its ancestors have sync info
	 * @param resource the resource being queried
	 * @throws CVSException
	 */
	protected void assertHasSyncInfo(IResource resource) throws CVSException {
		if (resource.getType() == IResource.ROOT) return;
		if (resource.getType() != IResource.FILE) {
			assertNotNull("Folder should have folder sync info but does not: " + resource.getProjectRelativePath(), sync.getFolderSync((IContainer)resource));
		}
		if (resource.getType() != IResource.PROJECT) {
			assertNotNull("Resource should have sync bytes but does not: " + resource.getProjectRelativePath(), sync.getSyncBytes(resource));
			assertHasSyncInfo(resource.getParent());
		}
	}
	
	/**
	 * Assert that the resources at the given resource paths do not have sync info.
	 * Also assert that the descendants of the resources also do not have sync info
	 * @param project
	 * @param resourcePaths
	 * @throws CVSException
	 */
	private void assertHasNoSyncInfo(IProject project, String[] resourcePaths) throws CoreException {
		for (int i = 0; i < resourcePaths.length; i++) {
			String path = resourcePaths[i];
			IResource resource = findResource(project, path);
			assertHasNoSyncInfo(resource);
		}
	}
	
	protected void assertHasNoSyncInfo(IResource resource) throws CoreException {
		if (resource.getType() == IResource.ROOT) return;
		if (resource.getType() != IResource.FILE) {
			assertNull("Folder should not have folder sync but does: " + resource.getProjectRelativePath(), sync.getFolderSync((IContainer)resource));
			IResource[] members = ((IContainer)resource).members();
			for (int i = 0; i < members.length; i++) {
				IResource child = members[i];
				assertHasNoSyncInfo(child);
			}
		}
		if (resource.getType() != IResource.PROJECT) {
			assertNull("Resource should not have sync bytes but does: " + resource.getProjectRelativePath(), sync.getSyncBytes(resource));
		}
	}

	public void testDeleteFile() throws CoreException {
		// Create a project with dummy sync info
		IProject project =  createProject(new String[] {"folder1/folder2/file1", "folder1/folder2/file2"});
		
		// Delete the file and assert old sync info is still in place and new has no sync info
		IFile file = project.getFile("folder1/folder2/file1");
		file.delete(false, false, null);
		assertHasSyncInfo(project, new String[] {"folder1/folder2/file1"});
	}
	
	public void testDeleteFolder() throws CoreException {
		// Create a project with dummy sync info
		IProject project =  createProject(new String[] {"folder1/folder2/file1", "folder1/folder2/file2"});
		
		// Delete the folder and assert old sync info is still in place and new has no sync info
		IFolder folder = project.getFolder("folder1/folder2/");
		folder.delete(false, false, null);
		assertHasSyncInfo(project, new String[] {"folder1/folder2/file1", "folder1/folder2/file2"});
	}
	
	public void testMoveFile() throws CoreException {
		// Create a project with dummy sync info
		IProject project =  createProject(new String[] {"folder1/folder2/file1", "folder1/folder2/file2"});
		
		// Move the file and assert old sync info is still in place and new has no sync info
		IFile file = project.getFile("folder1/folder2/file1");
		project.getFolder("folder1/folder3/").create(false, true, null);
		file.move(project.getFolder("folder1/folder3/file1").getFullPath(), false, null);
		assertHasSyncInfo(project, new String[] {"folder1/folder2/file1"});
		assertHasNoSyncInfo(project, new String[] {"folder1/folder3"});
	}
	
	public void testMoveFolder() throws CoreException {
		// Create a project with dummy sync info
		IProject project =  createProject(new String[] {"folder1/folder2/file1"});
		
		// Move the folder and assert old sync info is still in place and new has no sync info
		IFolder folder = project.getFolder("folder1/folder2/");
		folder.move(project.getFolder("folder1/folder3").getFullPath(), false, null);
		assertHasSyncInfo(project, new String[] {"folder1/folder2/file1"});
		assertHasNoSyncInfo(project, new String[] {"folder1/folder3/"});
	}
	
	/*
	 * See bug 44446
	 */
	public void testFileRecreation() throws CoreException {
		// Create a project with dummy sync info
		IProject project =  createProject(new String[] {"folder1/file1"});
		
		// Remove the file and assert that it still has sync info
		IFile file = project.getFile("folder1/file1");
		file.delete(false, false, null);
		assertHasSyncInfo(file);
		
		// Recreate the file and assert that it still has sync info
		file.create(getRandomContents(), false /*force*/, null);
		assertHasSyncInfo(file);
		
		// unmanage the file and assert that sync info is gone
		sync.deleteResourceSync(file);
		assertHasNoSyncInfo(file);
	}
	
	/*
	 * This testcase simulates an update that has an incoming deletion and a merge 
	 * (which may do a move).
	 */
	public void testFileMoveAndDelete() throws CoreException {
		// Create a project with dummy sync info
		final IProject project =  createProject(new String[] {"folder1/file1", "folder1/file2"});
		
		sync.run(project, new ICVSRunnable() {
			public void run(IProgressMonitor monitor) throws CVSException {
				try {
					IFile file1 = project.getFile("folder1/file1");
					IFile file2 = project.getFile("folder1/file2");
					// Delete file 1
					file1.delete(false, false, null);
					assertHasSyncInfo(file1);
					assertHasSyncInfo(file2);
					sync.deleteResourceSync(file1);
					assertHasNoSyncInfo(file1);
					assertHasSyncInfo(file2);
					// Move file 2
					file2.move(new Path("file3"), false, false, null);
					assertHasNoSyncInfo(file1);
					assertHasSyncInfo(file2);
				} catch (CoreException e) {
					throw CVSException.wrapException(e);
				}
			}
		}, null);
	}
	
	public void testMoveFolderOverFolder() throws CoreException {
		// Create a project with dummy sync info
		final IProject project =  createProject(new String[] {"folder1/file1", "folder2/file1"});
		
		// Change the sync info of folder1/file1 to be revision 1.9
		String revision = "1.9";
		IFile file11 = project.getFile("folder1/file1");
		ResourceSyncInfo info = sync.getResourceSync(file11);
		MutableResourceSyncInfo muttable = info.cloneMutable();
		muttable.setRevision(revision);
		sync.setResourceSync(file11, muttable);
		
		// Move the folder and verify that the sync info stays
		project.getFolder("folder2").delete(false, false, null);
		project.getFolder("folder1").move(new Path("folder2"), false, false, null);
		assertHasSyncInfo(file11);
		IFile file21 = project.getFile("folder2/file1");
		assertHasSyncInfo(file21);
		assertTrue(sync.getResourceSync(file11).getRevision().equals(revision));
		assertTrue(!sync.getResourceSync(file21).getRevision().equals(revision));
		
	}
}
