*** empty log message ***
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamDelta.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamDelta.java
index 580b214..bf80569 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamDelta.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamDelta.java
@@ -39,13 +39,13 @@
 	 * Delta kind constant (bit mask) indicating that a team provider has been configured on the resource.
 	 * @see IResourceDelta#getKind
 	 */
-	public static final int PROVIDER_CONFIGURED = 0x2;
+	public static final int ROOT_ADDED = 0x2;
 	
 	/**
 	 * Delta kind constant (bit mask) indicating that a team provider has been de-configured on the resource.
 	 * @see IResourceDelta#getKind
 	 */	
-	public static final int PROVIDER_DECONFIGURED = 0x4;
+	public static final int ROOT_REMOVED = 0x4;
 
 	private TeamSubscriber subscriber; 
 	private int flags;
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriberSyncInfoCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriberSyncInfoCollector.java
index 629a4f3..70db34c 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriberSyncInfoCollector.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriberSyncInfoCollector.java
@@ -21,20 +21,40 @@
 /**
  * This collector maintains a {@link SyncInfoSet} for a particular team subscriber keeping
  * it up-to-date with both incoming changes and outgoing changes as they occur for 
- * resources in the workspace.
+ * resources in the workspace. The collector can be configured to consider all the subscriber's
+ * roots or only a subset.
  * <p>
  * The advantage of this collector is that it processes both resource and team
  * subscriber deltas in a background thread.
  * </p>
  * @since 3.0
  */
