Fix for 17944.
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java
index c147ee1..8fe4c53 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java
@@ -1,16 +1,15 @@
 /**********************************************************************
  * Copyright (c) 2002 IBM Corporation and others.
  * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * 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-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
  * 
  * Contributors:
  * IBM - Initial API and implementation
  **********************************************************************/
 package org.eclipse.core.internal.resources;
 
-import java.io.*;
 import org.eclipse.core.internal.localstore.*;
 import org.eclipse.core.internal.properties.PropertyManager;
 import org.eclipse.core.internal.utils.Assert;
@@ -205,7 +204,7 @@
 	
 		// Move the workspace tree.
 		try {
-			workspace.move(source, destination.getFullPath(), depth, false);
+			workspace.move(source, destination.getFullPath(), depth, false, true);
 		} catch (CoreException e) {
 			String message = Policy.bind("resources.errorMoving", source.getFullPath().toString(), destination.getFullPath().toString()); //$NON-NLS-1$
 			IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java
index 6dd5e3f..815ab3d 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java
@@ -1,9 +1,9 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2002 IBM Corporation and others.
  * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * 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-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
  * 
  * Contributors:
  * IBM - Initial API and implementation
@@ -428,6 +428,9 @@
 }
 
 protected void copyTree(IResource source, IPath destination, int depth, boolean phantom, boolean overwrite) throws CoreException {
+	copyTree(source, destination, depth, phantom, overwrite, false);
+}
+protected void copyTree(IResource source, IPath destination, int depth, boolean phantom, boolean overwrite, boolean keepSyncInfo) throws CoreException {
 	// FIXME: change this method signature to use the int updateFlags rather than the booleans.
 
 	// retrieve the resource at the destination if there is one (phantoms included).
@@ -452,7 +455,7 @@
 		sourceInfo = (ResourceInfo) sourceInfo.clone();
 		sourceInfo.setType(destinationResource.getType());
 	}
-	ResourceInfo newInfo = createResource(destinationResource, sourceInfo, phantom, overwrite);
+	ResourceInfo newInfo = createResource(destinationResource, sourceInfo, phantom, overwrite, keepSyncInfo);
 	// get/set the node id from the source's resource info so we can later put it in the
 	// info for the destination resource. This will help us generate the proper deltas,
 	// indicating a move rather than a add/delete
@@ -475,7 +478,7 @@
 	for (int i = 0; i < children.length; i++) {
 		IResource child = children[i];
 		IPath childPath = destination.append(child.getName());
-		copyTree(child, childPath, depth, phantom, overwrite);
+		copyTree(child, childPath, depth, phantom, overwrite, keepSyncInfo);
 	}
 }
 /**
@@ -505,6 +508,9 @@
 	}
 	return 0;
 }
+public ResourceInfo createResource(IResource resource, ResourceInfo info, boolean phantom, boolean overwrite) throws CoreException {
+	return createResource(resource, info, phantom, overwrite, false);
+}
 /*
  * Creates the given resource in the tree and returns the new resource info object.  
  * If phantom is true, the created element is marked as a phantom.
@@ -514,8 +520,12 @@
  * the element is overwritten with the new element. (but the synchronization
  * information is preserved) If the specified resource info is null, then create
  * a new one.
+ * 
+ * If keepSyncInfo is set to be true, the sync info in the given ResourceInfo is NOT
+ * cleared before being created and thus any sync info already existing at that namespace
+ * (as indicated by an already existing phantom resource) will be lost.
  */
