*** empty log message ***
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantFactory.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantFactory.java
new file mode 100644
index 0000000..236133a
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantFactory.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.internal.core.subscribers.caches;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.IResourceVariant;
+
+/**
+ * Interface for fetching resource variants and
+ * for storing and retrieving resource variants in a 
+ * <code>ResourceVariantTree</code>
+ */
+public interface IResourceVariantFactory {
+		
+	/**
+	 * Fetch the resource variant corresponding to the given resource.
+	 * The depth parameter indicates the depth to which the resource 
+	 * variant's desendants will be traversed by subsequent calls to 
+	 * <code>fecthMembers(IResourceVariant, IProgressMonitor)</code>. 
+	 * This method may prefetch the descendants to the provided depth
+	 * or may just return the variant handle corresponding to the given 
+	 * local resource, in which case
+	 * the descendant variants will be fetched by <code>fecthMembers(IResourceVariant, IProgressMonitor)</code>.
+	 * @param resource the local resource
+	 * @param depth the depth of the refresh  (one of <code>IResource.DEPTH_ZERO</code>,
+	 * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
+	 * @param monitor a progress monitor
+	 * @return the resource variant corresponding to the given local resource
+	 */
+	public IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException;
+
+	/**
+	 * Fetch the members of the given resource variant handle. This method may
+	 * return members that were fetched when 
+	 * <code>fetchVariant(IResource, int, IProgressMonitor</code> 
+	 * was called or may fetch the children directly. 
+	 * @param variant the resource variant
+	 * @param progress a progress monitor
+	 * @return the members of the resource variant.
+	 */
+	public IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException;
+
+	/**
+	 * Returns the bytes that represent the state of the resource variant.
+	 * The bytes can be stored in the <code>ResourceVariantTree</code> 
+	 * and used to recreate the variant using <code>getResourceVariant</code>.
+	 * 
+	 * @param local the local resource
+	 * @param remote the corresponding resource variant handle
+	 * @return the bytes for the resource variant.
+	 */
+	public byte[] getBytes(IResource resource, IResourceVariant variant) throws TeamException;
+
+	/**
+	 * Create a resource variant handle for the local resource
+	 * from the bytes stored in the given resource variant tree.
+	 * @param resource the local resource
+	 * @param tree the resource variant tree
+	 * @return a resource variant handle
+	 * @throws TeamException
+	 */
+	public IResourceVariant getResourceVariant(IResource resource, ResourceVariantTree tree) throws TeamException;
+}
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java
index 1c7395c..56f6f7d 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java
@@ -28,7 +28,19 @@
  * a <code>ResourceVariantTree</code>. It also accumulates and returns all local resources 
  * for which the corresponding resource variant has changed.
  */