-public class TeamSubscriberSyncInfoCollector implements IResourceChangeListener, ITeamResourceChangeListener {
+public final class TeamSubscriberSyncInfoCollector implements IResourceChangeListener, ITeamResourceChangeListener {
 
 	private SyncSetInputFromSubscriber set;
 	private SubscriberEventHandler eventHandler;
 	private TeamSubscriber subscriber;
+	private IResource[] roots;
 
+	/**
+	 * Create a collector on the subscriber that collects out-of-sync resources
+	 * for all roots of the subscriber.
+	 * @param subscriber the TeamSubscriber
+	 */
 	public TeamSubscriberSyncInfoCollector(TeamSubscriber subscriber) {
+		this(subscriber, null /* use the subscriber roots */);
+	}
+	
+	/**
+	 * Create a collector that collects out-of-sync resources that are children of
+	 * the given roots. If the roots are <code>null</code>, then all out-of-sync resources
+	 * from the subscriber are collected. An empty array of roots will cause no resources
+	 * to be collected.
+	 * @param subscriber the TeamSubscriber
+	 * @param roots the roots of the out-of-sync resources to be collected
+	 */
+	public TeamSubscriberSyncInfoCollector(TeamSubscriber subscriber, IResource[] roots) {
+		this.roots = roots;
 		this.subscriber = subscriber;
 		Assert.isNotNull(subscriber);
 		set = new SyncSetInputFromSubscriber(subscriber);
@@ -43,11 +63,23 @@
 		ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
 		subscriber.addListener(this);
 	}
-
+	
+	/**
+	 * Return the set that provides access to the out-of-sync resources for the collector's
+	 * subscriber. The set will contain only those resources that are children of the roots
+	 * of the collector unless the roots of the colletor has been set to <code>null</code>
+	 * in which case all out-of-sync resources from the subscriber are collected.
+	 * @return a SyncInfoSet containing out-of-sync resources
+	 */
 	public SyncInfoSet getSyncInfoSet() {
 		return set.getSyncSet();
 	}
 
+	/**
+	 * This causes the calling thread to wait any background collection of out-of-sync resources
+	 * to stop before returning.
+	 * @param monitor a progress monitor
+	 */
 	public void waitForCollector(IProgressMonitor monitor) {
 		monitor.worked(1);
 		// wait for the event handler to process changes.
@@ -63,13 +95,15 @@
 	
 	/**
 	 * Clears this collector's <code>SyncInfoSet</code> and causes it to be recreated from the
-	 * associated <code>TeamSubscriber</code>. 
-	 * @param monitor
+	 * associated <code>TeamSubscriber</code>. The reset may occur in the background. If the
+	 * caller wishes to wait for the reset to complete, they should call \
+	 * {@link waitForCollector(IProgressMonitor)}.
+	 * @param monitor a progress monitor
 	 * @throws TeamException
 	 */
 	public void reset(IProgressMonitor monitor) throws TeamException {
 		set.reset(monitor);
-		eventHandler.initialize();
+		eventHandler.initialize(getRoots());
 	}
 
 	/**
@@ -117,7 +151,7 @@
 				return;
 			}
 			// Only interested in projects mapped to the provider
-			if (!isVisibleProject((IProject) resource)) {
+			if (!isAncestorOfRoot(resource)) {
 				// If the project has any entries in the sync set, remove them
 				if (getSyncInfoSet().hasMembers(resource)) {
 					eventHandler.remove(resource);
@@ -126,43 +160,84 @@
 			}
 		}
 
-		// If the resource has changed type, remove the old resource handle
-		// and add the new one
-		if ((delta.getFlags() & IResourceDelta.TYPE) != 0) {
-			eventHandler.remove(resource);
-			eventHandler.change(resource, IResource.DEPTH_INFINITE);
+		boolean visitChildren = false;
+		if (isDescendantOfRoot(resource)) {
+			visitChildren = true;
+			// If the resource has changed type, remove the old resource handle
+			// and add the new one
+			if ((delta.getFlags() & IResourceDelta.TYPE) != 0) {
+				eventHandler.remove(resource);
+				eventHandler.change(resource, IResource.DEPTH_INFINITE);
+			}
+	
+			// Check the flags for changes the SyncSet cares about.
+			// Notice we don't care about MARKERS currently.
+			int changeFlags = delta.getFlags();
+			if ((changeFlags & (IResourceDelta.OPEN | IResourceDelta.CONTENT)) != 0) {
+				eventHandler.change(resource, IResource.DEPTH_ZERO);
+			}
+	
+			// Check the kind and deal with those we care about
+			if ((delta.getKind() & (IResourceDelta.REMOVED | IResourceDelta.ADDED)) != 0) {
+				eventHandler.change(resource, IResource.DEPTH_ZERO);
+			}
 		}
 
-		// Check the flags for changes the SyncSet cares about.
-		// Notice we don't care about MARKERS currently.
-		int changeFlags = delta.getFlags();
-		if ((changeFlags & (IResourceDelta.OPEN | IResourceDelta.CONTENT)) != 0) {
-			eventHandler.change(resource, IResource.DEPTH_ZERO);
-		}
-
-		// Check the kind and deal with those we care about
-		if ((delta.getKind() & (IResourceDelta.REMOVED | IResourceDelta.ADDED)) != 0) {
-			eventHandler.change(resource, IResource.DEPTH_ZERO);
-		}
-
-		// Handle changed children .
-		IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED | IResourceDelta.ADDED);
-		for (int i = 0; i < affectedChildren.length; i++) {
-			processDelta(affectedChildren[i]);
+		// Handle changed children
+		if (visitChildren || isAncestorOfRoot(resource)) {
+			IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED | IResourceDelta.ADDED);
+			for (int i = 0; i < affectedChildren.length; i++) {
+				processDelta(affectedChildren[i]);
+			}
 		}
 	}
 
-	private boolean isVisibleProject(IProject project) {
-		IResource[] roots = getTeamSubscriber().roots();
+	private boolean isAncestorOfRoot(IResource parent) {
+		IResource[] roots = getRoots();
 		for (int i = 0; i < roots.length; i++) {
 			IResource resource = roots[i];
-			if (project.getFullPath().isPrefixOf(resource.getFullPath())) {
+			if (parent.getFullPath().isPrefixOf(resource.getFullPath())) {
 				return true;
 			}
 		}
 		return false;
 	}
 
+	private boolean isDescendantOfRoot(IResource resource) {
+		IResource[] roots = getRoots();
+		for (int i = 0; i < roots.length; i++) {
+			IResource root = roots[i];
+			if (root.getFullPath().isPrefixOf(resource.getFullPath())) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Return the roots that are being considered by this collector.
+	 * By default, the collector is interested in the roots of its
+	 * subscriber. However, the set can be reduced using {@link setRoots(IResource)).
+	 * @return
+	 */
+	public IResource[] getRoots() {
+		if (roots == null) {
+			return getTeamSubscriber().roots();
+		} else {
+			return roots;
+		}
+	}
+	
+	/*
+	 * Returns whether the collector is configured to collect for
+	 * all roots of the subscriber or not
+	 * @return <code>true</code> if the collector is considering all 
+	 * roots of the subscriber and <code>false</code> otherwise
+	 */
+	private boolean isAllRootsIncluded() {
+		return roots == null;
+	}
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -181,15 +256,31 @@
 		for (int i = 0; i < deltas.length; i++) {
 			switch (deltas[i].getFlags()) {
 				case TeamDelta.SYNC_CHANGED :
-					eventHandler.change(deltas[i].getResource(), IResource.DEPTH_ZERO);
+					if (isAllRootsIncluded() || isDescendantOfRoot(deltas[i].getResource())) {
+						eventHandler.change(deltas[i].getResource(), IResource.DEPTH_ZERO);
+					}
 					break;
-				case TeamDelta.PROVIDER_DECONFIGURED :
+				case TeamDelta.ROOT_REMOVED :
 					eventHandler.remove(deltas[i].getResource());
 					break;
-				case TeamDelta.PROVIDER_CONFIGURED :
-					eventHandler.change(deltas[i].getResource(), IResource.DEPTH_INFINITE);
+				case TeamDelta.ROOT_ADDED :
+					if (isAllRootsIncluded() || isDescendantOfRoot(deltas[i].getResource())) {
+						eventHandler.change(deltas[i].getResource(), IResource.DEPTH_INFINITE);
+					}
 					break;
 			}
 		}
 	}
+	
+	/**
+	 * Set the roots that are to be considered by the collector. The provided
+	 * resources should be either a subset of the roots of the collector's subscriber
+	 * of children of those roots. Other resources can be provided but will be ignored.
+	 * Setting the roots to <code>null</code> will cause the roots of the subscriber
+	 * to be used
+	 * @param roots The roots to be considered or <code>null</code>.
+	 */
+	public void setRoots(IResource[] roots) {
+		this.roots = roots;
+	}
 }
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java
index 1eaf73a..6c9bd53 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java
@@ -80,7 +80,7 @@
 	 */
 	public SubscriberEventHandler(SyncSetInputFromSubscriber set) {
 		this.set = set;
-		reset(SubscriberEvent.INITIALIZE);
+		reset(set.getSubscriber().roots(), SubscriberEvent.INITIALIZE);
 	}
 	
 	/**
@@ -96,8 +96,11 @@
 	 * @param resource
 	 * @param depth
 	 */
-	public void initialize() {
-		reset(SubscriberEvent.CHANGE);
+	public void initialize(IResource[] roots) {
+		if (roots == null) {
+			roots = set.getSubscriber().roots();
+		}
+		reset(roots, SubscriberEvent.CHANGE);
 	}
 	
 	/**
@@ -240,8 +243,8 @@
 	 * @param type can be Event.CHANGE to recalculate all states or Event.INITIALIZE to perform the
 	 *   optimized recalculation if supported by the subscriber.
 	 */
-	private void reset(int type) {
-		IResource[] resources = set.getSubscriber().roots();
+	private void reset(IResource[] roots, int type) {
+		IResource[] resources = roots;
 		for (int i = 0; i < resources.length; i++) {
 			queueEvent(new SubscriberEvent(resources[i], type, IResource.DEPTH_INFINITE));
 		}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java
index 3dd14c3..577823a 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java
@@ -53,7 +53,6 @@
 	
 	public CVSMergeSubscriber(IResource[] roots, CVSTag start, CVSTag end) {		
 		this(getUniqueId(), roots, start, end);
-		this.comparisonCriteria = new ContentComparisonCriteria(false /* don't ignore whitespace */);
 	}
 	
 	protected IResource[] refreshRemote(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
@@ -85,7 +84,8 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.team.internal.ccvs.core.CVSWorkspaceSubscriber#initialize()
 	 */
-	private void initialize() {				
+	private void initialize() {			
+		this.comparisonCriteria = new CVSRevisionNumberCompareCriteria();
 		QualifiedName id = getId();
 		String syncKeyPrefix = id.getLocalName();
 		remoteSynchronizer = new CVSSynchronizationCache(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + end.getName()));
@@ -210,7 +210,7 @@
 		for (int i = 0; i < deltas.length; i++) {
 			TeamDelta delta = deltas[i];
 			switch(delta.getFlags()) {
-				case TeamDelta.PROVIDER_DECONFIGURED:
+				case TeamDelta.ROOT_REMOVED:
 					IResource resource = delta.getResource();
 					if(roots.remove(resource))	{
 						fireTeamResourceChange(new TeamDelta[] {delta});
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java
index e451917..99da931 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java
@@ -156,7 +156,7 @@
 	 * @see org.eclipse.team.internal.ccvs.core.IResourceStateChangeListener#projectConfigured(org.eclipse.core.resources.IProject)
 	 */
 	public void projectConfigured(IProject project) {
-		TeamDelta delta = new TeamDelta(this, TeamDelta.PROVIDER_CONFIGURED, project);
+		TeamDelta delta = new TeamDelta(this, TeamDelta.ROOT_ADDED, project);
 		fireTeamResourceChange(new TeamDelta[] {delta});
 	}
 
@@ -169,7 +169,7 @@
 		} catch (TeamException e) {
 			CVSProviderPlugin.log(e);
 		}
-		TeamDelta delta = new TeamDelta(this, TeamDelta.PROVIDER_DECONFIGURED, project);
+		TeamDelta delta = new TeamDelta(this, TeamDelta.ROOT_REMOVED, project);
 		fireTeamResourceChange(new TeamDelta[] {delta});
 	}
 	
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java
index 6fe4a0b..8784db0 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java
@@ -32,41 +32,41 @@
 	// parents who need a label update accumulated while handling sync set changes
 	private Set parentsToUpdate = new HashSet();
 	
+	protected SyncInfoSet getSyncSet(Object input) {
+		if (input == null) {
+			return null;
+		}
+		if(input instanceof SyncInfoDiffNode) {
+			return ((SyncInfoDiffNode)input).getSyncInfoSet();
+		}
+		if(input instanceof SyncInfoSet) {
+			return (SyncInfoSet)input;
+		}
+		return null;
+	}
+	
 	protected SyncInfoSet getSyncSet() {
 		if(viewer == null || viewer.getControl().isDisposed()) {
 			return null;	
 		}
-		if(viewer.getInput() instanceof SyncInfoDiffNode) {
-			return (SyncInfoSet)((SyncInfoDiffNode)viewer.getInput()).getSyncInfoSet();
-		}
-		return (SyncInfoSet)viewer.getInput();
+		return getSyncSet(viewer.getInput());
 	}
-	
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
 	 */
 	public void inputChanged(Viewer v, Object oldInput, Object newInput) {
 		
 		this.viewer = v;
-		SyncInfoSet oldSyncSet = null;
-		SyncInfoSet newSyncSet = null;
-		
-		if(newInput instanceof SyncInfoDiffNode && oldInput != null) {
-			return;
-		}
-		
-		if (oldInput instanceof SyncInfoSet) {
-			oldSyncSet = (SyncInfoSet) oldInput;
-		}
-		if (newInput instanceof SyncInfoSet) {
-			newSyncSet = (SyncInfoSet) newInput;
-		}
+		SyncInfoSet oldSyncSet = getSyncSet(oldInput);
+		SyncInfoSet newSyncSet = getSyncSet(newInput);
+
 		if (oldSyncSet != newSyncSet) {
 			if (oldSyncSet != null) {
-				((SyncInfoSet)oldSyncSet).removeSyncSetChangedListener(this);
+				oldSyncSet.removeSyncSetChangedListener(this);
 			}
 			if (newSyncSet != null) {
-				((SyncInfoSet)newSyncSet).addSyncSetChangedListener(this);
+				newSyncSet.addSyncSetChangedListener(this);
 			}
 		}
 	}
@@ -263,11 +263,7 @@
 	 * @param resource
 	 */
 	public Object getModelObject(IResource resource) {
-		if (resource.getType() == IResource.ROOT) {
-			return getSyncSet();
-		} else {
-			return new SyncInfoDiffNode(getSyncSet(), resource);
-		}
+		return new SyncInfoDiffNode(getSyncSet(), resource);
 	}
 	
 	protected Object[] getModelObjects(IResource[] resources) {
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java
index 31702da..8fae7f1 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java
@@ -73,12 +73,7 @@
 			// TODO: Should group added roots by their parent
 			for (int i = 0; i < added.length; i++) {
 				IResource resource = added[i];
-				Object parent;
-				if (resource.getType() == IResource.PROJECT) {
-					parent = getSyncSet();
-				} else {
-					parent = getModelParent(resource);				
-				}
+				Object parent = getModelParent(resource);				
 				Object element = getModelObject(resource);				
 				tree.add(parent, element);
 				updateParentLabels(resource);		
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoDiffTreeViewer.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoDiffTreeViewer.java
index 332db22..b4321d1 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoDiffTreeViewer.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoDiffTreeViewer.java
@@ -16,6 +16,7 @@
 import org.eclipse.compare.*;
 import org.eclipse.compare.internal.INavigatable;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.jface.action.*;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.util.IPropertyChangeListener;
@@ -91,7 +92,7 @@
 		hookContextMenu();
 		
 		createToolBarActions(parent);			
-		setInput(getSyncSet());
+		setInput(new SyncInfoDiffNode(getSyncSet(), ResourcesPlugin.getWorkspace().getRoot()));
 	}
 
 	protected Object getTitle() {
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoSetCompareInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoSetCompareInput.java
index 271dd11..6f7b4e7 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoSetCompareInput.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/SyncInfoSetCompareInput.java
@@ -72,4 +72,5 @@
 	protected boolean allowParticipantMenuContributions() {
 		return menuId != null;
 	}
+	
 }