-public ResourceInfo createResource(IResource resource, ResourceInfo info, boolean phantom, boolean overwrite) throws CoreException {
+public ResourceInfo createResource(IResource resource, ResourceInfo info, boolean phantom, boolean overwrite, boolean keepSyncInfo) throws CoreException {
 	info = info == null ? newElement(resource.getType()) : (ResourceInfo) info.clone();
 	ResourceInfo original = getResourceInfo(resource.getFullPath(), true, false);
 	if (phantom) {
@@ -526,7 +536,8 @@
 	if (original == null) {
 		// we got here from a copy/move. we don't want to copy over any sync info
 		// from the source so clear it.
-		info.setSyncInfo(null);
+		if (!keepSyncInfo)
+			info.setSyncInfo(null);
 		tree.createElement(resource.getFullPath(), info);
 	} else {
 		// if overwrite==true then slam the new info into the tree even if one existed before
@@ -537,7 +548,8 @@
 			// preserve the old sync info so its not dirty
 			// XXX: must copy over the generic sync info from the old info to the new
 			// XXX: do we really need to clone the sync info here?
-			info.setSyncInfo(original.getSyncInfo(true));
+			if (!keepSyncInfo)
+				info.setSyncInfo(original.getSyncInfo(true));
 			// mark the markers bit as dirty so we snapshot an empty marker set for
 			// the new resource
 			info.set(ICoreConstants.M_MARKERS_SNAP_DIRTY);
@@ -1146,15 +1158,20 @@
 	return move(resources, destination, updateFlags, monitor);
 }
 
+/* package */ void move(Resource source, IPath destination, int depth, boolean overwrite) throws CoreException {
+	move(source, destination, depth, overwrite, false);
+}
 /**
  * Moves this resource's subtree to the destination. This operation should only be
  * used by move methods. Destination must be a valid destination for this resource.
+ * The keepSyncInfo boolean is used to indicated whether or not the sync info should
+ * be moved from the source to the destination.
  */
 
-/* package */ void move(Resource source, IPath destination, int depth, boolean overwrite) throws CoreException {
+/* package */ void move(Resource source, IPath destination, int depth, boolean overwrite, boolean keepSyncInfo) throws CoreException {
 	// overlay the tree at the destination path, preserving any important info
 	// in any already existing resource infos
-	copyTree(source, destination, depth, false, overwrite);
+	copyTree(source, destination, depth, false, overwrite, keepSyncInfo);
 	source.fixupAfterMoveSource();
 }
 /**
diff --git a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/ISynchronizerTest.java b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/ISynchronizerTest.java
index 7e0edf5..eb95f6c 100644
--- a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/ISynchronizerTest.java
+++ b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/ISynchronizerTest.java
@@ -1,9 +1,9 @@
 /**********************************************************************
  * Copyright (c) 2000,2002 IBM Corporation and others.
  * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * 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-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
  * 
  * Contributors: 
  * IBM - Initial API and implementation
@@ -370,6 +370,90 @@
 		fail("4.3", e);
 	}
 }
+public void testMoveResource2() {
+	final QualifiedName qname = new QualifiedName("org.eclipse.core.tests.resources", "myTarget");
+	final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer();
+
+	// cleanup auto-created resources
+	try {
+		getWorkspace().getRoot().delete(true, getMonitor());
+	} catch (CoreException e) {
+		fail("0.0", e);
+	}
+
+	// setup
+	IResource[] resources = buildResources(getWorkspace().getRoot(), new String[] { "/Foo", "/Foo/file.txt" });
+	IProject sourceProject = (IProject) resources[0];
+	IFile sourceFile = (IFile) resources[1];
+	// create in workspace
+	ensureExistsInWorkspace(resources, true);
+
+	// register partner and add sync info
+	synchronizer.add(qname);
+	byte[] b = new byte[] { 1, 2, 3, 4 };
+	try {
+		synchronizer.setSyncInfo(qname, sourceProject, b);
+		synchronizer.setSyncInfo(qname, sourceFile, b);
+	} catch (CoreException e) {
+		fail("2.0", e);
+	}
+
+	// move the file
+	IFile destFile = sourceProject.getFile("newFile.txt");
+	try {
+		sourceFile.move(destFile.getFullPath(), true, getMonitor());
+	} catch (CoreException e) {
+		fail("3.0", e);
+	}
+
+	// check sync info
+	try {
+		byte[] old = synchronizer.getSyncInfo(qname, sourceFile);
+		assertNotNull("4.0", old);
+		assertEquals("4.1", b, old);
+		assertNull("4.2", synchronizer.getSyncInfo(qname, destFile));
+	} catch (CoreException e) {
+		fail("4.3", e);
+	}
+	
+	// move the file back
+	try {
+		destFile.move(sourceFile.getFullPath(), true, getMonitor());
+	} catch (CoreException e) {
+		fail("5.0", e);
+	}
+	
+	// check the sync info
+	try {
+		byte[] old = synchronizer.getSyncInfo(qname, sourceFile);
+		assertNotNull("6.0", old);
+		assertEquals("6.1", b, old);
+		assertNull("6.2", synchronizer.getSyncInfo(qname, destFile));
+	} catch (CoreException e) {
+		fail("6.3", e);
+	}
+	
+	// rename the file and ensure that the sync info is moved with it
+	IProject destProject = getWorkspace().getRoot().getProject("newProject");
+	try {
+		sourceProject.move(destProject.getFullPath(), true, getMonitor());
+	} catch (CoreException e) {
+		fail("7.0", e);
+	}
+	try {
+		assertNull("7.1", synchronizer.getSyncInfo(qname, sourceProject));
+		assertNull("7.2", synchronizer.getSyncInfo(qname, sourceFile));
+		byte[] old = synchronizer.getSyncInfo(qname, destProject.getFile(sourceFile.getName()));
+		assertNotNull("7.3", old);
+		assertEquals("7.4", b, old);
+		old = synchronizer.getSyncInfo(qname, destProject);
+		assertNotNull("7.5", old);
+		assertEquals("7.6", b, old);
+	} catch (CoreException e) {
+		fail("7.3", e);
+	}
+	
+}
 public void testRegistration() {
 	// setup
 	QualifiedName[] partners = new QualifiedName[NUMBER_OF_PARTNERS];