-public abstract class ResourceVariantTreeRefresh {
+public class ResourceVariantTreeRefresh {
+	
+	private IResourceVariantFactory factory;
+	private ResourceVariantTree tree;
+	
+	/**
+	 * Create the refresh operation with the give variant factory.
+	 * @param factory
+	 */
+	public ResourceVariantTreeRefresh(IResourceVariantFactory factory, ResourceVariantTree tree) {
+		this.factory = factory;
+		this.tree = tree;
+	}
 	
 	/**
 	 * Refreshes the resource variant tree for the specified resources and possibly their descendants,
@@ -88,13 +100,13 @@
 			monitor.setTaskName(Policy.bind("SynchronizationCacheRefreshOperation.0", resource.getFullPath().makeRelative().toString())); //$NON-NLS-1$
 			
 			// build the remote tree only if an initial tree hasn't been provided
-			IResourceVariant tree = fetchVariant(resource, depth, Policy.subMonitorFor(monitor, 70));
+			IResourceVariant root = factory.fetchVariant(resource, depth, Policy.subMonitorFor(monitor, 70));
 			
 			// update the known remote handles 
 			IProgressMonitor sub = Policy.infiniteSubMonitorFor(monitor, 30);
 			try {
 				sub.beginTask(null, 64);
-				changedResources = collectChanges(resource, tree, depth, sub);
+				changedResources = collectChanges(resource, root, depth, sub);
 			} finally {
 				sub.done();	 
 			}
@@ -116,63 +128,13 @@
 	 * @return the resource's whose variants have changed
 	 * @throws TeamException
 	 */
-	protected IResource[] collectChanges(IResource local, IResourceVariant remote, int depth, IProgressMonitor monitor) throws TeamException {
+	public IResource[] collectChanges(IResource local, IResourceVariant remote, int depth, IProgressMonitor monitor) throws TeamException {
 		List changedResources = new ArrayList();
 		collectChanges(local, remote, changedResources, depth, monitor);
 		return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
 	}
 	
 	/**
-	 * Returns the resource variant tree that is being refreshed.
-	 * @return the resource variant tree that is being refreshed.
-	 */
-	protected abstract ResourceVariantTree getResourceVariantTree();
-	
-	/**
-	 * Get the bytes to be stored in the <code>ResourceVariantTree</code> 
-	 * from the given resource variant.
-	 * @param local the local resource
-	 * @param remote the corresponding resource variant handle
-	 * @return the bytes for the resource variant.
-	 */
-	protected abstract byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException;
-	
-	/**
-	 * Fetch the members of the given resource variant handle. This method may
-	 * return members that were fetched when <code>getRemoteTree</code> was called or
-	 * may fetch the children directly. 
-	 * @param variant the resource variant
-	 * @param progress a progress monitor
-	 * @return the members of the resource variant.
-	 */
-	protected abstract IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException;
-
-	/**
-	 * Returns the members of the local resource. This may include all the members of
-	 * the local resource or a subset that is of ineterest to the implementor.
-	 * @param parent the local resource
-	 * @return the members of the local resource
-	 */
-	protected abstract IResource[] members(IResource parent) throws TeamException;
-
-	/**
-	 * Fetch the resource variant corresponding to the given resource.
-	 * The depth
-	 * parameter indicates the depth of the refresh operation and also indicates the
-	 * depth to which the resource variant's desendants will be traversed. 
-	 * This method may prefetch the descendants to the provided depth
-	 * or may just return the variant handle corresponding to the given 
-	 * local resource, in which case
-	 * the descendant variants will be fetched by <code>fecthMembers(IResourceVariant, IProgressMonitor)</code>.
-	 * @param resource the local resource
-	 * @param depth the depth of the refresh  (one of <code>IResource.DEPTH_ZERO</code>,
-	 * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
-	 * @param monitor a progress monitor
-	 * @return the resource variant corresponding to the given local resource
-	 */
-	protected abstract IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException;
-	
-	/**
 	 * Return the scheduling rule that should be obtained for the given resource.
 	 * This method is invoked from <code>refresh(IResource, int, IProgressMonitor)</code>.
 	 * By default, the resource's project is returned. Subclasses may override.
@@ -184,13 +146,12 @@
 	}
 	
 	private void collectChanges(IResource local, IResourceVariant remote, Collection changedResources, int depth, IProgressMonitor monitor) throws TeamException {
-		ResourceVariantTree cache = getResourceVariantTree();
-		byte[] newRemoteBytes = getBytes(local, remote);
+		byte[] newRemoteBytes = factory.getBytes(local, remote);
 		boolean changed;
 		if (newRemoteBytes == null) {
-			changed = cache.setVariantDoesNotExist(local);
+			changed = tree.setVariantDoesNotExist(local);
 		} else {
-			changed = cache.setBytes(local, newRemoteBytes);
+			changed = tree.setBytes(local, newRemoteBytes);
 		}
 		if (changed) {
 			changedResources.add(local);
@@ -210,13 +171,12 @@
 
 	private void removeStaleBytes(IResource local, Map children, Collection changedResources) throws TeamException {
 		// Look for resources that have sync bytes but are not in the resources we care about
-		ResourceVariantTree cache = getResourceVariantTree();
 		IResource[] resources = getChildrenWithBytes(local);
 		for (int i = 0; i < resources.length; i++) {
 			IResource resource = resources[i];
 			if (!children.containsKey(resource)) {
 				// These sync bytes are stale. Purge them
-				cache.removeBytes(resource, IResource.DEPTH_INFINITE);
+				tree.removeBytes(resource, IResource.DEPTH_INFINITE);
 				changedResources.add(resource);
 			}
 		}
@@ -236,7 +196,7 @@
 				List childrenWithSyncBytes = new ArrayList();
 				for (int i = 0; i < allChildren.length; i++) {
 					IResource resource = allChildren[i];
-					if (getResourceVariantTree().getBytes(resource) != null) {
+					if (tree.getBytes(resource) != null) {
 						childrenWithSyncBytes.add(resource);
 					}
 				}
@@ -258,11 +218,11 @@
 		if (remote == null) {
 			remoteChildren = new IResourceVariant[0];
 		} else {
-			remoteChildren = fetchMembers(remote, progress);
+			remoteChildren = factory.fetchMembers(remote, progress);
 		}
 		
 		
-		IResource[] localChildren = members(local);		
+		IResource[] localChildren = tree.members(local);		
 
 		if (remoteChildren.length > 0 || localChildren.length > 0) {
 			Set allSet = new HashSet(20);
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SyncTreeSubscriber.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SyncTreeSubscriber.java
index 6b68087..6e4c9f3 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SyncTreeSubscriber.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SyncTreeSubscriber.java
@@ -51,11 +51,6 @@
 	}
 
 	/**
-	 * @return
-	 */
-	public abstract IResourceVariantComparator getResourceComparator();
-
-	/**
 	 * Method that creates an instance of SyncInfo for the provider local, base and remote.
 	 * Can be overiden by subclasses.
 	 * @param local
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java
index 2cb785b..182acf2 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java
@@ -151,15 +151,19 @@
 
 	protected IResource[] refreshBase(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
 		if (isThreeWay()) {
-			return new CVSRefreshOperation(getBaseSynchronizationCache(), null, getBaseTag(),  getCacheFileContentsHint())
-				.refresh(resources, depth, monitor);
+			return new ResourceVariantTreeRefresh(
+					new CVSResourceVariantFactory(null, getBaseTag(), getCacheFileContentsHint()), 
+					getBaseSynchronizationCache())
+			.refresh(resources, depth, monitor);
 		} else {
 			return new IResource[0];
 		}
 	}
 
 	protected IResource[] refreshRemote(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
-		return new CVSRefreshOperation(getRemoteSynchronizationCache(), getBaseSynchronizationCache(), getRemoteTag(), getCacheFileContentsHint())
+		return new ResourceVariantTreeRefresh(
+				new CVSResourceVariantFactory(getBaseSynchronizationCache(), getBaseTag(), getCacheFileContentsHint()), 
+				getRemoteSynchronizationCache())
 			.refresh(resources, depth, monitor);
 	}
 
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 cadb9f7..2ae7a4e 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
@@ -13,7 +13,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.QualifiedName;
 import org.eclipse.team.core.RepositoryProvider;
@@ -21,10 +23,14 @@
 import org.eclipse.team.core.subscribers.ISubscriberChangeEvent;
 import org.eclipse.team.core.subscribers.SubscriberChangeEvent;
 import org.eclipse.team.core.synchronize.IResourceVariant;
-import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSBaseSynchronizationCache;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSDescendantSynchronizationCache;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSResourceVariantFactory;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
 import org.eclipse.team.internal.ccvs.core.util.ResourceStateChangeListeners;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
 import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantTree;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefresh;
 
 /**
  * CVSWorkspaceSubscriber
@@ -176,7 +182,10 @@
 	public void setRemote(IProject project, IResourceVariant remote, IProgressMonitor monitor) throws TeamException {
 		// TODO: This exposes internal behavior to much
 		IResource[] changedResources = 
-			new CVSRefreshOperation(remoteSynchronizer, baseSynchronizer, null, false).collectChanges(project, remote, IResource.DEPTH_INFINITE, monitor);
+			 new ResourceVariantTreeRefresh(
+					new CVSResourceVariantFactory(baseSynchronizer, null, false), 
+					remoteSynchronizer)
+				.collectChanges(project, remote, IResource.DEPTH_INFINITE, monitor);
 		if (changedResources.length != 0) {
 			fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, changedResources));
 		}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java
deleted file mode 100644
index 395166a..0000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*******************************************************************************
- * 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.internal.ccvs.core.syncinfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.synchronize.IResourceVariant;
-import org.eclipse.team.internal.ccvs.core.*;
-import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
-import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefresh;
-
-/**
- * CVS Specific refresh operation
- */
-public class CVSRefreshOperation extends ResourceVariantTreeRefresh {
-
-	private ResourceVariantTree cache, baseCache;
-	private CVSTag tag;
-	private boolean cacheFileContentsHint;
-
-	public CVSRefreshOperation(ResourceVariantTree cache, ResourceVariantTree baseCache, CVSTag tag, boolean cacheFileContentsHint) {
-		this.tag = tag;
-		this.cache = cache;
-		this.baseCache = cache;
-		this.cacheFileContentsHint = cacheFileContentsHint;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getSynchronizationCache()
-	 */
-	protected ResourceVariantTree getResourceVariantTree() {
-		return cache;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteSyncBytes(org.eclipse.core.resources.IResource, org.eclipse.team.core.subscribers.ISubscriberResource)
-	 */
-	protected byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException {
-		if (remote != null) {
-			return ((RemoteResource)remote).getSyncBytes();
-		} else {
-			if (local.getType() == IResource.FOLDER && baseCache != null) {
-				// If there is no remote, use the local sync for the folder
-				return baseCache.getBytes(local);
-			}
-			return null;
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteChildren(org.eclipse.team.core.subscribers.ISubscriberResource, org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	protected IResourceVariant[] fetchMembers(IResourceVariant remote, IProgressMonitor progress) throws TeamException {
-		ICVSRemoteResource[] children = remote != null ? (ICVSRemoteResource[])((RemoteResource)remote).members(progress) : new ICVSRemoteResource[0];
-		IResourceVariant[] result = new IResourceVariant[children.length];
-		for (int i = 0; i < children.length; i++) {
-			result[i] = (IResourceVariant)children[i];
-		}
-		return result;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getLocalChildren(org.eclipse.core.resources.IResource)
-	 */
-	protected IResource[] members(IResource local) throws TeamException {
-		IResource[] localChildren = null;			
-		if( local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) {
-			// Include all non-ignored resources including outgoing deletions
-			ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local);
-			// Look inside existing folders and phantoms that are CVS folders
-			if (local.exists() || cvsFolder.isCVSFolder()) {
-				ICVSResource[] cvsChildren = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS | ICVSFolder.UNMANAGED_MEMBERS);
-				List resourceChildren = new ArrayList();
-				for (int i = 0; i < cvsChildren.length; i++) {
-					ICVSResource cvsResource = cvsChildren[i];
-					resourceChildren.add(cvsResource.getIResource());
-				}
-				localChildren = (IResource[]) resourceChildren.toArray(new IResource[resourceChildren.size()]);
-			}
-		}
-		if (localChildren == null) {
-			localChildren = new IResource[0];
-		}
-		return localChildren;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.core.subscribers.RefreshOperation#buildRemoteTree(org.eclipse.core.resources.IResource, int, boolean, org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	protected IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
-		// TODO: we are currently ignoring the depth parameter because the build remote tree is
-		// by default deep!
-		return (IResourceVariant)CVSWorkspaceRoot.getRemoteTree(resource, tag, cacheFileContentsHint, monitor);
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefreshOperation#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public IResource[] collectChanges(IResource local,
-			IResourceVariant remote, int depth, IProgressMonitor monitor)
-			throws TeamException {
-		return super.collectChanges(local, remote, depth, monitor);
-	}
-
-}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantFactory.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantFactory.java
new file mode 100644
index 0000000..ab4a0bc
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantFactory.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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.internal.ccvs.core.syncinfo;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.IResourceVariant;
+import org.eclipse.team.internal.ccvs.core.CVSTag;
+import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
+import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
+import org.eclipse.team.internal.core.subscribers.caches.IResourceVariantFactory;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
+
+public class CVSResourceVariantFactory implements IResourceVariantFactory {
+	private CVSTag tag;
+	private boolean cacheFileContentsHint;
+	private ResourceVariantTree baseCache;
+	
+	public CVSResourceVariantFactory(ResourceVariantTree baseCache, CVSTag tag, boolean cacheFileContentsHint) {
+		this.baseCache = baseCache;
+		this.tag = tag;
+		this.cacheFileContentsHint = cacheFileContentsHint;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantFactory#fetchVariant(org.eclipse.core.resources.IResource, int, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
+		// TODO: we are currently ignoring the depth parameter because the build remote tree is
+		// by default deep!
+		return (IResourceVariant)CVSWorkspaceRoot.getRemoteTree(resource, tag, cacheFileContentsHint, monitor);
+
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantFactory#fetchMembers(org.eclipse.team.core.synchronize.IResourceVariant, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException {
+		ICVSRemoteResource[] children = variant != null ? (ICVSRemoteResource[])((RemoteResource)variant).members(progress) : new ICVSRemoteResource[0];
+		IResourceVariant[] result = new IResourceVariant[children.length];
+		for (int i = 0; i < children.length; i++) {
+			result[i] = (IResourceVariant)children[i];
+		}
+		return result;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantFactory#getBytes(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant)
+	 */
+	public byte[] getBytes(IResource resource, IResourceVariant variant) throws TeamException {
+		if (variant != null) {
+			return ((RemoteResource)variant).getSyncBytes();
+		} else {
+			if (resource.getType() == IResource.FOLDER && baseCache != null) {
+				// If there is no remote, use the local sync for the folder
+				return baseCache.getBytes(resource);
+			}
+			return null;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantFactory#getResourceVariant(org.eclipse.core.resources.IResource, org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree)
+	 */
+	public IResourceVariant getResourceVariant(IResource resource, ResourceVariantTree tree) throws TeamException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}